} A promise that will resolve when the data is loaded.
*/
@@ -888,7 +895,7 @@ Object.defineProperties(GeoJsonDataSource.prototype, {
* @param {Resource|String|Object} data A url, GeoJSON object, or TopoJSON object to be loaded.
* @param {Object} [options] An object with the following properties:
* @param {String} [options.sourceUri] Overrides the url to use for resolving relative links.
- * @param {GeoJsonDataSource~describe} [options.describe=GeoJsonDataSource.defaultDescribeProperty] A function which returns a Property object (or just a string),
+ * @param {GeoJsonDataSource.describe} [options.describe=GeoJsonDataSource.defaultDescribeProperty] A function which returns a Property object (or just a string),
* which converts the properties into an html description.
* @param {Number} [options.markerSize=GeoJsonDataSource.markerSize] The default size of the map pin created for each point, in pixels.
* @param {String} [options.markerSymbol=GeoJsonDataSource.markerSymbol] The default symbol of the map pin created for each point.
@@ -964,6 +971,19 @@ GeoJsonDataSource.prototype.load = function (data, options) {
});
};
+/**
+ * Updates the data source to the provided time. This function is optional and
+ * is not required to be implemented. It is provided for data sources which
+ * retrieve data based on the current animation time or scene state.
+ * If implemented, update will be called by {@link DataSourceDisplay} once a frame.
+ *
+ * @param {JulianDate} time The simulation time.
+ * @returns {Boolean} True if this data source is ready to be displayed at the provided time, false otherwise.
+ */
+GeoJsonDataSource.prototype.update = function (time) {
+ return true;
+};
+
function load(that, geoJson, options, sourceUri) {
var name;
if (defined(sourceUri)) {
@@ -1037,7 +1057,7 @@ function load(that, geoJson, options, sourceUri) {
/**
* This callback is displayed as part of the GeoJsonDataSource class.
- * @callback GeoJsonDataSource~describe
+ * @callback GeoJsonDataSource.describe
* @param {Object} properties The properties of the feature.
* @param {String} nameProperty The property key that Cesium estimates to have the name of the feature.
*/
diff --git a/Source/DataSources/GeometryUpdater.js b/Source/DataSources/GeometryUpdater.js
index 1377c87dc82c..d23137b4b797 100644
--- a/Source/DataSources/GeometryUpdater.js
+++ b/Source/DataSources/GeometryUpdater.js
@@ -519,6 +519,7 @@ GeometryUpdater.prototype._onEntityPropertyChanged = function (
* @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame.
*
* @exception {DeveloperError} This instance does not represent dynamic geometry.
+ * @private
*/
GeometryUpdater.prototype.createDynamicUpdater = function (
primitives,
diff --git a/Source/DataSources/GridMaterialProperty.js b/Source/DataSources/GridMaterialProperty.js
index a1557b0d6f5d..3addebd12796 100644
--- a/Source/DataSources/GridMaterialProperty.js
+++ b/Source/DataSources/GridMaterialProperty.js
@@ -17,11 +17,11 @@ var defaultLineThickness = new Cartesian2(1, 1);
* @alias GridMaterialProperty
*
* @param {Object} [options] Object with the following properties:
- * @param {Property} [options.color=Color.WHITE] A Property specifying the grid {@link Color}.
- * @param {Property} [options.cellAlpha=0.1] A numeric Property specifying cell alpha values.
- * @param {Property} [options.lineCount=new Cartesian2(8, 8)] A {@link Cartesian2} Property specifying the number of grid lines along each axis.
- * @param {Property} [options.lineThickness=new Cartesian2(1.0, 1.0)] A {@link Cartesian2} Property specifying the thickness of grid lines along each axis.
- * @param {Property} [options.lineOffset=new Cartesian2(0.0, 0.0)] A {@link Cartesian2} Property specifying starting offset of grid lines along each axis.
+ * @param {Property|Color} [options.color=Color.WHITE] A Property specifying the grid {@link Color}.
+ * @param {Property|Number} [options.cellAlpha=0.1] A numeric Property specifying cell alpha values.
+ * @param {Property|Cartesian2} [options.lineCount=new Cartesian2(8, 8)] A {@link Cartesian2} Property specifying the number of grid lines along each axis.
+ * @param {Property|Cartesian2} [options.lineThickness=new Cartesian2(1.0, 1.0)] A {@link Cartesian2} Property specifying the thickness of grid lines along each axis.
+ * @param {Property|Cartesian2} [options.lineOffset=new Cartesian2(0.0, 0.0)] A {@link Cartesian2} Property specifying starting offset of grid lines along each axis.
*
* @constructor
*/
@@ -86,7 +86,7 @@ Object.defineProperties(GridMaterialProperty.prototype, {
/**
* Gets or sets the Property specifying the grid {@link Color}.
* @memberof GridMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Color.WHITE
*/
color: createPropertyDescriptor("color"),
@@ -94,7 +94,7 @@ Object.defineProperties(GridMaterialProperty.prototype, {
/**
* Gets or sets the numeric Property specifying cell alpha values.
* @memberof GridMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 0.1
*/
cellAlpha: createPropertyDescriptor("cellAlpha"),
@@ -102,7 +102,7 @@ Object.defineProperties(GridMaterialProperty.prototype, {
/**
* Gets or sets the {@link Cartesian2} Property specifying the number of grid lines along each axis.
* @memberof GridMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default new Cartesian2(8.0, 8.0)
*/
lineCount: createPropertyDescriptor("lineCount"),
@@ -110,7 +110,7 @@ Object.defineProperties(GridMaterialProperty.prototype, {
/**
* Gets or sets the {@link Cartesian2} Property specifying the thickness of grid lines along each axis.
* @memberof GridMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default new Cartesian2(1.0, 1.0)
*/
lineThickness: createPropertyDescriptor("lineThickness"),
@@ -118,7 +118,7 @@ Object.defineProperties(GridMaterialProperty.prototype, {
/**
* Gets or sets the {@link Cartesian2} Property specifying the starting offset of grid lines along each axis.
* @memberof GridMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default new Cartesian2(0.0, 0.0)
*/
lineOffset: createPropertyDescriptor("lineOffset"),
diff --git a/Source/DataSources/GroundGeometryUpdater.js b/Source/DataSources/GroundGeometryUpdater.js
index 724b0b04f1c1..2879e88ea059 100644
--- a/Source/DataSources/GroundGeometryUpdater.js
+++ b/Source/DataSources/GroundGeometryUpdater.js
@@ -54,6 +54,7 @@ Object.defineProperties(GroundGeometryUpdater.prototype, {
* @type {TerrainOffsetProperty}
* @memberof GroundGeometryUpdater.prototype
* @readonly
+ * @private
*/
terrainOffsetProperty: {
get: function () {
diff --git a/Source/DataSources/ImageMaterialProperty.js b/Source/DataSources/ImageMaterialProperty.js
index a1c3b717c0be..8fdc3f61417f 100644
--- a/Source/DataSources/ImageMaterialProperty.js
+++ b/Source/DataSources/ImageMaterialProperty.js
@@ -16,10 +16,10 @@ var defaultColor = Color.WHITE;
* @constructor
*
* @param {Object} [options] Object with the following properties:
- * @param {Property} [options.image] A Property specifying the Image, URL, Canvas, or Video.
- * @param {Property} [options.repeat=new Cartesian2(1.0, 1.0)] A {@link Cartesian2} Property specifying the number of times the image repeats in each direction.
- * @param {Property} [options.color=Color.WHITE] The color applied to the image
- * @param {Property} [options.transparent=false] Set to true when the image has transparency (for example, when a png has transparent sections)
+ * @param {Property|String|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} [options.image] A Property specifying the Image, URL, Canvas, or Video.
+ * @param {Property|Cartesian2} [options.repeat=new Cartesian2(1.0, 1.0)] A {@link Cartesian2} Property specifying the number of times the image repeats in each direction.
+ * @param {Property|Color} [options.color=Color.WHITE] The color applied to the image
+ * @param {Property|Boolean} [options.transparent=false] Set to true when the image has transparency (for example, when a png has transparent sections)
*/
function ImageMaterialProperty(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
@@ -75,14 +75,14 @@ Object.defineProperties(ImageMaterialProperty.prototype, {
/**
* Gets or sets the Property specifying Image, URL, Canvas, or Video to use.
* @memberof ImageMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
image: createPropertyDescriptor("image"),
/**
* Gets or sets the {@link Cartesian2} Property specifying the number of times the image repeats in each direction.
* @memberof ImageMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default new Cartesian2(1, 1)
*/
repeat: createPropertyDescriptor("repeat"),
@@ -90,7 +90,7 @@ Object.defineProperties(ImageMaterialProperty.prototype, {
/**
* Gets or sets the Color Property specifying the desired color applied to the image.
* @memberof ImageMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 1.0
*/
color: createPropertyDescriptor("color"),
@@ -98,7 +98,7 @@ Object.defineProperties(ImageMaterialProperty.prototype, {
/**
* Gets or sets the Boolean Property specifying whether the image has transparency
* @memberof ImageMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 1.0
*/
transparent: createPropertyDescriptor("transparent"),
diff --git a/Source/DataSources/KmlDataSource.js b/Source/DataSources/KmlDataSource.js
index 124298ba9a96..592e951fa0f7 100644
--- a/Source/DataSources/KmlDataSource.js
+++ b/Source/DataSources/KmlDataSource.js
@@ -3338,6 +3338,19 @@ function load(dataSource, entityCollection, data, options) {
});
}
+/**
+ * @typedef {Object} KmlDataSource.LoadOptions
+ *
+ * Initialization options for the `load` method.
+ *
+ * @property {Camera} camera The camera that is used for viewRefreshModes and sending camera properties to network links.
+ * @property {HTMLCanvasElement} canvas The canvas that is used for sending viewer properties to network links.
+ * @property {String} [sourceUri] Overrides the url to use for resolving relative links and other KML network features.
+ * @property {Boolean} [clampToGround=false] true if we want the geometry features (Polygons, LineStrings and LinearRings) clamped to the ground.
+ * @property {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The global ellipsoid used for geographical calculations.
+ * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas.
+ */
+
/**
* A {@link DataSource} which processes Keyhole Markup Language 2.2 (KML).
*
@@ -3358,7 +3371,7 @@ function load(dataSource, entityCollection, data, options) {
*
* @param {Object} options An object with the following properties:
* @param {Camera} options.camera The camera that is used for viewRefreshModes and sending camera properties to network links.
- * @param {Canvas} options.canvas The canvas that is used for sending viewer properties to network links.
+ * @param {HTMLCanvasElement} options.canvas The canvas that is used for sending viewer properties to network links.
* @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The global ellipsoid used for geographical calculations.
* @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas.
*
@@ -3434,13 +3447,7 @@ function KmlDataSource(options) {
* Creates a Promise to a new instance loaded with the provided KML data.
*
* @param {Resource|String|Document|Blob} data A url, parsed KML document, or Blob containing binary KMZ data or a parsed KML document.
- * @param {Object} options An object with the following properties:
- * @param {Camera} options.camera The camera that is used for viewRefreshModes and sending camera properties to network links.
- * @param {Canvas} options.canvas The canvas that is used for sending viewer properties to network links.
- * @param {String} [options.sourceUri] Overrides the url to use for resolving relative links and other KML network features.
- * @param {Boolean} [options.clampToGround=false] true if we want the geometry features (Polygons, LineStrings and LinearRings) clamped to the ground.
- * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The global ellipsoid used for geographical calculations.
- * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas.
+ * @param {KmlDataSource.LoadOptions} [options] An object specifying configuration options
*
* @returns {Promise.} A promise that will resolve to a new KmlDataSource instance once the KML is loaded.
*/
@@ -3865,8 +3872,7 @@ function getNetworkLinkUpdateCallback(
var entitiesToIgnore = new AssociativeArray();
/**
- * Updates any NetworkLink that require updating
- * @function
+ * Updates any NetworkLink that require updating.
*
* @param {JulianDate} time The simulation time.
* @returns {Boolean} True if this data source is ready to be displayed at the provided time, false otherwise.
@@ -4006,112 +4012,68 @@ KmlDataSource.prototype.update = function (time) {
* @constructor
*/
function KmlFeatureData() {
+ /**
+ * @typedef KmlFeatureData.Author
+ * @type {Object}
+ * @property {String} name Gets the name.
+ * @property {String} uri Gets the URI.
+ * @property {Number} age Gets the email.
+ */
+
/**
* Gets the atom syndication format author field.
- * @type Object
+ * @type {KmlFeatureData.Author}
*/
this.author = {
- /**
- * Gets the name.
- * @type String
- * @alias author.name
- * @memberof! KmlFeatureData#
- * @property author.name
- */
name: undefined,
- /**
- * Gets the URI.
- * @type String
- * @alias author.uri
- * @memberof! KmlFeatureData#
- * @property author.uri
- */
uri: undefined,
- /**
- * Gets the email.
- * @type String
- * @alias author.email
- * @memberof! KmlFeatureData#
- * @property author.email
- */
email: undefined,
};
+ /**
+ * @typedef KmlFeatureData.Link
+ * @type {Object}
+ * @property {String} href Gets the href.
+ * @property {String} hreflang Gets the language of the linked resource.
+ * @property {String} rel Gets the link relation.
+ * @property {String} type Gets the link type.
+ * @property {String} title Gets the link title.
+ * @property {String} length Gets the link length.
+ */
+
/**
* Gets the link.
- * @type Object
+ * @type {KmlFeatureData.Link}
*/
this.link = {
- /**
- * Gets the href.
- * @type String
- * @alias link.href
- * @memberof! KmlFeatureData#
- * @property link.href
- */
href: undefined,
- /**
- * Gets the language of the linked resource.
- * @type String
- * @alias link.hreflang
- * @memberof! KmlFeatureData#
- * @property link.hreflang
- */
hreflang: undefined,
- /**
- * Gets the link relation.
- * @type String
- * @alias link.rel
- * @memberof! KmlFeatureData#
- * @property link.rel
- */
rel: undefined,
- /**
- * Gets the link type.
- * @type String
- * @alias link.type
- * @memberof! KmlFeatureData#
- * @property link.type
- */
type: undefined,
- /**
- * Gets the link title.
- * @type String
- * @alias link.title
- * @memberof! KmlFeatureData#
- * @property link.title
- */
title: undefined,
- /**
- * Gets the link length.
- * @type String
- * @alias link.length
- * @memberof! KmlFeatureData#
- * @property link.length
- */
length: undefined,
};
/**
* Gets the unstructured address field.
- * @type String
+ * @type {String}
*/
this.address = undefined;
/**
* Gets the phone number.
- * @type String
+ * @type {String}
*/
this.phoneNumber = undefined;
/**
* Gets the snippet.
- * @type String
+ * @type {String}
*/
this.snippet = undefined;
/**
* Gets the extended data, parsed into a JSON object.
* Currently only the Data
property is supported.
* SchemaData
and custom data are ignored.
- * @type String
+ * @type {String}
*/
this.extendedData = undefined;
}
diff --git a/Source/DataSources/KmlTourFlyTo.js b/Source/DataSources/KmlTourFlyTo.js
index 97a3d8cce55b..f2f6b980fda4 100644
--- a/Source/DataSources/KmlTourFlyTo.js
+++ b/Source/DataSources/KmlTourFlyTo.js
@@ -24,7 +24,7 @@ function KmlTourFlyTo(duration, flyToMode, view) {
/**
* Play this playlist entry
*
- * @param {KmlTourFlyTo~DoneCallback} done function which will be called when playback ends
+ * @param {KmlTourFlyTo.DoneCallback} done function which will be called when playback ends
* @param {Camera} camera Cesium camera
* @param {Object} [cameraOptions] which will be merged with camera flyTo options. See {@link Camera#flyTo}
*/
@@ -95,7 +95,7 @@ KmlTourFlyTo.prototype.getCameraOptions = function (cameraOptions) {
/**
* A function that will be executed when the flight completes.
- * @callback KmlTourFlyTo~DoneCallback
+ * @callback KmlTourFlyTo.DoneCallback
*
* @param {Boolean} terminated true if {@link KmlTourFlyTo#stop} was
* called before entry done playback.
diff --git a/Source/DataSources/KmlTourWait.js b/Source/DataSources/KmlTourWait.js
index 6a809461ae42..476603d18553 100644
--- a/Source/DataSources/KmlTourWait.js
+++ b/Source/DataSources/KmlTourWait.js
@@ -16,7 +16,7 @@ function KmlTourWait(duration) {
/**
* Play this playlist entry
*
- * @param {KmlTourWait~DoneCallback} done function which will be called when playback ends
+ * @param {KmlTourWait.DoneCallback} done function which will be called when playback ends
*/
KmlTourWait.prototype.play = function (done) {
var self = this;
@@ -40,7 +40,7 @@ KmlTourWait.prototype.stop = function () {
/**
* A function which will be called when playback ends.
*
- * @callback KmlTourWait~DoneCallback
+ * @callback KmlTourWait.DoneCallback
* @param {Boolean} terminated true if {@link KmlTourWait#stop} was
* called before entry done playback.
*/
diff --git a/Source/DataSources/LabelGraphics.js b/Source/DataSources/LabelGraphics.js
index 85a468c21c88..3495a7e88e08 100644
--- a/Source/DataSources/LabelGraphics.js
+++ b/Source/DataSources/LabelGraphics.js
@@ -4,6 +4,34 @@ import DeveloperError from "../Core/DeveloperError.js";
import Event from "../Core/Event.js";
import createPropertyDescriptor from "./createPropertyDescriptor.js";
+/**
+ * @typedef {Object} LabelGraphics.ConstructorOptions
+ *
+ * Initialization options for the LabelGraphics constructor
+ *
+ * @property {Property | boolean} [show=true] A boolean Property specifying the visibility of the label.
+ * @property {Property | string} [text] A Property specifying the text. Explicit newlines '\n' are supported.
+ * @property {Property | string} [font='30px sans-serif'] A Property specifying the CSS font.
+ * @property {Property | LabelStyle} [style=LabelStyle.FILL] A Property specifying the {@link LabelStyle}.
+ * @property {Property | number} [scale=1.0] A numeric Property specifying the scale to apply to the text.
+ * @property {Property | boolean} [showBackground=false] A boolean Property specifying the visibility of the background behind the label.
+ * @property {Property | Color} [backgroundColor=new Color(0.165, 0.165, 0.165, 0.8)] A Property specifying the background {@link Color}.
+ * @property {Property | Cartesian2} [backgroundPadding=new Cartesian2(7, 5)] A {@link Cartesian2} Property specifying the horizontal and vertical background padding in pixels.
+ * @property {Property | Cartesian2} [pixelOffset=Cartesian2.ZERO] A {@link Cartesian2} Property specifying the pixel offset.
+ * @property {Property | Cartesian3} [eyeOffset=Cartesian3.ZERO] A {@link Cartesian3} Property specifying the eye offset.
+ * @property {Property | HorizontalOrigin} [horizontalOrigin=HorizontalOrigin.CENTER] A Property specifying the {@link HorizontalOrigin}.
+ * @property {Property | VerticalOrigin} [verticalOrigin=VerticalOrigin.CENTER] A Property specifying the {@link VerticalOrigin}.
+ * @property {Property | HeightReference} [heightReference=HeightReference.NONE] A Property specifying what the height is relative to.
+ * @property {Property | Color} [fillColor=Color.WHITE] A Property specifying the fill {@link Color}.
+ * @property {Property | Color} [outlineColor=Color.BLACK] A Property specifying the outline {@link Color}.
+ * @property {Property | number} [outlineWidth=1.0] A numeric Property specifying the outline width.
+ * @property {Property | NearFarScalar} [translucencyByDistance] A {@link NearFarScalar} Property used to set translucency based on distance from the camera.
+ * @property {Property | NearFarScalar} [pixelOffsetScaleByDistance] A {@link NearFarScalar} Property used to set pixelOffset based on distance from the camera.
+ * @property {Property | NearFarScalar} [scaleByDistance] A {@link NearFarScalar} Property used to set scale based on distance from the camera.
+ * @property {Property | DistanceDisplayCondition} [distanceDisplayCondition] A Property specifying at what distance from the camera that this label will be displayed.
+ * @property {Property | number} [disableDepthTestDistance] A Property specifying the distance from the camera at which to disable the depth test to.
+ */
+
/**
* Describes a two dimensional label located at the position of the containing {@link Entity}.
*
@@ -16,28 +44,7 @@ import createPropertyDescriptor from "./createPropertyDescriptor.js";
* @alias LabelGraphics
* @constructor
*
- * @param {Object} [options] Object with the following properties:
- * @param {Property} [options.show=true] A boolean Property specifying the visibility of the label.
- * @param {Property} [options.text] A Property specifying the text. Explicit newlines '\n' are supported.
- * @param {Property} [options.font='30px sans-serif'] A Property specifying the CSS font.
- * @param {Property} [options.style=LabelStyle.FILL] A Property specifying the {@link LabelStyle}.
- * @param {Property} [options.scale=1.0] A numeric Property specifying the scale to apply to the text.
- * @param {Property} [options.showBackground=false] A boolean Property specifying the visibility of the background behind the label.
- * @param {Property} [options.backgroundColor=new Color(0.165, 0.165, 0.165, 0.8)] A Property specifying the background {@link Color}.
- * @param {Property} [options.backgroundPadding=new Cartesian2(7, 5)] A {@link Cartesian2} Property specifying the horizontal and vertical background padding in pixels.
- * @param {Property} [options.pixelOffset=Cartesian2.ZERO] A {@link Cartesian2} Property specifying the pixel offset.
- * @param {Property} [options.eyeOffset=Cartesian3.ZERO] A {@link Cartesian3} Property specifying the eye offset.
- * @param {Property} [options.horizontalOrigin=HorizontalOrigin.CENTER] A Property specifying the {@link HorizontalOrigin}.
- * @param {Property} [options.verticalOrigin=VerticalOrigin.CENTER] A Property specifying the {@link VerticalOrigin}.
- * @param {Property} [options.heightReference=HeightReference.NONE] A Property specifying what the height is relative to.
- * @param {Property} [options.fillColor=Color.WHITE] A Property specifying the fill {@link Color}.
- * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the outline {@link Color}.
- * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the outline width.
- * @param {Property} [options.translucencyByDistance] A {@link NearFarScalar} Property used to set translucency based on distance from the camera.
- * @param {Property} [options.pixelOffsetScaleByDistance] A {@link NearFarScalar} Property used to set pixelOffset based on distance from the camera.
- * @param {Property} [options.scaleByDistance] A {@link NearFarScalar} Property used to set scale based on distance from the camera.
- * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this label will be displayed.
- * @param {Property} [options.disableDepthTestDistance] A Property specifying the distance from the camera at which to disable the depth test to.
+ * @param {LabelGraphics.ConstructorOptions} [options] Object describing initialization options
*
* @demo {@link https://sandcastle.cesium.com/index.html?src=Labels.html|Cesium Sandcastle Labels Demo}
*/
@@ -106,7 +113,7 @@ Object.defineProperties(LabelGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying the visibility of the label.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
show: createPropertyDescriptor("show"),
@@ -114,14 +121,14 @@ Object.defineProperties(LabelGraphics.prototype, {
* Gets or sets the string Property specifying the text of the label.
* Explicit newlines '\n' are supported.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
text: createPropertyDescriptor("text"),
/**
* Gets or sets the string Property specifying the font in CSS syntax.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font|CSS font on MDN}
*/
font: createPropertyDescriptor("font"),
@@ -129,7 +136,7 @@ Object.defineProperties(LabelGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link LabelStyle}.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
style: createPropertyDescriptor("style"),
@@ -144,7 +151,7 @@ Object.defineProperties(LabelGraphics.prototype, {
*
*
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 1.0
*/
scale: createPropertyDescriptor("scale"),
@@ -152,7 +159,7 @@ Object.defineProperties(LabelGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying the visibility of the background behind the label.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default false
*/
showBackground: createPropertyDescriptor("showBackground"),
@@ -160,7 +167,7 @@ Object.defineProperties(LabelGraphics.prototype, {
/**
* Gets or sets the Property specifying the background {@link Color}.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default new Color(0.165, 0.165, 0.165, 0.8)
*/
backgroundColor: createPropertyDescriptor("backgroundColor"),
@@ -169,7 +176,7 @@ Object.defineProperties(LabelGraphics.prototype, {
* Gets or sets the {@link Cartesian2} Property specifying the label's horizontal and vertical
* background padding in pixels.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default new Cartesian2(7, 5)
*/
backgroundPadding: createPropertyDescriptor("backgroundPadding"),
@@ -189,7 +196,7 @@ Object.defineProperties(LabelGraphics.prototype, {
*
*
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Cartesian2.ZERO
*/
pixelOffset: createPropertyDescriptor("pixelOffset"),
@@ -214,7 +221,7 @@ Object.defineProperties(LabelGraphics.prototype, {
*
*
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Cartesian3.ZERO
*/
eyeOffset: createPropertyDescriptor("eyeOffset"),
@@ -222,21 +229,21 @@ Object.defineProperties(LabelGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link HorizontalOrigin}.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
horizontalOrigin: createPropertyDescriptor("horizontalOrigin"),
/**
* Gets or sets the Property specifying the {@link VerticalOrigin}.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
verticalOrigin: createPropertyDescriptor("verticalOrigin"),
/**
* Gets or sets the Property specifying the {@link HeightReference}.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default HeightReference.NONE
*/
heightReference: createPropertyDescriptor("heightReference"),
@@ -244,43 +251,43 @@ Object.defineProperties(LabelGraphics.prototype, {
/**
* Gets or sets the Property specifying the fill {@link Color}.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
fillColor: createPropertyDescriptor("fillColor"),
/**
* Gets or sets the Property specifying the outline {@link Color}.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
outlineColor: createPropertyDescriptor("outlineColor"),
/**
* Gets or sets the numeric Property specifying the outline width.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
outlineWidth: createPropertyDescriptor("outlineWidth"),
/**
* Gets or sets {@link NearFarScalar} Property specifying the translucency of the label based on the distance from the camera.
* A label's translucency will interpolate between the {@link NearFarScalar#nearValue} and
- * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds
+ * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds
* of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}.
* Outside of these ranges the label's translucency remains clamped to the nearest bound.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
translucencyByDistance: createPropertyDescriptor("translucencyByDistance"),
/**
* Gets or sets {@link NearFarScalar} Property specifying the pixel offset of the label based on the distance from the camera.
* A label's pixel offset will interpolate between the {@link NearFarScalar#nearValue} and
- * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds
+ * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds
* of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}.
* Outside of these ranges the label's pixel offset remains clamped to the nearest bound.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
pixelOffsetScaleByDistance: createPropertyDescriptor(
"pixelOffsetScaleByDistance"
@@ -289,19 +296,19 @@ Object.defineProperties(LabelGraphics.prototype, {
/**
* Gets or sets near and far scaling properties of a Label based on the label's distance from the camera.
* A label's scale will interpolate between the {@link NearFarScalar#nearValue} and
- * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds
+ * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds
* of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}.
* Outside of these ranges the label's scale remains clamped to the nearest bound. If undefined,
* scaleByDistance will be disabled.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
scaleByDistance: createPropertyDescriptor("scaleByDistance"),
/**
* Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this label will be displayed.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
distanceDisplayCondition: createPropertyDescriptor(
"distanceDisplayCondition"
@@ -311,7 +318,7 @@ Object.defineProperties(LabelGraphics.prototype, {
* Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain.
* When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied.
* @memberof LabelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
disableDepthTestDistance: createPropertyDescriptor(
"disableDepthTestDistance"
diff --git a/Source/DataSources/ModelGraphics.js b/Source/DataSources/ModelGraphics.js
index 94a52176a947..a30b00954c88 100644
--- a/Source/DataSources/ModelGraphics.js
+++ b/Source/DataSources/ModelGraphics.js
@@ -18,6 +18,34 @@ function createArticulationStagePropertyBag(value) {
return new PropertyBag(value);
}
+/**
+ * @typedef {Object} ModelGraphics.ConstructorOptions
+ *
+ * Initialization options for the ModelGraphics constructor
+ *
+ * @property {Property | boolean} [show=true] A boolean Property specifying the visibility of the model.
+ * @property {Property | string | Resource} [uri] A string or Resource Property specifying the URI of the glTF asset.
+ * @property {Property | number} [scale=1.0] A numeric Property specifying a uniform linear scale.
+ * @property {Property | number} [minimumPixelSize=0.0] A numeric Property specifying the approximate minimum pixel size of the model regardless of zoom.
+ * @property {Property | number} [maximumScale] The maximum scale size of a model. An upper limit for minimumPixelSize.
+ * @property {Property | boolean} [incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded.
+ * @property {Property | boolean} [runAnimations=true] A boolean Property specifying if glTF animations specified in the model should be started.
+ * @property {Property | boolean} [clampAnimations=true] A boolean Property specifying if glTF animations should hold the last pose for time durations with no keyframes.
+ * @property {Property | ShadowMode} [shadows=ShadowMode.ENABLED] An enum Property specifying whether the model casts or receives shadows from light sources.
+ * @property {Property | HeightReference} [heightReference=HeightReference.NONE] A Property specifying what the height is relative to.
+ * @property {Property | Color} [silhouetteColor=Color.RED] A Property specifying the {@link Color} of the silhouette.
+ * @property {Property | number} [silhouetteSize=0.0] A numeric Property specifying the size of the silhouette in pixels.
+ * @property {Property | Color} [color=Color.WHITE] A Property specifying the {@link Color} that blends with the model's rendered color.
+ * @property {Property | ColorBlendMode} [colorBlendMode=ColorBlendMode.HIGHLIGHT] An enum Property specifying how the color blends with the model.
+ * @property {Property | number} [colorBlendAmount=0.5] A numeric Property specifying the color strength when the colorBlendMode
is MIX
. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two.
+ * @property {Property | Cartesian2} [imageBasedLightingFactor=new Cartesian2(1.0, 1.0)] A property specifying the contribution from diffuse and specular image-based lighting.
+ * @property {Property | Color} [lightColor] A property specifying the light color when shading the model. When undefined
the scene's light color is used instead.
+ * @property {Property | DistanceDisplayCondition} [distanceDisplayCondition] A Property specifying at what distance from the camera that this model will be displayed.
+ * @property {PropertyBag | Object.} [nodeTransformations] An object, where keys are names of nodes, and values are {@link TranslationRotationScale} Properties describing the transformation to apply to that node. The transformation is applied after the node's existing transformation as specified in the glTF, and does not replace the node's existing transformation.
+ * @property {PropertyBag | Object.} [articulations] An object, where keys are composed of an articulation name, a single space, and a stage name, and the values are numeric properties.
+ * @property {Property | ClippingPlaneCollection} [clippingPlanes] A property specifying the {@link ClippingPlaneCollection} used to selectively disable rendering the model.
+ */
+
/**
* A 3D model based on {@link https://github.com/KhronosGroup/glTF|glTF}, the runtime asset format for WebGL, OpenGL ES, and OpenGL.
* The position and orientation of the model is determined by the containing {@link Entity}.
@@ -29,28 +57,7 @@ function createArticulationStagePropertyBag(value) {
* @alias ModelGraphics
* @constructor
*
- * @param {Object} [options] Object with the following properties:
- * @param {Property} [options.show=true] A boolean Property specifying the visibility of the model.
- * @param {Property} [options.uri] A string or Resource Property specifying the URI of the glTF asset.
- * @param {Property} [options.scale=1.0] A numeric Property specifying a uniform linear scale.
- * @param {Property} [options.minimumPixelSize=0.0] A numeric Property specifying the approximate minimum pixel size of the model regardless of zoom.
- * @param {Property} [options.maximumScale] The maximum scale size of a model. An upper limit for minimumPixelSize.
- * @param {Property} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded.
- * @param {Property} [options.runAnimations=true] A boolean Property specifying if glTF animations specified in the model should be started.
- * @param {Property} [options.clampAnimations=true] A boolean Property specifying if glTF animations should hold the last pose for time durations with no keyframes.
- * @param {Property} [options.shadows=ShadowMode.ENABLED] An enum Property specifying whether the model casts or receives shadows from light sources.
- * @param {Property} [options.heightReference=HeightReference.NONE] A Property specifying what the height is relative to.
- * @param {Property} [options.silhouetteColor=Color.RED] A Property specifying the {@link Color} of the silhouette.
- * @param {Property} [options.silhouetteSize=0.0] A numeric Property specifying the size of the silhouette in pixels.
- * @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} that blends with the model's rendered color.
- * @param {Property} [options.colorBlendMode=ColorBlendMode.HIGHLIGHT] An enum Property specifying how the color blends with the model.
- * @param {Property} [options.colorBlendAmount=0.5] A numeric Property specifying the color strength when the colorBlendMode
is MIX
. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two.
- * @param {Property} [options.imageBasedLightingFactor=new Cartesian2(1.0, 1.0)] A property specifying the contribution from diffuse and specular image-based lighting.
- * @param {Property} [options.lightColor] A property specifying the light color when shading the model. When undefined
the scene's light color is used instead.
- * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this model will be displayed.
- * @param {PropertyBag} [options.nodeTransformations] An object, where keys are names of nodes, and values are {@link TranslationRotationScale} Properties describing the transformation to apply to that node. The transformation is applied after the node's existing transformation as specified in the glTF, and does not replace the node's existing transformation.
- * @param {PropertyBag} [options.articulations] An object, where keys are composed of an articulation name, a single space, and a stage name, and the values are numeric properties.
- * @param {Property} [options.clippingPlanes] A property specifying the {@link ClippingPlaneCollection} used to selectively disable rendering the model.
+ * @param {ModelGraphics.ConstructorOptions} [options] Object describing initialization options
*
* @see {@link https://cesium.com/docs/tutorials/3d-models/|3D Models Tutorial}
* @demo {@link https://sandcastle.cesium.com/index.html?src=3D%20Models.html|Cesium Sandcastle 3D Models Demo}
@@ -119,7 +126,7 @@ Object.defineProperties(ModelGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying the visibility of the model.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default true
*/
show: createPropertyDescriptor("show"),
@@ -127,7 +134,7 @@ Object.defineProperties(ModelGraphics.prototype, {
/**
* Gets or sets the string Property specifying the URI of the glTF asset.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
uri: createPropertyDescriptor("uri"),
@@ -136,7 +143,7 @@ Object.defineProperties(ModelGraphics.prototype, {
* for this model. Values greater than 1.0 increase the size of the model while
* values less than 1.0 decrease it.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 1.0
*/
scale: createPropertyDescriptor("scale"),
@@ -147,7 +154,7 @@ Object.defineProperties(ModelGraphics.prototype, {
* a model is visible even when the viewer zooms out. When 0.0
,
* no minimum size is enforced.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 0.0
*/
minimumPixelSize: createPropertyDescriptor("minimumPixelSize"),
@@ -157,7 +164,7 @@ Object.defineProperties(ModelGraphics.prototype, {
* size of a model. This property is used as an upper limit for
* {@link ModelGraphics#minimumPixelSize}.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
maximumScale: createPropertyDescriptor("maximumScale"),
@@ -165,7 +172,7 @@ Object.defineProperties(ModelGraphics.prototype, {
* Get or sets the boolean Property specifying whether textures
* may continue to stream in after the model is loaded.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
incrementallyLoadTextures: createPropertyDescriptor(
"incrementallyLoadTextures"
@@ -174,7 +181,7 @@ Object.defineProperties(ModelGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying if glTF animations should be run.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default true
*/
runAnimations: createPropertyDescriptor("runAnimations"),
@@ -182,7 +189,7 @@ Object.defineProperties(ModelGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying if glTF animations should hold the last pose for time durations with no keyframes.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default true
*/
clampAnimations: createPropertyDescriptor("clampAnimations"),
@@ -191,7 +198,7 @@ Object.defineProperties(ModelGraphics.prototype, {
* Get or sets the enum Property specifying whether the model
* casts or receives shadows from light sources.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default ShadowMode.ENABLED
*/
shadows: createPropertyDescriptor("shadows"),
@@ -199,7 +206,7 @@ Object.defineProperties(ModelGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link HeightReference}.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default HeightReference.NONE
*/
heightReference: createPropertyDescriptor("heightReference"),
@@ -207,7 +214,7 @@ Object.defineProperties(ModelGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link Color} of the silhouette.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Color.RED
*/
silhouetteColor: createPropertyDescriptor("silhouetteColor"),
@@ -215,7 +222,7 @@ Object.defineProperties(ModelGraphics.prototype, {
/**
* Gets or sets the numeric Property specifying the size of the silhouette in pixels.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 0.0
*/
silhouetteSize: createPropertyDescriptor("silhouetteSize"),
@@ -223,7 +230,7 @@ Object.defineProperties(ModelGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link Color} that blends with the model's rendered color.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Color.WHITE
*/
color: createPropertyDescriptor("color"),
@@ -231,7 +238,7 @@ Object.defineProperties(ModelGraphics.prototype, {
/**
* Gets or sets the enum Property specifying how the color blends with the model.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default ColorBlendMode.HIGHLIGHT
*/
colorBlendMode: createPropertyDescriptor("colorBlendMode"),
@@ -241,7 +248,7 @@ Object.defineProperties(ModelGraphics.prototype, {
* A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with
* any value in-between resulting in a mix of the two.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 0.5
*/
colorBlendAmount: createPropertyDescriptor("colorBlendAmount"),
@@ -249,7 +256,7 @@ Object.defineProperties(ModelGraphics.prototype, {
/**
* A property specifying the {@link Cartesian2} used to scale the diffuse and specular image-based lighting contribution to the final color.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
imageBasedLightingFactor: createPropertyDescriptor(
"imageBasedLightingFactor"
@@ -258,14 +265,14 @@ Object.defineProperties(ModelGraphics.prototype, {
/**
* A property specifying the {@link Cartesian3} light color when shading the model. When undefined
the scene's light color is used instead.
* @memberOf ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
lightColor: createPropertyDescriptor("lightColor"),
/**
* Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this model will be displayed.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
distanceDisplayCondition: createPropertyDescriptor(
"distanceDisplayCondition"
@@ -299,7 +306,7 @@ Object.defineProperties(ModelGraphics.prototype, {
/**
* A property specifying the {@link ClippingPlaneCollection} used to selectively disable rendering the model.
* @memberof ModelGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
clippingPlanes: createPropertyDescriptor("clippingPlanes"),
});
diff --git a/Source/DataSources/NodeTransformationProperty.js b/Source/DataSources/NodeTransformationProperty.js
index 9cf7ad22ccda..f5070203484f 100644
--- a/Source/DataSources/NodeTransformationProperty.js
+++ b/Source/DataSources/NodeTransformationProperty.js
@@ -13,9 +13,9 @@ var defaultNodeTransformation = new TranslationRotationScale();
* @constructor
*
* @param {Object} [options] Object with the following properties:
- * @param {Property} [options.translation=Cartesian3.ZERO] A {@link Cartesian3} Property specifying the (x, y, z) translation to apply to the node.
- * @param {Property} [options.rotation=Quaternion.IDENTITY] A {@link Quaternion} Property specifying the (x, y, z, w) rotation to apply to the node.
- * @param {Property} [options.scale=new Cartesian3(1.0, 1.0, 1.0)] A {@link Cartesian3} Property specifying the (x, y, z) scaling to apply to the node.
+ * @param {Property|Cartesian3} [options.translation=Cartesian3.ZERO] A {@link Cartesian3} Property specifying the (x, y, z) translation to apply to the node.
+ * @param {Property|Quaternion} [options.rotation=Quaternion.IDENTITY] A {@link Quaternion} Property specifying the (x, y, z, w) rotation to apply to the node.
+ * @param {Property|Cartesian3} [options.scale=new Cartesian3(1.0, 1.0, 1.0)] A {@link Cartesian3} Property specifying the (x, y, z) scaling to apply to the node.
*/
function NodeTransformationProperty(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
@@ -70,7 +70,7 @@ Object.defineProperties(NodeTransformationProperty.prototype, {
/**
* Gets or sets the {@link Cartesian3} Property specifying the (x, y, z) translation to apply to the node.
* @memberof NodeTransformationProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Cartesian3.ZERO
*/
translation: createPropertyDescriptor("translation"),
@@ -78,7 +78,7 @@ Object.defineProperties(NodeTransformationProperty.prototype, {
/**
* Gets or sets the {@link Quaternion} Property specifying the (x, y, z, w) rotation to apply to the node.
* @memberof NodeTransformationProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Quaternion.IDENTITY
*/
rotation: createPropertyDescriptor("rotation"),
@@ -86,7 +86,7 @@ Object.defineProperties(NodeTransformationProperty.prototype, {
/**
* Gets or sets the {@link Cartesian3} Property specifying the (x, y, z) scaling to apply to the node.
* @memberof NodeTransformationProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default new Cartesian3(1.0, 1.0, 1.0)
*/
scale: createPropertyDescriptor("scale"),
diff --git a/Source/DataSources/PathGraphics.js b/Source/DataSources/PathGraphics.js
index b2d36c1ba7c5..4e95e18792de 100644
--- a/Source/DataSources/PathGraphics.js
+++ b/Source/DataSources/PathGraphics.js
@@ -5,20 +5,27 @@ import Event from "../Core/Event.js";
import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor.js";
import createPropertyDescriptor from "./createPropertyDescriptor.js";
+/**
+ * @typedef {Object} PathGraphics.ConstructorOptions
+ *
+ * Initialization options for the PathGraphics constructor
+ *
+ * @property {Property | boolean} [show=true] A boolean Property specifying the visibility of the path.
+ * @property {Property | number} [leadTime] A Property specifying the number of seconds in front the object to show.
+ * @property {Property | number} [trailTime] A Property specifying the number of seconds behind of the object to show.
+ * @property {Property | number} [width=1.0] A numeric Property specifying the width in pixels.
+ * @property {Property | number} [resolution=60] A numeric Property specifying the maximum number of seconds to step when sampling the position.
+ * @property {MaterialProperty | Color} [material=Color.WHITE] A Property specifying the material used to draw the path.
+ * @property {Property | DistanceDisplayCondition} [distanceDisplayCondition] A Property specifying at what distance from the camera that this path will be displayed.
+ */
+
/**
* Describes a polyline defined as the path made by an {@link Entity} as it moves over time.
*
* @alias PathGraphics
* @constructor
*
- * @param {Object} [options] Object with the following properties:
- * @param {Property} [options.show=true] A boolean Property specifying the visibility of the path.
- * @param {Property} [options.leadTime] A Property specifying the number of seconds in front the object to show.
- * @param {Property} [options.trailTime] A Property specifying the number of seconds behind of the object to show.
- * @param {Property} [options.width=1.0] A numeric Property specifying the width in pixels.
- * @param {Property} [options.resolution=60] A numeric Property specifying the maximum number of seconds to step when sampling the position.
- * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to draw the path.
- * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this path will be displayed.
+ * @param {PathGraphics.ConstructorOptions} [options] Object describing initialization options
*/
function PathGraphics(options) {
this._definitionChanged = new Event();
@@ -56,7 +63,7 @@ Object.defineProperties(PathGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying the visibility of the path.
* @memberof PathGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default true
*/
show: createPropertyDescriptor("show"),
@@ -64,21 +71,21 @@ Object.defineProperties(PathGraphics.prototype, {
/**
* Gets or sets the Property specifying the number of seconds in front of the object to show.
* @memberof PathGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
leadTime: createPropertyDescriptor("leadTime"),
/**
* Gets or sets the Property specifying the number of seconds behind the object to show.
* @memberof PathGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
trailTime: createPropertyDescriptor("trailTime"),
/**
* Gets or sets the numeric Property specifying the width in pixels.
* @memberof PathGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 1.0
*/
width: createPropertyDescriptor("width"),
@@ -86,7 +93,7 @@ Object.defineProperties(PathGraphics.prototype, {
/**
* Gets or sets the Property specifying the maximum number of seconds to step when sampling the position.
* @memberof PathGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 60
*/
resolution: createPropertyDescriptor("resolution"),
@@ -102,7 +109,7 @@ Object.defineProperties(PathGraphics.prototype, {
/**
* Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this path will be displayed.
* @memberof PathGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
distanceDisplayCondition: createPropertyDescriptor(
"distanceDisplayCondition"
diff --git a/Source/DataSources/PlaneGraphics.js b/Source/DataSources/PlaneGraphics.js
index 3cd6e2a33f54..2745da6a6661 100644
--- a/Source/DataSources/PlaneGraphics.js
+++ b/Source/DataSources/PlaneGraphics.js
@@ -5,23 +5,30 @@ import Event from "../Core/Event.js";
import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor.js";
import createPropertyDescriptor from "./createPropertyDescriptor.js";
+/**
+ * @typedef {Object} PlaneGraphics.ConstructorOptions
+ *
+ * Initialization options for the PlaneGraphics constructor
+ *
+ * @property {Property | boolean} [show=true] A boolean Property specifying the visibility of the plane.
+ * @property {Property | Plane} [plane] A {@link Plane} Property specifying the normal and distance for the plane.
+ * @property {Property | Cartesian2} [dimensions] A {@link Cartesian2} Property specifying the width and height of the plane.
+ * @property {Property | boolean} [fill=true] A boolean Property specifying whether the plane is filled with the provided material.
+ * @property {MaterialProperty | Color} [material=Color.WHITE] A Property specifying the material used to fill the plane.
+ * @property {Property | boolean} [outline=false] A boolean Property specifying whether the plane is outlined.
+ * @property {Property | Color} [outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline.
+ * @property {Property | number} [outlineWidth=1.0] A numeric Property specifying the width of the outline.
+ * @property {Property | ShadowMode} [shadows=ShadowMode.DISABLED] An enum Property specifying whether the plane casts or receives shadows from light sources.
+ * @property {Property | DistanceDisplayCondition} [distanceDisplayCondition] A Property specifying at what distance from the camera that this plane will be displayed.
+ */
+
/**
* Describes a plane. The center position and orientation are determined by the containing {@link Entity}.
*
* @alias PlaneGraphics
* @constructor
*
- * @param {Object} [options] Object with the following properties:
- * @param {Property} [options.show=true] A boolean Property specifying the visibility of the plane.
- * @param {Property} [options.plane] A {@link Plane} Property specifying the normal and distance for the plane.
- * @param {Property} [options.dimensions] A {@link Cartesian2} Property specifying the width and height of the plane.
- * @param {Property} [options.fill=true] A boolean Property specifying whether the plane is filled with the provided material.
- * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the plane.
- * @param {Property} [options.outline=false] A boolean Property specifying whether the plane is outlined.
- * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline.
- * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline.
- * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the plane casts or receives shadows from light sources.
- * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this plane will be displayed.
+ * @param {PlaneGraphics.ConstructorOptions} [options] Object describing initialization options
*
* @demo {@link https://sandcastle.cesium.com/index.html?src=Plane.html|Cesium Sandcastle Plane Demo}
*/
@@ -67,7 +74,7 @@ Object.defineProperties(PlaneGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying the visibility of the plane.
* @memberof PlaneGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default true
*/
show: createPropertyDescriptor("show"),
@@ -76,7 +83,7 @@ Object.defineProperties(PlaneGraphics.prototype, {
* Gets or sets the {@link Plane} Property specifying the normal and distance of the plane.
*
* @memberof PlaneGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
plane: createPropertyDescriptor("plane"),
@@ -84,14 +91,14 @@ Object.defineProperties(PlaneGraphics.prototype, {
* Gets or sets the {@link Cartesian2} Property specifying the width and height of the plane.
*
* @memberof PlaneGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
dimensions: createPropertyDescriptor("dimensions"),
/**
* Gets or sets the boolean Property specifying whether the plane is filled with the provided material.
* @memberof PlaneGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default true
*/
fill: createPropertyDescriptor("fill"),
@@ -107,7 +114,7 @@ Object.defineProperties(PlaneGraphics.prototype, {
/**
* Gets or sets the Property specifying whether the plane is outlined.
* @memberof PlaneGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default false
*/
outline: createPropertyDescriptor("outline"),
@@ -115,7 +122,7 @@ Object.defineProperties(PlaneGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link Color} of the outline.
* @memberof PlaneGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Color.BLACK
*/
outlineColor: createPropertyDescriptor("outlineColor"),
@@ -123,7 +130,7 @@ Object.defineProperties(PlaneGraphics.prototype, {
/**
* Gets or sets the numeric Property specifying the width of the outline.
* @memberof PlaneGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 1.0
*/
outlineWidth: createPropertyDescriptor("outlineWidth"),
@@ -132,7 +139,7 @@ Object.defineProperties(PlaneGraphics.prototype, {
* Get or sets the enum Property specifying whether the plane
* casts or receives shadows from light sources.
* @memberof PlaneGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default ShadowMode.DISABLED
*/
shadows: createPropertyDescriptor("shadows"),
@@ -140,7 +147,7 @@ Object.defineProperties(PlaneGraphics.prototype, {
/**
* Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this plane will be displayed.
* @memberof PlaneGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
distanceDisplayCondition: createPropertyDescriptor(
"distanceDisplayCondition"
diff --git a/Source/DataSources/PointGraphics.js b/Source/DataSources/PointGraphics.js
index 3df09de18218..982d86906ff8 100644
--- a/Source/DataSources/PointGraphics.js
+++ b/Source/DataSources/PointGraphics.js
@@ -4,23 +4,30 @@ import DeveloperError from "../Core/DeveloperError.js";
import Event from "../Core/Event.js";
import createPropertyDescriptor from "./createPropertyDescriptor.js";
+/**
+ * @typedef {Object} PointGraphics.ConstructorOptions
+ *
+ * Initialization options for the PointGraphics constructor
+ *
+ * @property {Property | boolean} [show=true] A boolean Property specifying the visibility of the point.
+ * @property {Property | number} [pixelSize=1] A numeric Property specifying the size in pixels.
+ * @property {Property | HeightReference} [heightReference=HeightReference.NONE] A Property specifying what the height is relative to.
+ * @property {Property | Color} [color=Color.WHITE] A Property specifying the {@link Color} of the point.
+ * @property {Property | Color} [outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline.
+ * @property {Property | number} [outlineWidth=0] A numeric Property specifying the the outline width in pixels.
+ * @property {Property | NearFarScalar} [scaleByDistance] A {@link NearFarScalar} Property used to scale the point based on distance.
+ * @property {Property | NearFarScalar} [translucencyByDistance] A {@link NearFarScalar} Property used to set translucency based on distance from the camera.
+ * @property {Property | DistanceDisplayCondition} [distanceDisplayCondition] A Property specifying at what distance from the camera that this point will be displayed.
+ * @property {Property | number} [disableDepthTestDistance] A Property specifying the distance from the camera at which to disable the depth test to.
+ */
+
/**
* Describes a graphical point located at the position of the containing {@link Entity}.
*
* @alias PointGraphics
* @constructor
*
- * @param {Object} [options] Object with the following properties:
- * @param {Property} [options.show=true] A boolean Property specifying the visibility of the point.
- * @param {Property} [options.pixelSize=1] A numeric Property specifying the size in pixels.
- * @param {Property} [options.heightReference=HeightReference.NONE] A Property specifying what the height is relative to.
- * @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} of the point.
- * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline.
- * @param {Property} [options.outlineWidth=0] A numeric Property specifying the the outline width in pixels.
- * @param {Property} [options.scaleByDistance] A {@link NearFarScalar} Property used to scale the point based on distance.
- * @param {Property} [options.translucencyByDistance] A {@link NearFarScalar} Property used to set translucency based on distance from the camera.
- * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this point will be displayed.
- * @param {Property} [options.disableDepthTestDistance] A Property specifying the distance from the camera at which to disable the depth test to.
+ * @param {PointGraphics.ConstructorOptions} [options] Object describing initialization options
*/
function PointGraphics(options) {
this._definitionChanged = new Event();
@@ -65,7 +72,7 @@ Object.defineProperties(PointGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying the visibility of the point.
* @memberof PointGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default true
*/
show: createPropertyDescriptor("show"),
@@ -73,7 +80,7 @@ Object.defineProperties(PointGraphics.prototype, {
/**
* Gets or sets the numeric Property specifying the size in pixels.
* @memberof PointGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 1
*/
pixelSize: createPropertyDescriptor("pixelSize"),
@@ -81,7 +88,7 @@ Object.defineProperties(PointGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link HeightReference}.
* @memberof PointGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default HeightReference.NONE
*/
heightReference: createPropertyDescriptor("heightReference"),
@@ -89,7 +96,7 @@ Object.defineProperties(PointGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link Color} of the point.
* @memberof PointGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Color.WHITE
*/
color: createPropertyDescriptor("color"),
@@ -97,7 +104,7 @@ Object.defineProperties(PointGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link Color} of the outline.
* @memberof PointGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Color.BLACK
*/
outlineColor: createPropertyDescriptor("outlineColor"),
@@ -105,7 +112,7 @@ Object.defineProperties(PointGraphics.prototype, {
/**
* Gets or sets the numeric Property specifying the the outline width in pixels.
* @memberof PointGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 0
*/
outlineWidth: createPropertyDescriptor("outlineWidth"),
@@ -114,25 +121,25 @@ Object.defineProperties(PointGraphics.prototype, {
* Gets or sets the {@link NearFarScalar} Property used to scale the point based on distance.
* If undefined, a constant size is used.
* @memberof PointGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
scaleByDistance: createPropertyDescriptor("scaleByDistance"),
/**
* Gets or sets {@link NearFarScalar} Property specifying the translucency of the point based on the distance from the camera.
* A point's translucency will interpolate between the {@link NearFarScalar#nearValue} and
- * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds
+ * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds
* of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}.
* Outside of these ranges the points's translucency remains clamped to the nearest bound.
* @memberof PointGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
translucencyByDistance: createPropertyDescriptor("translucencyByDistance"),
/**
* Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this point will be displayed.
* @memberof PointGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
distanceDisplayCondition: createPropertyDescriptor(
"distanceDisplayCondition"
@@ -142,7 +149,7 @@ Object.defineProperties(PointGraphics.prototype, {
* Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain.
* When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied.
* @memberof PointGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
disableDepthTestDistance: createPropertyDescriptor(
"disableDepthTestDistance"
diff --git a/Source/DataSources/PolygonGraphics.js b/Source/DataSources/PolygonGraphics.js
index 2650b8e9dc39..fb813e568dca 100644
--- a/Source/DataSources/PolygonGraphics.js
+++ b/Source/DataSources/PolygonGraphics.js
@@ -15,6 +15,34 @@ function createPolygonHierarchyProperty(value) {
return new ConstantProperty(value);
}
+/**
+ * @typedef {Object} PolygonGraphics.ConstructorOptions
+ *
+ * Initialization options for the PolygonGraphics constructor
+ *
+ * @property {Property | boolean} [show=true] A boolean Property specifying the visibility of the polygon.
+ * @property {Property | PolygonHierarchy} [hierarchy] A Property specifying the {@link PolygonHierarchy}.
+ * @property {Property | number} [height=0] A numeric Property specifying the altitude of the polygon relative to the ellipsoid surface.
+ * @property {Property | HeightReference} [heightReference=HeightReference.NONE] A Property specifying what the height is relative to.
+ * @property {Property | number} [extrudedHeight] A numeric Property specifying the altitude of the polygon's extruded face relative to the ellipsoid surface.
+ * @property {Property | HeightReference} [extrudedHeightReference=HeightReference.NONE] A Property specifying what the extrudedHeight is relative to.
+ * @property {Property | number} [stRotation=0.0] A numeric property specifying the rotation of the polygon texture counter-clockwise from north.
+ * @property {Property | number} [granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude point.
+ * @property {Property | boolean} [fill=true] A boolean Property specifying whether the polygon is filled with the provided material.
+ * @property {MaterialProperty | Color} [material=Color.WHITE] A Property specifying the material used to fill the polygon.
+ * @property {Property | boolean} [outline=false] A boolean Property specifying whether the polygon is outlined.
+ * @property {Property | Color} [outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline.
+ * @property {Property | number} [outlineWidth=1.0] A numeric Property specifying the width of the outline.
+ * @property {Property | boolean} [perPositionHeight=false] A boolean specifying whether or not the height of each position is used.
+ * @property {Boolean | boolean} [closeTop=true] When false, leaves off the top of an extruded polygon open.
+ * @property {Boolean | boolean} [closeBottom=true] When false, leaves off the bottom of an extruded polygon open.
+ * @property {Property | ArcType} [arcType=ArcType.GEODESIC] The type of line the polygon edges must follow.
+ * @property {Property | ShadowMode} [shadows=ShadowMode.DISABLED] An enum Property specifying whether the polygon casts or receives shadows from light sources.
+ * @property {Property | DistanceDisplayCondition} [distanceDisplayCondition] A Property specifying at what distance from the camera that this polygon will be displayed.
+ * @property {Property | ClassificationType} [classificationType=ClassificationType.BOTH] An enum Property specifying whether this polygon will classify terrain, 3D Tiles, or both when on the ground.
+ * @property {ConstantProperty | number} [zIndex=0] A property specifying the zIndex used for ordering ground geometry. Only has an effect if the polygon is constant and neither height or extrudedHeight are specified.
+ */
+
/**
* Describes a polygon defined by an hierarchy of linear rings which make up the outer shape and any nested holes.
* The polygon conforms to the curvature of the globe and can be placed on the surface or
@@ -23,28 +51,7 @@ function createPolygonHierarchyProperty(value) {
* @alias PolygonGraphics
* @constructor
*
- * @param {Object} [options] Object with the following properties:
- * @param {Property} [options.show=true] A boolean Property specifying the visibility of the polygon.
- * @param {Property} [options.hierarchy] A Property specifying the {@link PolygonHierarchy}.
- * @param {Property} [options.height=0] A numeric Property specifying the altitude of the polygon relative to the ellipsoid surface.
- * @param {Property} [options.heightReference=HeightReference.NONE] A Property specifying what the height is relative to.
- * @param {Property} [options.extrudedHeight] A numeric Property specifying the altitude of the polygon's extruded face relative to the ellipsoid surface.
- * @param {Property} [options.extrudedHeightReference=HeightReference.NONE] A Property specifying what the extrudedHeight is relative to.
- * @param {Property} [options.stRotation=0.0] A numeric property specifying the rotation of the polygon texture counter-clockwise from north.
- * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude point.
- * @param {Property} [options.fill=true] A boolean Property specifying whether the polygon is filled with the provided material.
- * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the polygon.
- * @param {Property} [options.outline=false] A boolean Property specifying whether the polygon is outlined.
- * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline.
- * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline.
- * @param {Property} [options.perPositionHeight=false] A boolean specifying whether or not the the height of each position is used.
- * @param {Boolean} [options.closeTop=true] When false, leaves off the top of an extruded polygon open.
- * @param {Boolean} [options.closeBottom=true] When false, leaves off the bottom of an extruded polygon open.
- * @param {Property} [options.arcType=ArcType.GEODESIC] The type of line the polygon edges must follow.
- * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the polygon casts or receives shadows from light sources.
- * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this polygon will be displayed.
- * @param {Property} [options.classificationType=ClassificationType.BOTH] An enum Property specifying whether this polygon will classify terrain, 3D Tiles, or both when on the ground.
- * @param {ConstantProperty} [options.zIndex=0] A property specifying the zIndex used for ordering ground geometry. Only has an effect if the polygon is constant and neither height or extrudedHeight are specified.
+ * @param {PolygonGraphics.ConstructorOptions} [options] Object describing initialization options
*
* @see Entity
* @demo {@link https://sandcastle.cesium.com/index.html?src=Polygon.html|Cesium Sandcastle Polygon Demo}
@@ -114,7 +121,7 @@ Object.defineProperties(PolygonGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying the visibility of the polygon.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default true
*/
show: createPropertyDescriptor("show"),
@@ -122,7 +129,7 @@ Object.defineProperties(PolygonGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link PolygonHierarchy}.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
hierarchy: createPropertyDescriptor(
"hierarchy",
@@ -133,7 +140,7 @@ Object.defineProperties(PolygonGraphics.prototype, {
/**
* Gets or sets the numeric Property specifying the constant altitude of the polygon.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 0.0
*/
height: createPropertyDescriptor("height"),
@@ -141,7 +148,7 @@ Object.defineProperties(PolygonGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link HeightReference}.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default HeightReference.NONE
*/
heightReference: createPropertyDescriptor("heightReference"),
@@ -151,14 +158,14 @@ Object.defineProperties(PolygonGraphics.prototype, {
* If {@link PolygonGraphics#perPositionHeight} is false, the volume starts at {@link PolygonGraphics#height} and ends at this altitude.
* If {@link PolygonGraphics#perPositionHeight} is true, the volume starts at the height of each {@link PolygonGraphics#hierarchy} position and ends at this altitude.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
extrudedHeight: createPropertyDescriptor("extrudedHeight"),
/**
* Gets or sets the Property specifying the extruded {@link HeightReference}.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default HeightReference.NONE
*/
extrudedHeightReference: createPropertyDescriptor("extrudedHeightReference"),
@@ -166,7 +173,7 @@ Object.defineProperties(PolygonGraphics.prototype, {
/**
* Gets or sets the numeric property specifying the rotation of the polygon texture counter-clockwise from north.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 0
*/
stRotation: createPropertyDescriptor("stRotation"),
@@ -174,7 +181,7 @@ Object.defineProperties(PolygonGraphics.prototype, {
/**
* Gets or sets the numeric Property specifying the angular distance between points on the polygon.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default {CesiumMath.RADIANS_PER_DEGREE}
*/
granularity: createPropertyDescriptor("granularity"),
@@ -182,7 +189,7 @@ Object.defineProperties(PolygonGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying whether the polygon is filled with the provided material.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default true
*/
fill: createPropertyDescriptor("fill"),
@@ -198,7 +205,7 @@ Object.defineProperties(PolygonGraphics.prototype, {
/**
* Gets or sets the Property specifying whether the polygon is outlined.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default false
*/
outline: createPropertyDescriptor("outline"),
@@ -206,7 +213,7 @@ Object.defineProperties(PolygonGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link Color} of the outline.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Color.BLACK
*/
outlineColor: createPropertyDescriptor("outlineColor"),
@@ -214,7 +221,7 @@ Object.defineProperties(PolygonGraphics.prototype, {
/**
* Gets or sets the numeric Property specifying the width of the outline.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 1.0
*/
outlineWidth: createPropertyDescriptor("outlineWidth"),
@@ -224,28 +231,28 @@ Object.defineProperties(PolygonGraphics.prototype, {
* If true, the shape will have non-uniform altitude defined by the height of each {@link PolygonGraphics#hierarchy} position.
* If false, the shape will have a constant altitude as specified by {@link PolygonGraphics#height}.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
perPositionHeight: createPropertyDescriptor("perPositionHeight"),
/**
* Gets or sets a boolean specifying whether or not the top of an extruded polygon is included.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
closeTop: createPropertyDescriptor("closeTop"),
/**
* Gets or sets a boolean specifying whether or not the bottom of an extruded polygon is included.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
closeBottom: createPropertyDescriptor("closeBottom"),
/**
* Gets or sets the {@link ArcType} Property specifying the type of lines the polygon edges use.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default ArcType.GEODESIC
*/
arcType: createPropertyDescriptor("arcType"),
@@ -254,7 +261,7 @@ Object.defineProperties(PolygonGraphics.prototype, {
* Get or sets the enum Property specifying whether the polygon
* casts or receives shadows from light sources.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default ShadowMode.DISABLED
*/
shadows: createPropertyDescriptor("shadows"),
@@ -262,7 +269,7 @@ Object.defineProperties(PolygonGraphics.prototype, {
/**
* Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this polygon will be displayed.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
distanceDisplayCondition: createPropertyDescriptor(
"distanceDisplayCondition"
@@ -271,7 +278,7 @@ Object.defineProperties(PolygonGraphics.prototype, {
/**
* Gets or sets the {@link ClassificationType} Property specifying whether this polygon will classify terrain, 3D Tiles, or both when on the ground.
* @memberof PolygonGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default ClassificationType.BOTH
*/
classificationType: createPropertyDescriptor("classificationType"),
@@ -279,7 +286,7 @@ Object.defineProperties(PolygonGraphics.prototype, {
/**
* Gets or sets the zIndex Prperty specifying the ordering of ground geometry. Only has an effect if the polygon is constant and neither height or extrudedHeight are specified.
* @memberof PolygonGraphics.prototype
- * @type {ConstantProperty}
+ * @type {ConstantProperty|undefined}
* @default 0
*/
zIndex: createPropertyDescriptor("zIndex"),
diff --git a/Source/DataSources/PolylineArrowMaterialProperty.js b/Source/DataSources/PolylineArrowMaterialProperty.js
index dbb9477d794f..cd413dce829a 100644
--- a/Source/DataSources/PolylineArrowMaterialProperty.js
+++ b/Source/DataSources/PolylineArrowMaterialProperty.js
@@ -7,7 +7,7 @@ import Property from "./Property.js";
/**
* A {@link MaterialProperty} that maps to PolylineArrow {@link Material} uniforms.
*
- * @param {Property} [color=Color.WHITE] The {@link Color} Property to be used.
+ * @param {Property|Color} [color=Color.WHITE] The {@link Color} Property to be used.
*
* @alias PolylineArrowMaterialProperty
* @constructor
@@ -51,7 +51,7 @@ Object.defineProperties(PolylineArrowMaterialProperty.prototype, {
/**
* Gets or sets the {@link Color} {@link Property}.
* @memberof PolylineArrowMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Color.WHITE
*/
color: createPropertyDescriptor("color"),
diff --git a/Source/DataSources/PolylineDashMaterialProperty.js b/Source/DataSources/PolylineDashMaterialProperty.js
index 97ae8bff5505..4165440d47f1 100644
--- a/Source/DataSources/PolylineDashMaterialProperty.js
+++ b/Source/DataSources/PolylineDashMaterialProperty.js
@@ -16,10 +16,10 @@ var defaultDashPattern = 255.0;
* @constructor
*
* @param {Object} [options] Object with the following properties:
- * @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} of the line.
- * @param {Property} [options.gapColor=Color.TRANSPARENT] A Property specifying the {@link Color} of the gaps in the line.
- * @param {Property} [options.dashLength=16.0] A numeric Property specifying the length of the dash pattern in pixels.
- * @param {Property} [options.dashPattern=255.0] A numeric Property specifying a 16 bit pattern for the dash
+ * @param {Property|Color} [options.color=Color.WHITE] A Property specifying the {@link Color} of the line.
+ * @param {Property|Color} [options.gapColor=Color.TRANSPARENT] A Property specifying the {@link Color} of the gaps in the line.
+ * @param {Property|Number} [options.dashLength=16.0] A numeric Property specifying the length of the dash pattern in pixels.
+ * @param {Property|Number} [options.dashPattern=255.0] A numeric Property specifying a 16 bit pattern for the dash
*/
function PolylineDashMaterialProperty(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
@@ -74,28 +74,28 @@ Object.defineProperties(PolylineDashMaterialProperty.prototype, {
/**
* Gets or sets the Property specifying the {@link Color} of the line.
* @memberof PolylineDashMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
color: createPropertyDescriptor("color"),
/**
* Gets or sets the Property specifying the {@link Color} of the gaps in the line.
* @memberof PolylineDashMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
gapColor: createPropertyDescriptor("gapColor"),
/**
* Gets or sets the numeric Property specifying the length of a dash cycle
* @memberof PolylineDashMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
dashLength: createPropertyDescriptor("dashLength"),
/**
* Gets or sets the numeric Property specifying a dash pattern
* @memberof PolylineDashMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
dashPattern: createPropertyDescriptor("dashPattern"),
});
diff --git a/Source/DataSources/PolylineGeometryUpdater.js b/Source/DataSources/PolylineGeometryUpdater.js
index b782858b1be8..96fc87575d61 100644
--- a/Source/DataSources/PolylineGeometryUpdater.js
+++ b/Source/DataSources/PolylineGeometryUpdater.js
@@ -616,6 +616,7 @@ PolylineGeometryUpdater.prototype._onEntityPropertyChanged = function (
* @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame.
*
* @exception {DeveloperError} This instance does not represent dynamic geometry.
+ * @private
*/
PolylineGeometryUpdater.prototype.createDynamicUpdater = function (
primitives,
diff --git a/Source/DataSources/PolylineGlowMaterialProperty.js b/Source/DataSources/PolylineGlowMaterialProperty.js
index 6bc811ed0f83..cf92ae555b60 100644
--- a/Source/DataSources/PolylineGlowMaterialProperty.js
+++ b/Source/DataSources/PolylineGlowMaterialProperty.js
@@ -15,9 +15,9 @@ var defaultTaperPower = 1.0;
* @constructor
*
* @param {Object} [options] Object with the following properties:
- * @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} of the line.
- * @param {Property} [options.glowPower=0.25] A numeric Property specifying the strength of the glow, as a percentage of the total line width.
- * @param {Property} [options.taperPower=1.0] A numeric Property specifying the strength of the tapering effect, as a percentage of the total line length. If 1.0 or higher, no taper effect is used.
+ * @param {Property|Color} [options.color=Color.WHITE] A Property specifying the {@link Color} of the line.
+ * @param {Property|Number} [options.glowPower=0.25] A numeric Property specifying the strength of the glow, as a percentage of the total line width.
+ * @param {Property|Number} [options.taperPower=1.0] A numeric Property specifying the strength of the tapering effect, as a percentage of the total line length. If 1.0 or higher, no taper effect is used.
*/
function PolylineGlowMaterialProperty(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
@@ -66,21 +66,21 @@ Object.defineProperties(PolylineGlowMaterialProperty.prototype, {
/**
* Gets or sets the Property specifying the {@link Color} of the line.
* @memberof PolylineGlowMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
color: createPropertyDescriptor("color"),
/**
* Gets or sets the numeric Property specifying the strength of the glow, as a percentage of the total line width (less than 1.0).
* @memberof PolylineGlowMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
glowPower: createPropertyDescriptor("glowPower"),
/**
* Gets or sets the numeric Property specifying the strength of the tapering effect, as a percentage of the total line length. If 1.0 or higher, no taper effect is used.
* @memberof PolylineGlowMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
taperPower: createPropertyDescriptor("taperPower"),
});
diff --git a/Source/DataSources/PolylineGraphics.js b/Source/DataSources/PolylineGraphics.js
index 11338241b749..90566a523341 100644
--- a/Source/DataSources/PolylineGraphics.js
+++ b/Source/DataSources/PolylineGraphics.js
@@ -5,6 +5,25 @@ import Event from "../Core/Event.js";
import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor.js";
import createPropertyDescriptor from "./createPropertyDescriptor.js";
+/**
+ * @typedef {Object} PolylineGraphics.ConstructorOptions
+ *
+ * Initialization options for the PolylineGraphics constructor
+ *
+ * @property {Property | boolean} [show=true] A boolean Property specifying the visibility of the polyline.
+ * @property {Property | Array} [positions] A Property specifying the array of {@link Cartesian3} positions that define the line strip.
+ * @property {Property | number} [width=1.0] A numeric Property specifying the width in pixels.
+ * @property {Property | number} [granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude if arcType is not ArcType.NONE.
+ * @property {MaterialProperty | Color} [material=Color.WHITE] A Property specifying the material used to draw the polyline.
+ * @property {MaterialProperty | Color} [depthFailMaterial] A property specifying the material used to draw the polyline when it is below the terrain.
+ * @property {Property | ArcType} [arcType=ArcType.GEODESIC] The type of line the polyline segments must follow.
+ * @property {Property | boolean} [clampToGround=false] A boolean Property specifying whether the Polyline should be clamped to the ground.
+ * @property {Property | ShadowMode} [shadows=ShadowMode.DISABLED] An enum Property specifying whether the polyline casts or receives shadows from light sources.
+ * @property {Property | DistanceDisplayCondition} [distanceDisplayCondition] A Property specifying at what distance from the camera that this polyline will be displayed.
+ * @property {Property | ClassificationType} [classificationType=ClassificationType.BOTH] An enum Property specifying whether this polyline will classify terrain, 3D Tiles, or both when on the ground.
+ * @property {Property | number} [zIndex=0] A Property specifying the zIndex used for ordering ground geometry. Only has an effect if `clampToGround` is true and polylines on terrain is supported.
+ */
+
/**
* Describes a polyline. The first two positions define a line segment,
* and each additional position defines a line segment from the previous position. The segments
@@ -13,19 +32,7 @@ import createPropertyDescriptor from "./createPropertyDescriptor.js";
* @alias PolylineGraphics
* @constructor
*
- * @param {Object} [options] Object with the following properties:
- * @param {Property} [options.show=true] A boolean Property specifying the visibility of the polyline.
- * @param {Property} [options.positions] A Property specifying the array of {@link Cartesian3} positions that define the line strip.
- * @param {Property} [options.width=1.0] A numeric Property specifying the width in pixels.
- * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude if arcType is not ArcType.NONE.
- * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to draw the polyline.
- * @param {MaterialProperty} [options.depthFailMaterial] A property specifying the material used to draw the polyline when it is below the terrain.
- * @param {ArcType} [options.arcType=ArcType.GEODESIC] The type of line the polyline segments must follow.
- * @param {Property} [options.clampToGround=false] A boolean Property specifying whether the Polyline should be clamped to the ground.
- * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the polyline casts or receives shadows from light sources.
- * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this polyline will be displayed.
- * @param {Property} [options.classificationType=ClassificationType.BOTH] An enum Property specifying whether this polyline will classify terrain, 3D Tiles, or both when on the ground.
- * @param {Property} [options.zIndex=0] A Property specifying the zIndex used for ordering ground geometry. Only has an effect if `clampToGround` is true and polylines on terrain is supported.
+ * @param {PolylineGraphics.ConstructorOptions} [options] Object describing initialization options
*
* @see Entity
* @demo {@link https://sandcastle.cesium.com/index.html?src=Polyline.html|Cesium Sandcastle Polyline Demo}
@@ -77,7 +84,7 @@ Object.defineProperties(PolylineGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying the visibility of the polyline.
* @memberof PolylineGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default true
*/
show: createPropertyDescriptor("show"),
@@ -86,14 +93,14 @@ Object.defineProperties(PolylineGraphics.prototype, {
* Gets or sets the Property specifying the array of {@link Cartesian3}
* positions that define the line strip.
* @memberof PolylineGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
positions: createPropertyDescriptor("positions"),
/**
* Gets or sets the numeric Property specifying the width in pixels.
* @memberof PolylineGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 1.0
*/
width: createPropertyDescriptor("width"),
@@ -101,7 +108,7 @@ Object.defineProperties(PolylineGraphics.prototype, {
/**
* Gets or sets the numeric Property specifying the angular distance between each latitude and longitude if arcType is not ArcType.NONE and clampToGround is false.
* @memberof PolylineGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Cesium.Math.RADIANS_PER_DEGREE
*/
granularity: createPropertyDescriptor("granularity"),
@@ -129,7 +136,7 @@ Object.defineProperties(PolylineGraphics.prototype, {
/**
* Gets or sets the {@link ArcType} Property specifying whether the line segments should be great arcs, rhumb lines or linearly connected.
* @memberof PolylineGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default ArcType.GEODESIC
*/
arcType: createPropertyDescriptor("arcType"),
@@ -138,7 +145,7 @@ Object.defineProperties(PolylineGraphics.prototype, {
* Gets or sets the boolean Property specifying whether the polyline
* should be clamped to the ground.
* @memberof PolylineGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default false
*/
clampToGround: createPropertyDescriptor("clampToGround"),
@@ -147,7 +154,7 @@ Object.defineProperties(PolylineGraphics.prototype, {
* Get or sets the enum Property specifying whether the polyline
* casts or receives shadows from light sources.
* @memberof PolylineGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default ShadowMode.DISABLED
*/
shadows: createPropertyDescriptor("shadows"),
@@ -155,7 +162,7 @@ Object.defineProperties(PolylineGraphics.prototype, {
/**
* Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this polyline will be displayed.
* @memberof PolylineGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
distanceDisplayCondition: createPropertyDescriptor(
"distanceDisplayCondition"
@@ -164,7 +171,7 @@ Object.defineProperties(PolylineGraphics.prototype, {
/**
* Gets or sets the {@link ClassificationType} Property specifying whether this polyline will classify terrain, 3D Tiles, or both when on the ground.
* @memberof PolylineGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default ClassificationType.BOTH
*/
classificationType: createPropertyDescriptor("classificationType"),
@@ -172,7 +179,7 @@ Object.defineProperties(PolylineGraphics.prototype, {
/**
* Gets or sets the zIndex Property specifying the ordering of the polyline. Only has an effect if `clampToGround` is true and polylines on terrain is supported.
* @memberof PolylineGraphics.prototype
- * @type {ConstantProperty}
+ * @type {ConstantProperty|undefined}
* @default 0
*/
zIndex: createPropertyDescriptor("zIndex"),
diff --git a/Source/DataSources/PolylineOutlineMaterialProperty.js b/Source/DataSources/PolylineOutlineMaterialProperty.js
index b59dba3310a0..7f93571f9689 100644
--- a/Source/DataSources/PolylineOutlineMaterialProperty.js
+++ b/Source/DataSources/PolylineOutlineMaterialProperty.js
@@ -15,9 +15,9 @@ var defaultOutlineWidth = 1.0;
* @constructor
*
* @param {Object} [options] Object with the following properties:
- * @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} of the line.
- * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline.
- * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline, in pixels.
+ * @param {Property|Color} [options.color=Color.WHITE] A Property specifying the {@link Color} of the line.
+ * @param {Property|Color} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline.
+ * @param {Property|Number} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline, in pixels.
*/
function PolylineOutlineMaterialProperty(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
@@ -70,7 +70,7 @@ Object.defineProperties(PolylineOutlineMaterialProperty.prototype, {
/**
* Gets or sets the Property specifying the {@link Color} of the line.
* @memberof PolylineOutlineMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Color.WHITE
*/
color: createPropertyDescriptor("color"),
@@ -78,7 +78,7 @@ Object.defineProperties(PolylineOutlineMaterialProperty.prototype, {
/**
* Gets or sets the Property specifying the {@link Color} of the outline.
* @memberof PolylineOutlineMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Color.BLACK
*/
outlineColor: createPropertyDescriptor("outlineColor"),
@@ -86,7 +86,7 @@ Object.defineProperties(PolylineOutlineMaterialProperty.prototype, {
/**
* Gets or sets the numeric Property specifying the width of the outline.
* @memberof PolylineOutlineMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 1.0
*/
outlineWidth: createPropertyDescriptor("outlineWidth"),
diff --git a/Source/DataSources/PolylineVolumeGraphics.js b/Source/DataSources/PolylineVolumeGraphics.js
index 541e5b8892b7..103da05c7dad 100644
--- a/Source/DataSources/PolylineVolumeGraphics.js
+++ b/Source/DataSources/PolylineVolumeGraphics.js
@@ -5,6 +5,25 @@ import Event from "../Core/Event.js";
import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor.js";
import createPropertyDescriptor from "./createPropertyDescriptor.js";
+/**
+ * @typedef {Object} PolylineVolumeGraphics.ConstructorOptions
+ *
+ * Initialization options for the PolylineVolumeGraphics constructor
+ *
+ * @property {Property | boolean} [show=true] A boolean Property specifying the visibility of the volume.
+ * @property {Property | Array} [positions] A Property specifying the array of {@link Cartesian3} positions which define the line strip.
+ * @property {Property | Array} [shape] A Property specifying the array of {@link Cartesian2} positions which define the shape to be extruded.
+ * @property {Property | CornerType} [cornerType=CornerType.ROUNDED] A {@link CornerType} Property specifying the style of the corners.
+ * @property {Property | number} [granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude point.
+ * @property {Property | boolean} [fill=true] A boolean Property specifying whether the volume is filled with the provided material.
+ * @property {MaterialProperty | Color} [material=Color.WHITE] A Property specifying the material used to fill the volume.
+ * @property {Property | boolean} [outline=false] A boolean Property specifying whether the volume is outlined.
+ * @property {Property | Color} [outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline.
+ * @property {Property | number} [outlineWidth=1.0] A numeric Property specifying the width of the outline.
+ * @property {Property | ShadowMode} [shadows=ShadowMode.DISABLED] An enum Property specifying whether the volume casts or receives shadows from light sources.
+ * @property {Property | DistanceDisplayCondition} [distanceDisplayCondition] A Property specifying at what distance from the camera that this volume will be displayed.
+ */
+
/**
* Describes a polyline volume defined as a line strip and corresponding two dimensional shape which is extruded along it.
* The resulting volume conforms to the curvature of the globe.
@@ -12,19 +31,7 @@ import createPropertyDescriptor from "./createPropertyDescriptor.js";
* @alias PolylineVolumeGraphics
* @constructor
*
- * @param {Object} [options] Object with the following properties:
- * @param {Property} [options.show=true] A boolean Property specifying the visibility of the volume.
- * @param {Property} [options.positions] A Property specifying the array of {@link Cartesian3} positions which define the line strip.
- * @param {Property} [options.shape] A Property specifying the array of {@link Cartesian2} positions which define the shape to be extruded.
- * @param {Property} [options.cornerType=CornerType.ROUNDED] A {@link CornerType} Property specifying the style of the corners.
- * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude point.
- * @param {Property} [options.fill=true] A boolean Property specifying whether the volume is filled with the provided material.
- * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the volume.
- * @param {Property} [options.outline=false] A boolean Property specifying whether the volume is outlined.
- * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline.
- * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline.
- * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the volume casts or receives shadows from light sources.
- * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this volume will be displayed.
+ * @param {PolylineVolumeGraphics.ConstructorOptions} [options] Object describing initialization options
*
* @see Entity
* @demo {@link https://sandcastle.cesium.com/index.html?src=Polyline%20Volume.html|Cesium Sandcastle Polyline Volume Demo}
@@ -76,7 +83,7 @@ Object.defineProperties(PolylineVolumeGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying the visibility of the volume.
* @memberof PolylineVolumeGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default true
*/
show: createPropertyDescriptor("show"),
@@ -84,21 +91,21 @@ Object.defineProperties(PolylineVolumeGraphics.prototype, {
/**
* Gets or sets the Property specifying the array of {@link Cartesian3} positions which define the line strip.
* @memberof PolylineVolumeGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
positions: createPropertyDescriptor("positions"),
/**
* Gets or sets the Property specifying the array of {@link Cartesian2} positions which define the shape to be extruded.
* @memberof PolylineVolumeGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
shape: createPropertyDescriptor("shape"),
/**
* Gets or sets the {@link CornerType} Property specifying the style of the corners.
* @memberof PolylineVolumeGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default CornerType.ROUNDED
*/
cornerType: createPropertyDescriptor("cornerType"),
@@ -106,7 +113,7 @@ Object.defineProperties(PolylineVolumeGraphics.prototype, {
/**
* Gets or sets the numeric Property specifying the angular distance between points on the volume.
* @memberof PolylineVolumeGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default {CesiumMath.RADIANS_PER_DEGREE}
*/
granularity: createPropertyDescriptor("granularity"),
@@ -114,7 +121,7 @@ Object.defineProperties(PolylineVolumeGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying whether the volume is filled with the provided material.
* @memberof PolylineVolumeGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default true
*/
fill: createPropertyDescriptor("fill"),
@@ -130,7 +137,7 @@ Object.defineProperties(PolylineVolumeGraphics.prototype, {
/**
* Gets or sets the Property specifying whether the volume is outlined.
* @memberof PolylineVolumeGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default false
*/
outline: createPropertyDescriptor("outline"),
@@ -138,7 +145,7 @@ Object.defineProperties(PolylineVolumeGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link Color} of the outline.
* @memberof PolylineVolumeGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Color.BLACK
*/
outlineColor: createPropertyDescriptor("outlineColor"),
@@ -146,7 +153,7 @@ Object.defineProperties(PolylineVolumeGraphics.prototype, {
/**
* Gets or sets the numeric Property specifying the width of the outline.
* @memberof PolylineVolumeGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 1.0
*/
outlineWidth: createPropertyDescriptor("outlineWidth"),
@@ -155,7 +162,7 @@ Object.defineProperties(PolylineVolumeGraphics.prototype, {
* Get or sets the enum Property specifying whether the volume
* casts or receives shadows from light sources.
* @memberof PolylineVolumeGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default ShadowMode.DISABLED
*/
shadows: createPropertyDescriptor("shadows"),
@@ -163,7 +170,7 @@ Object.defineProperties(PolylineVolumeGraphics.prototype, {
/**
* Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this volume will be displayed.
* @memberof PolylineVolumeGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
distanceDisplayCondition: createPropertyDescriptor(
"distanceDisplayCondition"
diff --git a/Source/DataSources/PositionPropertyArray.js b/Source/DataSources/PositionPropertyArray.js
index b4c04259f138..1067d4914735 100644
--- a/Source/DataSources/PositionPropertyArray.js
+++ b/Source/DataSources/PositionPropertyArray.js
@@ -7,7 +7,7 @@ import ReferenceFrame from "../Core/ReferenceFrame.js";
import Property from "./Property.js";
/**
- * A {@link PositionProperty} whose value is an array whose items are the computed value
+ * A {@link Property} whose value is an array whose items are the computed value
* of other PositionProperty instances.
*
* @alias PositionPropertyArray
diff --git a/Source/DataSources/PropertyBag.js b/Source/DataSources/PropertyBag.js
index 4d356a462df2..688053f4c7ae 100644
--- a/Source/DataSources/PropertyBag.js
+++ b/Source/DataSources/PropertyBag.js
@@ -11,6 +11,7 @@ import Property from "./Property.js";
*
* @alias PropertyBag
* @constructor
+ * @implements {DictionaryLike}
*
* @param {Object} [value] An object, containing key-value mapping of property names to properties.
* @param {Function} [createPropertyCallback] A function that will be called when the value of any of the properties in value are not a Property.
diff --git a/Source/DataSources/RectangleGraphics.js b/Source/DataSources/RectangleGraphics.js
index fa553282f7d2..d5423e713b87 100644
--- a/Source/DataSources/RectangleGraphics.js
+++ b/Source/DataSources/RectangleGraphics.js
@@ -5,6 +5,31 @@ import Event from "../Core/Event.js";
import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor.js";
import createPropertyDescriptor from "./createPropertyDescriptor.js";
+/**
+ * @typedef {Object} RectangleGraphics.ConstructorOptions
+ *
+ * Initialization options for the RectangleGraphics constructor
+ *
+ * @property {Property | boolean} [show=true] A boolean Property specifying the visibility of the rectangle.
+ * @property {Property | Rectangle} [coordinates] The Property specifying the {@link Rectangle}.
+ * @property {Property | number} [height=0] A numeric Property specifying the altitude of the rectangle relative to the ellipsoid surface.
+ * @property {Property | HeightReference} [heightReference=HeightReference.NONE] A Property specifying what the height is relative to.
+ * @property {Property | number} [extrudedHeight] A numeric Property specifying the altitude of the rectangle's extruded face relative to the ellipsoid surface.
+ * @property {Property | HeightReference} [extrudedHeightReference=HeightReference.NONE] A Property specifying what the extrudedHeight is relative to.
+ * @property {Property | number} [rotation=0.0] A numeric property specifying the rotation of the rectangle clockwise from north.
+ * @property {Property | number} [stRotation=0.0] A numeric property specifying the rotation of the rectangle texture counter-clockwise from north.
+ * @property {Property | number} [granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between points on the rectangle.
+ * @property {Property | boolean} [fill=true] A boolean Property specifying whether the rectangle is filled with the provided material.
+ * @property {MaterialProperty | Color} [material=Color.WHITE] A Property specifying the material used to fill the rectangle.
+ * @property {Property | boolean} [outline=false] A boolean Property specifying whether the rectangle is outlined.
+ * @property {Property | Color} [outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline.
+ * @property {Property | number} [outlineWidth=1.0] A numeric Property specifying the width of the outline.
+ * @property {Property | ShadowMode} [shadows=ShadowMode.DISABLED] An enum Property specifying whether the rectangle casts or receives shadows from light sources.
+ * @property {Property | DistanceDisplayCondition} [distanceDisplayCondition] A Property specifying at what distance from the camera that this rectangle will be displayed.
+ * @property {Property | ClassificationType} [classificationType=ClassificationType.BOTH] An enum Property specifying whether this rectangle will classify terrain, 3D Tiles, or both when on the ground.
+ * @property {Property | number} [zIndex=0] A Property specifying the zIndex used for ordering ground geometry. Only has an effect if the rectangle is constant and neither height or extrudedHeight are specified.
+ */
+
/**
* Describes graphics for a {@link Rectangle}.
* The rectangle conforms to the curvature of the globe and can be placed on the surface or
@@ -13,25 +38,7 @@ import createPropertyDescriptor from "./createPropertyDescriptor.js";
* @alias RectangleGraphics
* @constructor
*
- * @param {Object} [options] Object with the following properties:
- * @param {Property} [options.show=true] A boolean Property specifying the visibility of the rectangle.
- * @param {Property} [options.coordinates] The Property specifying the {@link Rectangle}.
- * @param {Property} [options.height=0] A numeric Property specifying the altitude of the rectangle relative to the ellipsoid surface.
- * @param {Property} [options.heightReference=HeightReference.NONE] A Property specifying what the height is relative to.
- * @param {Property} [options.extrudedHeight] A numeric Property specifying the altitude of the rectangle's extruded face relative to the ellipsoid surface.
- * @param {Property} [options.extrudedHeightReference=HeightReference.NONE] A Property specifying what the extrudedHeight is relative to.
- * @param {Property} [options.rotation=0.0] A numeric property specifying the rotation of the rectangle clockwise from north.
- * @param {Property} [options.stRotation=0.0] A numeric property specifying the rotation of the rectangle texture counter-clockwise from north.
- * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between points on the rectangle.
- * @param {Property} [options.fill=true] A boolean Property specifying whether the rectangle is filled with the provided material.
- * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the rectangle.
- * @param {Property} [options.outline=false] A boolean Property specifying whether the rectangle is outlined.
- * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline.
- * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline.
- * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the rectangle casts or receives shadows from light sources.
- * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this rectangle will be displayed.
- * @param {Property} [options.classificationType=ClassificationType.BOTH] An enum Property specifying whether this rectangle will classify terrain, 3D Tiles, or both when on the ground.
- * @param {Property} [options.zIndex=0] A Property specifying the zIndex used for ordering ground geometry. Only has an effect if the rectangle is constant and neither height or extrudedHeight are specified.
+ * @param {RectangleGraphics.ConstructorOptions} [options] Object describing initialization options
*
* @see Entity
* @demo {@link https://sandcastle.cesium.com/index.html?src=Rectangle.html|Cesium Sandcastle Rectangle Demo}
@@ -95,7 +102,7 @@ Object.defineProperties(RectangleGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying the visibility of the rectangle.
* @memberof RectangleGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default true
*/
show: createPropertyDescriptor("show"),
@@ -103,14 +110,14 @@ Object.defineProperties(RectangleGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link Rectangle}.
* @memberof RectangleGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
coordinates: createPropertyDescriptor("coordinates"),
/**
* Gets or sets the numeric Property specifying the altitude of the rectangle.
* @memberof RectangleGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 0.0
*/
height: createPropertyDescriptor("height"),
@@ -118,7 +125,7 @@ Object.defineProperties(RectangleGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link HeightReference}.
* @memberof RectangleGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default HeightReference.NONE
*/
heightReference: createPropertyDescriptor("heightReference"),
@@ -127,14 +134,14 @@ Object.defineProperties(RectangleGraphics.prototype, {
* Gets or sets the numeric Property specifying the altitude of the rectangle extrusion.
* Setting this property creates volume starting at height and ending at this altitude.
* @memberof RectangleGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
extrudedHeight: createPropertyDescriptor("extrudedHeight"),
/**
* Gets or sets the Property specifying the extruded {@link HeightReference}.
* @memberof RectangleGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default HeightReference.NONE
*/
extrudedHeightReference: createPropertyDescriptor("extrudedHeightReference"),
@@ -142,7 +149,7 @@ Object.defineProperties(RectangleGraphics.prototype, {
/**
* Gets or sets the numeric property specifying the rotation of the rectangle clockwise from north.
* @memberof RectangleGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 0
*/
rotation: createPropertyDescriptor("rotation"),
@@ -150,7 +157,7 @@ Object.defineProperties(RectangleGraphics.prototype, {
/**
* Gets or sets the numeric property specifying the rotation of the rectangle texture counter-clockwise from north.
* @memberof RectangleGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 0
*/
stRotation: createPropertyDescriptor("stRotation"),
@@ -158,7 +165,7 @@ Object.defineProperties(RectangleGraphics.prototype, {
/**
* Gets or sets the numeric Property specifying the angular distance between points on the rectangle.
* @memberof RectangleGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default {CesiumMath.RADIANS_PER_DEGREE}
*/
granularity: createPropertyDescriptor("granularity"),
@@ -166,7 +173,7 @@ Object.defineProperties(RectangleGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying whether the rectangle is filled with the provided material.
* @memberof RectangleGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default true
*/
fill: createPropertyDescriptor("fill"),
@@ -182,7 +189,7 @@ Object.defineProperties(RectangleGraphics.prototype, {
/**
* Gets or sets the Property specifying whether the rectangle is outlined.
* @memberof RectangleGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default false
*/
outline: createPropertyDescriptor("outline"),
@@ -190,7 +197,7 @@ Object.defineProperties(RectangleGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link Color} of the outline.
* @memberof RectangleGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Color.BLACK
*/
outlineColor: createPropertyDescriptor("outlineColor"),
@@ -198,7 +205,7 @@ Object.defineProperties(RectangleGraphics.prototype, {
/**
* Gets or sets the numeric Property specifying the width of the outline.
* @memberof RectangleGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 1.0
*/
outlineWidth: createPropertyDescriptor("outlineWidth"),
@@ -207,7 +214,7 @@ Object.defineProperties(RectangleGraphics.prototype, {
* Get or sets the enum Property specifying whether the rectangle
* casts or receives shadows from light sources.
* @memberof RectangleGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default ShadowMode.DISABLED
*/
shadows: createPropertyDescriptor("shadows"),
@@ -215,7 +222,7 @@ Object.defineProperties(RectangleGraphics.prototype, {
/**
* Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this rectangle will be displayed.
* @memberof RectangleGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
distanceDisplayCondition: createPropertyDescriptor(
"distanceDisplayCondition"
@@ -224,7 +231,7 @@ Object.defineProperties(RectangleGraphics.prototype, {
/**
* Gets or sets the {@link ClassificationType} Property specifying whether this rectangle will classify terrain, 3D Tiles, or both when on the ground.
* @memberof RectangleGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default ClassificationType.BOTH
*/
classificationType: createPropertyDescriptor("classificationType"),
@@ -232,7 +239,7 @@ Object.defineProperties(RectangleGraphics.prototype, {
/**
* Gets or sets the zIndex Property specifying the ordering of the rectangle. Only has an effect if the rectangle is constant and neither height or extrudedHeight are specified.
* @memberof RectangleGraphics.prototype
- * @type {ConstantProperty}
+ * @type {ConstantProperty|undefined}
* @default 0
*/
zIndex: createPropertyDescriptor("zIndex"),
diff --git a/Source/DataSources/ReferenceProperty.js b/Source/DataSources/ReferenceProperty.js
index 6800b16eb181..d658f1521e59 100644
--- a/Source/DataSources/ReferenceProperty.js
+++ b/Source/DataSources/ReferenceProperty.js
@@ -191,7 +191,7 @@ Object.defineProperties(ReferenceProperty.prototype, {
/**
* Gets the resolved instance of the underlying referenced property.
* @memberof ReferenceProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @readonly
*/
resolvedProperty: {
diff --git a/Source/DataSources/Rotation.js b/Source/DataSources/Rotation.js
index 42aa8dbc8883..8273f8d1a3aa 100755
--- a/Source/DataSources/Rotation.js
+++ b/Source/DataSources/Rotation.js
@@ -9,7 +9,7 @@ import CesiumMath from "../Core/Math.js";
* but is instead passed to the constructor of {@link SampledProperty}
* in order to represent a two-dimensional angle of rotation.
*
- * @exports Rotation
+ * @interface Rotation
*
*
* @example
@@ -87,7 +87,7 @@ var Rotation = {
* @param {Number[]} packedArray The packed array.
* @param {Number} [startingIndex=0] The index of the first element to be converted.
* @param {Number} [lastIndex=packedArray.length] The index of the last element to be converted.
- * @param {Number[]} result The object into which to store the result.
+ * @param {Number[]} [result] The object into which to store the result.
*/
convertPackedArrayForInterpolation: function (
packedArray,
@@ -101,6 +101,10 @@ var Rotation = {
}
//>>includeEnd('debug');
+ if (!defined(result)) {
+ result = [];
+ }
+
startingIndex = defaultValue(startingIndex, 0);
lastIndex = defaultValue(lastIndex, packedArray.length);
diff --git a/Source/DataSources/SampledPositionProperty.js b/Source/DataSources/SampledPositionProperty.js
index e644b82d497d..9a239a6f94ab 100644
--- a/Source/DataSources/SampledPositionProperty.js
+++ b/Source/DataSources/SampledPositionProperty.js
@@ -108,8 +108,8 @@ Object.defineProperties(SampledPositionProperty.prototype, {
* The number of derivatives contained by this property; i.e. 0 for just position, 1 for velocity, etc.
* @memberof SampledPositionProperty.prototype
*
- * @type {Boolean}
- * @default false
+ * @type {Number}
+ * @default 0
*/
numberOfDerivatives: {
get: function () {
diff --git a/Source/DataSources/StripeMaterialProperty.js b/Source/DataSources/StripeMaterialProperty.js
index 9da8226bb106..0bec4de51be6 100644
--- a/Source/DataSources/StripeMaterialProperty.js
+++ b/Source/DataSources/StripeMaterialProperty.js
@@ -18,11 +18,11 @@ var defaultRepeat = 1;
* @constructor
*
* @param {Object} [options] Object with the following properties:
- * @param {Property} [options.orientation=StripeOrientation.HORIZONTAL] A Property specifying the {@link StripeOrientation}.
- * @param {Property} [options.evenColor=Color.WHITE] A Property specifying the first {@link Color}.
- * @param {Property} [options.oddColor=Color.BLACK] A Property specifying the second {@link Color}.
- * @param {Property} [options.offset=0] A numeric Property specifying how far into the pattern to start the material.
- * @param {Property} [options.repeat=1] A numeric Property specifying how many times the stripes repeat.
+ * @param {Property|StripeOrientation} [options.orientation=StripeOrientation.HORIZONTAL] A Property specifying the {@link StripeOrientation}.
+ * @param {Property|Color} [options.evenColor=Color.WHITE] A Property specifying the first {@link Color}.
+ * @param {Property|Color} [options.oddColor=Color.BLACK] A Property specifying the second {@link Color}.
+ * @param {Property|Number} [options.offset=0] A numeric Property specifying how far into the pattern to start the material.
+ * @param {Property|Number} [options.repeat=1] A numeric Property specifying how many times the stripes repeat.
*/
function StripeMaterialProperty(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
@@ -84,7 +84,7 @@ Object.defineProperties(StripeMaterialProperty.prototype, {
/**
* Gets or sets the Property specifying the {@link StripeOrientation}/
* @memberof StripeMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default StripeOrientation.HORIZONTAL
*/
orientation: createPropertyDescriptor("orientation"),
@@ -92,7 +92,7 @@ Object.defineProperties(StripeMaterialProperty.prototype, {
/**
* Gets or sets the Property specifying the first {@link Color}.
* @memberof StripeMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Color.WHITE
*/
evenColor: createPropertyDescriptor("evenColor"),
@@ -100,7 +100,7 @@ Object.defineProperties(StripeMaterialProperty.prototype, {
/**
* Gets or sets the Property specifying the second {@link Color}.
* @memberof StripeMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Color.BLACK
*/
oddColor: createPropertyDescriptor("oddColor"),
@@ -111,7 +111,7 @@ Object.defineProperties(StripeMaterialProperty.prototype, {
* of the odd color, 2.0 being the even color again, and any multiple or fractional values
* being in between.
* @memberof StripeMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 0.0
*/
offset: createPropertyDescriptor("offset"),
@@ -119,7 +119,7 @@ Object.defineProperties(StripeMaterialProperty.prototype, {
/**
* Gets or sets the numeric Property specifying how many times the stripes repeat.
* @memberof StripeMaterialProperty.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 1.0
*/
repeat: createPropertyDescriptor("repeat"),
diff --git a/Source/DataSources/StripeOrientation.js b/Source/DataSources/StripeOrientation.js
index aed7c398e134..c2da3b8f8810 100644
--- a/Source/DataSources/StripeOrientation.js
+++ b/Source/DataSources/StripeOrientation.js
@@ -1,7 +1,7 @@
/**
* Defined the orientation of stripes in {@link StripeMaterialProperty}.
*
- * @exports StripeOrientation
+ * @enum {Number}
*/
var StripeOrientation = {
/**
diff --git a/Source/DataSources/TerrainOffsetProperty.js b/Source/DataSources/TerrainOffsetProperty.js
index dc6d4d89f48d..ed9c22e13723 100644
--- a/Source/DataSources/TerrainOffsetProperty.js
+++ b/Source/DataSources/TerrainOffsetProperty.js
@@ -238,7 +238,7 @@ TerrainOffsetProperty.prototype.destroy = function () {
/**
* A function which creates one or more providers.
- * @callback TerrainOffsetProperty~PositionFunction
+ * @callback TerrainOffsetProperty.PositionFunction
* @param {JulianDate} time The clock time at which to retrieve the position
* @param {Cartesian3} result The result position
* @returns {Cartesian3} The position at which to do the terrain height check
diff --git a/Source/DataSources/VelocityOrientationProperty.js b/Source/DataSources/VelocityOrientationProperty.js
index 450b7864d7b4..78c49d7c647c 100644
--- a/Source/DataSources/VelocityOrientationProperty.js
+++ b/Source/DataSources/VelocityOrientationProperty.js
@@ -16,7 +16,7 @@ import VelocityVectorProperty from "./VelocityVectorProperty.js";
* @alias VelocityOrientationProperty
* @constructor
*
- * @param {Property} [position] The position property used to compute the orientation.
+ * @param {PositionProperty} [position] The position property used to compute the orientation.
* @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid used to determine which way is up.
*
* @example
@@ -71,7 +71,7 @@ Object.defineProperties(VelocityOrientationProperty.prototype, {
* Gets or sets the position property used to compute orientation.
* @memberof VelocityOrientationProperty.prototype
*
- * @type {Property}
+ * @type {Property|undefined}
*/
position: {
get: function () {
@@ -85,7 +85,7 @@ Object.defineProperties(VelocityOrientationProperty.prototype, {
* Gets or sets the ellipsoid used to determine which way is up.
* @memberof VelocityOrientationProperty.prototype
*
- * @type {Property}
+ * @type {Property|undefined}
*/
ellipsoid: {
get: function () {
diff --git a/Source/DataSources/VelocityVectorProperty.js b/Source/DataSources/VelocityVectorProperty.js
index f6c719369133..b5506059e849 100644
--- a/Source/DataSources/VelocityVectorProperty.js
+++ b/Source/DataSources/VelocityVectorProperty.js
@@ -13,7 +13,7 @@ import Property from "./Property.js";
* @alias VelocityVectorProperty
* @constructor
*
- * @param {Property} [position] The position property used to compute the velocity.
+ * @param {PositionProperty} [position] The position property used to compute the velocity.
* @param {Boolean} [normalize=true] Whether to normalize the computed velocity vector.
*
* @example
@@ -66,7 +66,7 @@ Object.defineProperties(VelocityVectorProperty.prototype, {
* Gets or sets the position property used to compute the velocity vector.
* @memberof VelocityVectorProperty.prototype
*
- * @type {Property}
+ * @type {Property|undefined}
*/
position: {
get: function () {
diff --git a/Source/DataSources/WallGraphics.js b/Source/DataSources/WallGraphics.js
index d0ce102b0a16..8ad9f13bcf8b 100644
--- a/Source/DataSources/WallGraphics.js
+++ b/Source/DataSources/WallGraphics.js
@@ -5,6 +5,25 @@ import Event from "../Core/Event.js";
import createMaterialPropertyDescriptor from "./createMaterialPropertyDescriptor.js";
import createPropertyDescriptor from "./createPropertyDescriptor.js";
+/**
+ * @typedef {Object} WallGraphics.ConstructorOptions
+ *
+ * Initialization options for the WallGraphics constructor
+ *
+ * @property {Property | boolean} [show=true] A boolean Property specifying the visibility of the wall.
+ * @property {Property | Array} [positions] A Property specifying the array of {@link Cartesian3} positions which define the top of the wall.
+ * @property {Property | Array} [minimumHeights] A Property specifying an array of heights to be used for the bottom of the wall instead of the globe surface.
+ * @property {Property | Array} [maximumHeights] A Property specifying an array of heights to be used for the top of the wall instead of the height of each position.
+ * @property {Property | number} [granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude point.
+ * @property {Property | boolean} [fill=true] A boolean Property specifying whether the wall is filled with the provided material.
+ * @property {MaterialProperty | Color} [material=Color.WHITE] A Property specifying the material used to fill the wall.
+ * @property {Property | boolean} [outline=false] A boolean Property specifying whether the wall is outlined.
+ * @property {Property | Color} [outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline.
+ * @property {Property | number} [outlineWidth=1.0] A numeric Property specifying the width of the outline.
+ * @property {Property | ShadowMode} [shadows=ShadowMode.DISABLED] An enum Property specifying whether the wall casts or receives shadows from light sources.
+ * @property {Property | DistanceDisplayCondition} [distanceDisplayCondition] A Property specifying at what distance from the camera that this wall will be displayed.
+ */
+
/**
* Describes a two dimensional wall defined as a line strip and optional maximum and minimum heights.
* The wall conforms to the curvature of the globe and can be placed along the surface or at altitude.
@@ -12,19 +31,7 @@ import createPropertyDescriptor from "./createPropertyDescriptor.js";
* @alias WallGraphics
* @constructor
*
- * @param {Object} [options] Object with the following properties:
- * @param {Property} [options.show=true] A boolean Property specifying the visibility of the wall.
- * @param {Property} [options.positions] A Property specifying the array of {@link Cartesian3} positions which define the top of the wall.
- * @param {Property} [options.minimumHeights] A Property specifying an array of heights to be used for the bottom of the wall instead of the globe surface.
- * @param {Property} [options.maximumHeights] A Property specifying an array of heights to be used for the top of the wall instead of the height of each position.
- * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude point.
- * @param {Property} [options.fill=true] A boolean Property specifying whether the wall is filled with the provided material.
- * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the wall.
- * @param {Property} [options.outline=false] A boolean Property specifying whether the wall is outlined.
- * @param {Property} [options.outlineColor=Color.BLACK] A Property specifying the {@link Color} of the outline.
- * @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline.
- * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the wall casts or receives shadows from light sources.
- * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this wall will be displayed.
+ * @param {WallGraphics.ConstructorOptions} [options] Object describing initialization options
*
* @see Entity
* @demo {@link https://sandcastle.cesium.com/index.html?src=Wall.html|Cesium Sandcastle Wall Demo}
@@ -76,7 +83,7 @@ Object.defineProperties(WallGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying the visibility of the wall.
* @memberof WallGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default true
*/
show: createPropertyDescriptor("show"),
@@ -84,7 +91,7 @@ Object.defineProperties(WallGraphics.prototype, {
/**
* Gets or sets the Property specifying the array of {@link Cartesian3} positions which define the top of the wall.
* @memberof WallGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
positions: createPropertyDescriptor("positions"),
@@ -92,7 +99,7 @@ Object.defineProperties(WallGraphics.prototype, {
* Gets or sets the Property specifying an array of heights to be used for the bottom of the wall instead of the surface of the globe.
* If defined, the array must be the same length as {@link Wall#positions}.
* @memberof WallGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
minimumHeights: createPropertyDescriptor("minimumHeights"),
@@ -100,14 +107,14 @@ Object.defineProperties(WallGraphics.prototype, {
* Gets or sets the Property specifying an array of heights to be used for the top of the wall instead of the height of each position.
* If defined, the array must be the same length as {@link Wall#positions}.
* @memberof WallGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
maximumHeights: createPropertyDescriptor("maximumHeights"),
/**
* Gets or sets the numeric Property specifying the angular distance between points on the wall.
* @memberof WallGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default {CesiumMath.RADIANS_PER_DEGREE}
*/
granularity: createPropertyDescriptor("granularity"),
@@ -115,7 +122,7 @@ Object.defineProperties(WallGraphics.prototype, {
/**
* Gets or sets the boolean Property specifying whether the wall is filled with the provided material.
* @memberof WallGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default true
*/
fill: createPropertyDescriptor("fill"),
@@ -131,7 +138,7 @@ Object.defineProperties(WallGraphics.prototype, {
/**
* Gets or sets the Property specifying whether the wall is outlined.
* @memberof WallGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default false
*/
outline: createPropertyDescriptor("outline"),
@@ -139,7 +146,7 @@ Object.defineProperties(WallGraphics.prototype, {
/**
* Gets or sets the Property specifying the {@link Color} of the outline.
* @memberof WallGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default Color.BLACK
*/
outlineColor: createPropertyDescriptor("outlineColor"),
@@ -147,7 +154,7 @@ Object.defineProperties(WallGraphics.prototype, {
/**
* Gets or sets the numeric Property specifying the width of the outline.
* @memberof WallGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default 1.0
*/
outlineWidth: createPropertyDescriptor("outlineWidth"),
@@ -156,7 +163,7 @@ Object.defineProperties(WallGraphics.prototype, {
* Get or sets the enum Property specifying whether the wall
* casts or receives shadows from light sources.
* @memberof WallGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
* @default ShadowMode.DISABLED
*/
shadows: createPropertyDescriptor("shadows"),
@@ -164,7 +171,7 @@ Object.defineProperties(WallGraphics.prototype, {
/**
* Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this wall will be displayed.
* @memberof WallGraphics.prototype
- * @type {Property}
+ * @type {Property|undefined}
*/
distanceDisplayCondition: createPropertyDescriptor(
"distanceDisplayCondition"
diff --git a/Source/DataSources/exportKml.js b/Source/DataSources/exportKml.js
index d251de4143b3..46c1fa16de9e 100644
--- a/Source/DataSources/exportKml.js
+++ b/Source/DataSources/exportKml.js
@@ -222,6 +222,19 @@ IdManager.prototype.get = function (id) {
return id.toString() + "-" + ++ids[id];
};
+/**
+ * @typedef exportKmlResultKml
+ * @type {Object}
+ * @property {String} kml The generated KML.
+ * @property {Object.} externalFiles An object dictionary of external files
+ */
+
+/**
+ * @typedef exportKmlResultKmz
+ * @type {Object}
+ * @property {Blob} kmz The generated kmz file.
+ */
+
/**
* Exports an EntityCollection as a KML document. Only Point, Billboard, Model, Path, Polygon, Polyline geometries
* will be exported. Note that there is not a 1 to 1 mapping of Entity properties to KML Feature properties. For
@@ -232,18 +245,18 @@ IdManager.prototype.get = function (id) {
* as gx:Track Features. Not all Materials are representable in KML, so for more advanced Materials just the primary
* color is used. Canvas objects are exported as PNG images.
*
- * @exports exportKml
+ * @function exportKml
*
* @param {Object} options An object with the following properties:
* @param {EntityCollection} options.entities The EntityCollection to export as KML.
* @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for the output file.
- * @param {exportKml~ModelCallback} [options.modelCallback] A callback that will be called with a {@link ModelGraphics} instance and should return the URI to use in the KML. Required if a model exists in the entity collection.
+ * @param {exportKmlModelCallback} [options.modelCallback] A callback that will be called with a {@link ModelGraphics} instance and should return the URI to use in the KML. Required if a model exists in the entity collection.
* @param {JulianDate} [options.time=entities.computeAvailability().start] The time value to use to get properties that are not time varying in KML.
* @param {TimeInterval} [options.defaultAvailability=entities.computeAvailability()] The interval that will be sampled if an entity doesn't have an availability.
* @param {Number} [options.sampleDuration=60] The number of seconds to sample properties that are varying in KML.
* @param {Boolean} [options.kmz=false] If true KML and external files will be compressed into a kmz file.
*
- * @returns {Promise} A promise that resolved to an object containing the KML string and a dictionary of external file blobs, or a kmz file as a blob if options.kmz is true.
+ * @returns {Promise} A promise that resolved to an object containing the KML string and a dictionary of external file blobs, or a kmz file as a blob if options.kmz is true.
* @demo {@link https://sandcastle.cesium.com/index.html?src=Export%20KML.html|Cesium Sandcastle KML Export Demo}
* @example
* Cesium.exportKml({
@@ -1503,7 +1516,7 @@ function colorToString(color) {
* It can also be used to add additional files to the externalFiles
object, which is the list of files embedded in the exported KMZ,
* or otherwise returned with the KML string when exporting.
*
- * @callback exportKml~ModelCallback
+ * @callback exportKmlModelCallback
*
* @param {ModelGraphics} model The ModelGraphics instance for an Entity.
* @param {JulianDate} time The time that any properties should use to get the value.
diff --git a/Source/Renderer/AutomaticUniforms.js b/Source/Renderer/AutomaticUniforms.js
index b4de4b7c7d94..e72cd6eddb2e 100644
--- a/Source/Renderer/AutomaticUniforms.js
+++ b/Source/Renderer/AutomaticUniforms.js
@@ -51,10 +51,6 @@ var AutomaticUniforms = {
* and height
properties in an vec4
's x
, y
, z
,
* and w
components, respectively.
*
- * @alias czm_viewport
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec4 czm_viewport;
@@ -85,10 +81,6 @@ var AutomaticUniforms = {
* The former transforms from normalized device coordinates to window coordinates; the later transforms
* from window coordinates to clip coordinates, and is often used to assign to gl_Position
.
*
- * @alias czm_viewportOrthographic
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_viewportOrthographic;
@@ -124,10 +116,6 @@ var AutomaticUniforms = {
* The former transforms from normalized device coordinates to window coordinates; the later transforms
* from window coordinates to clip coordinates, and is often used to assign to gl_Position
.
*
- * @alias czm_viewportTransformation
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_viewportTransformation;
@@ -157,12 +145,6 @@ var AutomaticUniforms = {
* after the globe pass and then updated after the 3D Tiles pass.
* The depth is packed into an RGBA texture.
*
- * @private
- *
- * @alias czm_globeDepthTexture
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform sampler2D czm_globeDepthTexture;
@@ -183,10 +165,6 @@ var AutomaticUniforms = {
* An automatic GLSL uniform representing a 4x4 model transformation matrix that
* transforms model coordinates to world coordinates.
*
- * @alias czm_model
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_model;
@@ -211,10 +189,6 @@ var AutomaticUniforms = {
* An automatic GLSL uniform representing a 4x4 model transformation matrix that
* transforms world coordinates to model coordinates.
*
- * @alias czm_inverseModel
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_inverseModel;
@@ -238,10 +212,6 @@ var AutomaticUniforms = {
* An automatic GLSL uniform representing a 4x4 view transformation matrix that
* transforms world coordinates to eye coordinates.
*
- * @alias czm_view
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_view;
@@ -271,10 +241,6 @@ var AutomaticUniforms = {
* as if the camera were at an equivalent location in 3D mode. This is useful for lighting
* 2D and Columbus View in the same way that 3D is lit.
*
- * @alias czm_view3D
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_view3D;
@@ -297,10 +263,6 @@ var AutomaticUniforms = {
* An automatic GLSL uniform representing a 3x3 view rotation matrix that
* transforms vectors in world coordinates to eye coordinates.
*
- * @alias czm_viewRotation
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat3 czm_viewRotation;
@@ -328,10 +290,6 @@ var AutomaticUniforms = {
* as if the camera were at an equivalent location in 3D mode. This is useful for lighting
* 2D and Columbus View in the same way that 3D is lit.
*
- * @alias czm_viewRotation3D
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat3 czm_viewRotation3D;
@@ -354,10 +312,6 @@ var AutomaticUniforms = {
* An automatic GLSL uniform representing a 4x4 transformation matrix that
* transforms from eye coordinates to world coordinates.
*
- * @alias czm_inverseView
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_inverseView;
@@ -384,10 +338,6 @@ var AutomaticUniforms = {
* as if the camera were at an equivalent location in 3D mode. This is useful for lighting
* 2D and Columbus View in the same way that 3D is lit.
*
- * @alias czm_inverseView3D
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_inverseView3D;
@@ -410,10 +360,6 @@ var AutomaticUniforms = {
* An automatic GLSL uniform representing a 3x3 rotation matrix that
* transforms vectors from eye coordinates to world coordinates.
*
- * @alias czm_inverseViewRotation
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat3 czm_inverseViewRotation;
@@ -441,10 +387,6 @@ var AutomaticUniforms = {
* as if the camera were at an equivalent location in 3D mode. This is useful for lighting
* 2D and Columbus View in the same way that 3D is lit.
*
- * @alias czm_inverseViewRotation3D
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat3 czm_inverseViewRotation3D;
@@ -468,10 +410,6 @@ var AutomaticUniforms = {
* transforms eye coordinates to clip coordinates. Clip coordinates is the
* coordinate system for a vertex shader's gl_Position
output.
*
- * @alias czm_projection
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_projection;
@@ -497,10 +435,6 @@ var AutomaticUniforms = {
* transforms from clip coordinates to eye coordinates. Clip coordinates is the
* coordinate system for a vertex shader's gl_Position
output.
*
- * @alias czm_inverseProjection
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_inverseProjection;
@@ -526,10 +460,6 @@ var AutomaticUniforms = {
* in algorithms like shadow volumes and GPU ray casting with proxy geometry to ensure that triangles
* are not clipped by the far plane.
*
- * @alias czm_infiniteProjection
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_infiniteProjection;
@@ -556,10 +486,6 @@ var AutomaticUniforms = {
* Positions should be transformed to eye coordinates using czm_modelView
and
* normals should be transformed using {@link czm_normal}.
*
- * @alias czm_modelView
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_modelView;
@@ -594,10 +520,6 @@ var AutomaticUniforms = {
* Positions should be transformed to eye coordinates using czm_modelView3D
and
* normals should be transformed using {@link czm_normal3D}.
*
- * @alias czm_modelView3D
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_modelView3D;
@@ -624,10 +546,6 @@ var AutomaticUniforms = {
* transforms model coordinates, relative to the eye, to eye coordinates. This is used
* in conjunction with {@link czm_translateRelativeToEye}.
*
- * @alias czm_modelViewRelativeToEye
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_modelViewRelativeToEye;
@@ -658,10 +576,6 @@ var AutomaticUniforms = {
* An automatic GLSL uniform representing a 4x4 transformation matrix that
* transforms from eye coordinates to model coordinates.
*
- * @alias czm_inverseModelView
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_inverseModelView;
@@ -687,10 +601,6 @@ var AutomaticUniforms = {
* as if the camera were at an equivalent location in 3D mode. This is useful for lighting
* 2D and Columbus View in the same way that 3D is lit.
*
- * @alias czm_inverseModelView3D
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_inverseModelView3D;
@@ -715,10 +625,6 @@ var AutomaticUniforms = {
* transforms world coordinates to clip coordinates. Clip coordinates is the
* coordinate system for a vertex shader's gl_Position
output.
*
- * @alias czm_viewProjection
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_viewProjection;
@@ -748,10 +654,6 @@ var AutomaticUniforms = {
* transforms clip coordinates to world coordinates. Clip coordinates is the
* coordinate system for a vertex shader's gl_Position
output.
*
- * @alias czm_inverseViewProjection
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_inverseViewProjection;
@@ -775,10 +677,6 @@ var AutomaticUniforms = {
* transforms model coordinates to clip coordinates. Clip coordinates is the
* coordinate system for a vertex shader's gl_Position
output.
*
- * @alias czm_modelViewProjection
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_modelViewProjection;
@@ -811,10 +709,6 @@ var AutomaticUniforms = {
* transforms clip coordinates to model coordinates. Clip coordinates is the
* coordinate system for a vertex shader's gl_Position
output.
*
- * @alias czm_inverseModelViewProjection
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_inverseModelViewProjection;
@@ -839,10 +733,6 @@ var AutomaticUniforms = {
* coordinate system for a vertex shader's gl_Position
output. This is used in
* conjunction with {@link czm_translateRelativeToEye}.
*
- * @alias czm_modelViewProjectionRelativeToEye
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_modelViewProjectionRelativeToEye;
@@ -876,10 +766,6 @@ var AutomaticUniforms = {
* the far plane at infinity. This is useful in algorithms like shadow volumes and GPU ray casting with
* proxy geometry to ensure that triangles are not clipped by the far plane.
*
- * @alias czm_modelViewInfiniteProjection
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat4 czm_modelViewInfiniteProjection;
@@ -907,9 +793,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform that indicates if the current camera is orthographic in 3D.
*
- * @alias czm_orthographicIn3D
- * @namespace
- * @glslUniform
* @see UniformState#orthographicIn3D
*/
czm_orthographicIn3D: new AutomaticUniform({
@@ -927,10 +810,6 @@ var AutomaticUniforms = {
* Positions should be transformed to eye coordinates using {@link czm_modelView} and
* normals should be transformed using czm_normal
.
*
- * @alias czm_normal
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat3 czm_normal;
@@ -961,10 +840,6 @@ var AutomaticUniforms = {
* Positions should be transformed to eye coordinates using {@link czm_modelView3D} and
* normals should be transformed using czm_normal3D
.
*
- * @alias czm_normal3D
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat3 czm_normal3D;
@@ -988,10 +863,6 @@ var AutomaticUniforms = {
* transforms normal vectors in eye coordinates to model coordinates. This is
* the opposite of the transform provided by {@link czm_normal}.
*
- * @alias czm_inverseNormal
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat3 czm_inverseNormal;
@@ -1021,10 +892,6 @@ var AutomaticUniforms = {
* matrix as if the camera were at an equivalent location in 3D mode. This is useful for lighting
* 2D and Columbus View in the same way that 3D is lit.
*
- * @alias czm_inverseNormal3D
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat3 czm_inverseNormal3D;
@@ -1044,12 +911,23 @@ var AutomaticUniforms = {
}),
/**
- * An automatic GLSL uniform containing height (x
) and height squared (y
)
- * of the eye (camera) in the 2D scene in meters.
+ * An automatic GLSL uniform containing the height in meters of the
+ * eye (camera) above or below the ellipsoid.
*
- * @alias czm_eyeHeight2D
- * @namespace
- * @glslUniform
+ * @see UniformState#eyeHeight
+ */
+ czm_eyeHeight: new AutomaticUniform({
+ size: 1,
+ datatype: WebGLConstants.FLOAT,
+ getValue: function (uniformState) {
+ return uniformState.eyeHeight;
+ },
+ }),
+
+ /**
+ * An automatic GLSL uniform containing height (x
) and height squared (y
)
+ * in meters of the eye (camera) above the 2D world plane. This uniform is only valid
+ * when the {@link SceneMode} is SCENE2D
.
*
* @see UniformState#eyeHeight2D
*/
@@ -1066,10 +944,6 @@ var AutomaticUniforms = {
* of the frustum defined by the camera. This is the largest possible frustum, not an individual
* frustum used for multi-frustum rendering.
*
- * @alias czm_entireFrustum
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec2 czm_entireFrustum;
@@ -1093,10 +967,6 @@ var AutomaticUniforms = {
* of the frustum defined by the camera. This is the individual
* frustum used for multi-frustum rendering.
*
- * @alias czm_currentFrustum
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec2 czm_currentFrustum;
@@ -1118,10 +988,6 @@ var AutomaticUniforms = {
/**
* The distances to the frustum planes. The top, bottom, left and right distances are
* the x, y, z, and w components, respectively.
- *
- * @alias czm_frustumPlanes
- * @namespace
- * @glslUniform
*/
czm_frustumPlanes: new AutomaticUniform({
size: 1,
@@ -1133,10 +999,6 @@ var AutomaticUniforms = {
/**
* Gets the far plane's distance from the near plane, plus 1.0.
- *
- * @alias czm_farDepthFromNearPlusOne
- * @namespace
- * @glslUniform
*/
czm_farDepthFromNearPlusOne: new AutomaticUniform({
size: 1,
@@ -1148,10 +1010,6 @@ var AutomaticUniforms = {
/**
* Gets the log2 of {@link AutomaticUniforms#czm_farDepthFromNearPlusOne}.
- *
- * @alias czm_oneOverLog2FarDepthFromNearPlusOne
- * @namespace
- * @glslUniform
*/
czm_log2FarDepthFromNearPlusOne: new AutomaticUniform({
size: 1,
@@ -1163,10 +1021,6 @@ var AutomaticUniforms = {
/**
* Gets 1.0 divided by {@link AutomaticUniforms#czm_log2FarDepthFromNearPlusOne}.
- *
- * @alias czm_oneOverLog2FarDepthFromNearPlusOne
- * @namespace
- * @glslUniform
*/
czm_oneOverLog2FarDepthFromNearPlusOne: new AutomaticUniform({
size: 1,
@@ -1179,10 +1033,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform representing the sun position in world coordinates.
*
- * @alias czm_sunPositionWC
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec3 czm_sunPositionWC;
@@ -1202,10 +1052,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform representing the sun position in Columbus view world coordinates.
*
- * @alias czm_sunPositionColumbusView
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec3 czm_sunPositionColumbusView;
@@ -1224,10 +1070,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform representing the normalized direction to the sun in eye coordinates.
*
- * @alias czm_sunDirectionEC
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec3 czm_sunDirectionEC;
@@ -1250,10 +1092,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform representing the normalized direction to the sun in world coordinates.
*
- * @alias czm_sunDirectionWC
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec3 czm_sunDirectionWC;
@@ -1276,10 +1114,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform representing the normalized direction to the moon in eye coordinates.
*
- * @alias czm_moonDirectionEC
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec3 czm_moonDirectionEC;
@@ -1302,10 +1136,6 @@ var AutomaticUniforms = {
* An automatic GLSL uniform representing the normalized direction to the scene's light source in eye coordinates.
* This is commonly used for directional lighting computations.
*
- * @alias czm_lightDirectionEC
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec3 czm_lightDirectionEC;
@@ -1328,10 +1158,6 @@ var AutomaticUniforms = {
* An automatic GLSL uniform representing the normalized direction to the scene's light source in world coordinates.
* This is commonly used for directional lighting computations.
*
- * @alias czm_lightDirectionWC
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec3 czm_lightDirectionWC;
@@ -1355,10 +1181,6 @@ var AutomaticUniforms = {
* is equivalent to the light color multiplied by the light intensity limited to a maximum luminance of 1.0
* suitable for non-HDR lighting.
*
- * @alias czm_lightColor
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec3 czm_lightColor;
@@ -1381,10 +1203,6 @@ var AutomaticUniforms = {
* An automatic GLSL uniform that represents the high dynamic range color of light emitted by the scene's light
* source. This is equivalent to the light color multiplied by the light intensity suitable for HDR lighting.
*
- * @alias czm_lightColorHdr
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec3 czm_lightColorHdr;
@@ -1408,10 +1226,6 @@ var AutomaticUniforms = {
* coordinates. This is used for GPU RTE to eliminate jittering artifacts when rendering
* as described in {@link http://help.agi.com/AGIComponents/html/BlogPrecisionsPrecisions.htm|Precisions, Precisions}.
*
- * @alias czm_encodedCameraPositionMCHigh
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec3 czm_encodedCameraPositionMCHigh;
@@ -1433,10 +1247,6 @@ var AutomaticUniforms = {
* coordinates. This is used for GPU RTE to eliminate jittering artifacts when rendering
* as described in {@linkhttp://help.agi.com/AGIComponents/html/BlogPrecisionsPrecisions.htm|Precisions, Precisions}.
*
- * @alias czm_encodedCameraPositionMCLow
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec3 czm_encodedCameraPositionMCLow;
@@ -1456,10 +1266,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform representing the position of the viewer (camera) in world coordinates.
*
- * @alias czm_viewerPositionWC
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec3 czm_viewerPositionWC;
@@ -1479,10 +1285,6 @@ var AutomaticUniforms = {
* An automatic GLSL uniform representing the frame number. This uniform is automatically incremented
* every frame.
*
- * @alias czm_frameNumber
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform float czm_frameNumber;
@@ -1499,10 +1301,6 @@ var AutomaticUniforms = {
* An automatic GLSL uniform representing the current morph transition time between
* 2D/Columbus View and 3D, with 0.0 being 2D or Columbus View and 1.0 being 3D.
*
- * @alias czm_morphTime
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform float czm_morphTime;
@@ -1522,10 +1320,6 @@ var AutomaticUniforms = {
* An automatic GLSL uniform representing the current {@link SceneMode}, expressed
* as a float.
*
- * @alias czm_sceneMode
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform float czm_sceneMode;
@@ -1552,10 +1346,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform representing the current rendering pass.
*
- * @alias czm_pass
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform float czm_pass;
@@ -1577,10 +1367,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform representing the current scene background color.
*
- * @alias czm_backgroundColor
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec4 czm_backgroundColor;
@@ -1607,10 +1393,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform containing the BRDF look up texture used for image-based lighting computations.
*
- * @alias czm_brdfLut
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform sampler2D czm_brdfLut;
@@ -1631,10 +1413,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform containing the environment map used within the scene.
*
- * @alias czm_environmentMap
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform samplerCube czm_environmentMap;
@@ -1654,10 +1432,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform containing the specular environment map atlas used within the scene.
*
- * @alias czm_specularEnvironmentMaps
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform sampler2D czm_specularEnvironmentMaps;
@@ -1673,10 +1447,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform containing the size of the specular environment map atlas used within the scene.
*
- * @alias czm_specularEnvironmentMapSize
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec2 czm_specularEnvironmentMapSize;
@@ -1692,10 +1462,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform containing the maximum level-of-detail of the specular environment map atlas used within the scene.
*
- * @alias czm_specularEnvironmentMapsMaximumLOD
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform float czm_specularEnvironmentMapsMaximumLOD;
@@ -1711,10 +1477,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform containing the spherical harmonic coefficients used within the scene.
*
- * @alias czm_sphericalHarmonicCoefficients
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform vec3[9] czm_sphericalHarmonicCoefficients;
@@ -1731,10 +1493,6 @@ var AutomaticUniforms = {
* An automatic GLSL uniform representing a 3x3 rotation matrix that transforms
* from True Equator Mean Equinox (TEME) axes to the pseudo-fixed axes at the current scene time.
*
- * @alias czm_temeToPseudoFixed
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform mat3 czm_temeToPseudoFixed;
@@ -1756,10 +1514,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform representing the ratio of canvas coordinate space to canvas pixel space.
*
- * @alias czm_pixelRatio
- * @namespace
- * @glslUniform
- *
* @example
* uniform float czm_pixelRatio;
*/
@@ -1774,10 +1528,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform scalar used to mix a color with the fog color based on the distance to the camera.
*
- * @alias czm_fogDensity
- * @namespace
- * @glslUniform
- *
* @see czm_fog
*/
czm_fogDensity: new AutomaticUniform({
@@ -1792,10 +1542,6 @@ var AutomaticUniforms = {
* An automatic GLSL uniform representing the splitter position to use when rendering imagery layers with a splitter.
* This will be in pixel coordinates relative to the canvas.
*
- * @alias czm_imagerySplitPosition
- * @namespace
- * @glslUniform
- *
* @example
* // GLSL declaration
* uniform float czm_imagerySplitPosition;
@@ -1810,10 +1556,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform scalar representing the geometric tolerance per meter
- *
- * @alias czm_geometricToleranceOverMeter
- * @namespace
- * @glslUniform
*/
czm_geometricToleranceOverMeter: new AutomaticUniform({
size: 1,
@@ -1827,10 +1569,6 @@ var AutomaticUniforms = {
* An automatic GLSL uniform representing the distance from the camera at which to disable the depth test of billboards, labels and points
* to, for example, prevent clipping against terrain. When set to zero, the depth test should always be applied. When less than zero,
* the depth test should never be applied.
- *
- * @alias czm_minimumDisableDepthTestDistance
- * @namespace
- * @glslUniform
*/
czm_minimumDisableDepthTestDistance: new AutomaticUniform({
size: 1,
@@ -1842,10 +1580,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform that will be the highlight color of unclassified 3D Tiles.
- *
- * @alias czm_invertClassificationColor
- * @namespace
- * @glslUniform
*/
czm_invertClassificationColor: new AutomaticUniform({
size: 1,
@@ -1857,9 +1591,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform that is used for gamma correction.
- *
- * @alias czm_gamma
- * @glslUniform
*/
czm_gamma: new AutomaticUniform({
size: 1,
@@ -1871,9 +1602,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform that stores the ellipsoid radii.
- *
- * @alias czm_ellipsoidRadii
- * @glslUniform
*/
czm_ellipsoidRadii: new AutomaticUniform({
size: 1,
@@ -1885,9 +1613,6 @@ var AutomaticUniforms = {
/**
* An automatic GLSL uniform that stores the ellipsoid inverse radii.
- *
- * @alias czm_ellipsoidRadii
- * @glslUniform
*/
czm_ellipsoidInverseRadii: new AutomaticUniform({
size: 1,
diff --git a/Source/Renderer/PixelDatatype.js b/Source/Renderer/PixelDatatype.js
index e7f17f8404cd..e9238e94f5a8 100644
--- a/Source/Renderer/PixelDatatype.js
+++ b/Source/Renderer/PixelDatatype.js
@@ -1,7 +1,10 @@
import WebGLConstants from "../Core/WebGLConstants.js";
/**
- * @private
+ * The data type of a pixel.
+ *
+ * @enum {Number}
+ * @see PostProcessStage
*/
var PixelDatatype = {
UNSIGNED_BYTE: WebGLConstants.UNSIGNED_BYTE,
@@ -13,45 +16,55 @@ var PixelDatatype = {
UNSIGNED_SHORT_4_4_4_4: WebGLConstants.UNSIGNED_SHORT_4_4_4_4,
UNSIGNED_SHORT_5_5_5_1: WebGLConstants.UNSIGNED_SHORT_5_5_5_1,
UNSIGNED_SHORT_5_6_5: WebGLConstants.UNSIGNED_SHORT_5_6_5,
+};
- isPacked: function (pixelDatatype) {
- return (
- pixelDatatype === PixelDatatype.UNSIGNED_INT_24_8 ||
- pixelDatatype === PixelDatatype.UNSIGNED_SHORT_4_4_4_4 ||
- pixelDatatype === PixelDatatype.UNSIGNED_SHORT_5_5_5_1 ||
- pixelDatatype === PixelDatatype.UNSIGNED_SHORT_5_6_5
- );
- },
+/**
+ @private
+*/
+PixelDatatype.isPacked = function (pixelDatatype) {
+ return (
+ pixelDatatype === PixelDatatype.UNSIGNED_INT_24_8 ||
+ pixelDatatype === PixelDatatype.UNSIGNED_SHORT_4_4_4_4 ||
+ pixelDatatype === PixelDatatype.UNSIGNED_SHORT_5_5_5_1 ||
+ pixelDatatype === PixelDatatype.UNSIGNED_SHORT_5_6_5
+ );
+};
- sizeInBytes: function (pixelDatatype) {
- switch (pixelDatatype) {
- case PixelDatatype.UNSIGNED_BYTE:
- return 1;
- case PixelDatatype.UNSIGNED_SHORT:
- case PixelDatatype.UNSIGNED_SHORT_4_4_4_4:
- case PixelDatatype.UNSIGNED_SHORT_5_5_5_1:
- case PixelDatatype.UNSIGNED_SHORT_5_6_5:
- case PixelDatatype.HALF_FLOAT:
- return 2;
- case PixelDatatype.UNSIGNED_INT:
- case PixelDatatype.FLOAT:
- case PixelDatatype.UNSIGNED_INT_24_8:
- return 4;
- }
- },
+/**
+ @private
+*/
+PixelDatatype.sizeInBytes = function (pixelDatatype) {
+ switch (pixelDatatype) {
+ case PixelDatatype.UNSIGNED_BYTE:
+ return 1;
+ case PixelDatatype.UNSIGNED_SHORT:
+ case PixelDatatype.UNSIGNED_SHORT_4_4_4_4:
+ case PixelDatatype.UNSIGNED_SHORT_5_5_5_1:
+ case PixelDatatype.UNSIGNED_SHORT_5_6_5:
+ case PixelDatatype.HALF_FLOAT:
+ return 2;
+ case PixelDatatype.UNSIGNED_INT:
+ case PixelDatatype.FLOAT:
+ case PixelDatatype.UNSIGNED_INT_24_8:
+ return 4;
+ }
+};
- validate: function (pixelDatatype) {
- return (
- pixelDatatype === PixelDatatype.UNSIGNED_BYTE ||
- pixelDatatype === PixelDatatype.UNSIGNED_SHORT ||
- pixelDatatype === PixelDatatype.UNSIGNED_INT ||
- pixelDatatype === PixelDatatype.FLOAT ||
- pixelDatatype === PixelDatatype.HALF_FLOAT ||
- pixelDatatype === PixelDatatype.UNSIGNED_INT_24_8 ||
- pixelDatatype === PixelDatatype.UNSIGNED_SHORT_4_4_4_4 ||
- pixelDatatype === PixelDatatype.UNSIGNED_SHORT_5_5_5_1 ||
- pixelDatatype === PixelDatatype.UNSIGNED_SHORT_5_6_5
- );
- },
+/**
+ @private
+*/
+PixelDatatype.validate = function (pixelDatatype) {
+ return (
+ pixelDatatype === PixelDatatype.UNSIGNED_BYTE ||
+ pixelDatatype === PixelDatatype.UNSIGNED_SHORT ||
+ pixelDatatype === PixelDatatype.UNSIGNED_INT ||
+ pixelDatatype === PixelDatatype.FLOAT ||
+ pixelDatatype === PixelDatatype.HALF_FLOAT ||
+ pixelDatatype === PixelDatatype.UNSIGNED_INT_24_8 ||
+ pixelDatatype === PixelDatatype.UNSIGNED_SHORT_4_4_4_4 ||
+ pixelDatatype === PixelDatatype.UNSIGNED_SHORT_5_5_5_1 ||
+ pixelDatatype === PixelDatatype.UNSIGNED_SHORT_5_6_5
+ );
};
+
export default Object.freeze(PixelDatatype);
diff --git a/Source/Renderer/Texture.js b/Source/Renderer/Texture.js
index d4d117da35e1..3ccdad327c82 100644
--- a/Source/Renderer/Texture.js
+++ b/Source/Renderer/Texture.js
@@ -633,10 +633,10 @@ Object.defineProperties(Texture.prototype, {
});
/**
- * Copy new image data into this texture, from a source {@link ImageData}, {@link Image}, {@link Canvas}, or {@link Video}.
+ * Copy new image data into this texture, from a source {@link ImageData}, {@link HTMLImageElement}, {@link HTMLCanvasElement}, or {@link HTMLVideoElement}.
* or an object with width, height, and arrayBufferView properties.
*
- * @param {Object} source The source {@link ImageData}, {@link Image}, {@link Canvas}, or {@link Video},
+ * @param {Object} source The source {@link ImageData}, {@link HTMLImageElement}, {@link HTMLCanvasElement}, or {@link HTMLVideoElement},
* or an object with width, height, and arrayBufferView properties.
* @param {Number} [xOffset=0] The offset in the x direction within the texture to copy into.
* @param {Number} [yOffset=0] The offset in the y direction within the texture to copy into.
diff --git a/Source/Renderer/TextureMagnificationFilter.js b/Source/Renderer/TextureMagnificationFilter.js
index 5103252b72ba..cc1b5a05a821 100644
--- a/Source/Renderer/TextureMagnificationFilter.js
+++ b/Source/Renderer/TextureMagnificationFilter.js
@@ -3,7 +3,7 @@ import WebGLConstants from "../Core/WebGLConstants.js";
/**
* Enumerates all possible filters used when magnifying WebGL textures.
*
- * @exports TextureMagnificationFilter
+ * @enum {Number}
*
* @see TextureMinificationFilter
*/
@@ -22,20 +22,20 @@ var TextureMagnificationFilter = {
* @constant
*/
LINEAR: WebGLConstants.LINEAR,
+};
- /**
- * Validates the given textureMinificationFilter
with respect to the possible enum values.
- *
- * @private
- *
- * @param textureMagnificationFilter
- * @returns {Boolean} true
if textureMagnificationFilter
is valid.
- */
- validate: function (textureMagnificationFilter) {
- return (
- textureMagnificationFilter === TextureMagnificationFilter.NEAREST ||
- textureMagnificationFilter === TextureMagnificationFilter.LINEAR
- );
- },
+/**
+ * Validates the given textureMinificationFilter
with respect to the possible enum values.
+ * @param textureMagnificationFilter
+ * @returns {Boolean} true
if textureMagnificationFilter
is valid.
+ *
+ * @private
+ */
+TextureMagnificationFilter.validate = function (textureMagnificationFilter) {
+ return (
+ textureMagnificationFilter === TextureMagnificationFilter.NEAREST ||
+ textureMagnificationFilter === TextureMagnificationFilter.LINEAR
+ );
};
+
export default Object.freeze(TextureMagnificationFilter);
diff --git a/Source/Renderer/TextureMinificationFilter.js b/Source/Renderer/TextureMinificationFilter.js
index 2eb8929bd8f0..a7cc13fb2bde 100644
--- a/Source/Renderer/TextureMinificationFilter.js
+++ b/Source/Renderer/TextureMinificationFilter.js
@@ -3,7 +3,7 @@ import WebGLConstants from "../Core/WebGLConstants.js";
/**
* Enumerates all possible filters used when minifying WebGL textures.
*
- * @exports TextureMinificationFilter
+ * @enum {Number}
*
* @see TextureMagnificationFilter
*/
@@ -67,28 +67,28 @@ var TextureMinificationFilter = {
* @constant
*/
LINEAR_MIPMAP_LINEAR: WebGLConstants.LINEAR_MIPMAP_LINEAR,
+};
- /**
- * Validates the given textureMinificationFilter
with respect to the possible enum values.
- *
- * @private
- *
- * @param textureMinificationFilter
- * @returns {Boolean} true
if textureMinificationFilter
is valid.
- */
- validate: function (textureMinificationFilter) {
- return (
- textureMinificationFilter === TextureMinificationFilter.NEAREST ||
- textureMinificationFilter === TextureMinificationFilter.LINEAR ||
- textureMinificationFilter ===
- TextureMinificationFilter.NEAREST_MIPMAP_NEAREST ||
- textureMinificationFilter ===
- TextureMinificationFilter.LINEAR_MIPMAP_NEAREST ||
- textureMinificationFilter ===
- TextureMinificationFilter.NEAREST_MIPMAP_LINEAR ||
- textureMinificationFilter ===
- TextureMinificationFilter.LINEAR_MIPMAP_LINEAR
- );
- },
+/**
+ * Validates the given textureMinificationFilter
with respect to the possible enum values.
+ *
+ * @private
+ *
+ * @param textureMinificationFilter
+ * @returns {Boolean} true
if textureMinificationFilter
is valid.
+ */
+TextureMinificationFilter.validate = function (textureMinificationFilter) {
+ return (
+ textureMinificationFilter === TextureMinificationFilter.NEAREST ||
+ textureMinificationFilter === TextureMinificationFilter.LINEAR ||
+ textureMinificationFilter ===
+ TextureMinificationFilter.NEAREST_MIPMAP_NEAREST ||
+ textureMinificationFilter ===
+ TextureMinificationFilter.LINEAR_MIPMAP_NEAREST ||
+ textureMinificationFilter ===
+ TextureMinificationFilter.NEAREST_MIPMAP_LINEAR ||
+ textureMinificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_LINEAR
+ );
};
+
export default Object.freeze(TextureMinificationFilter);
diff --git a/Source/Renderer/UniformState.js b/Source/Renderer/UniformState.js
index d456419789c0..7fc58612aec0 100644
--- a/Source/Renderer/UniformState.js
+++ b/Source/Renderer/UniformState.js
@@ -142,6 +142,7 @@ function UniformState() {
this._cameraRight = new Cartesian3();
this._cameraUp = new Cartesian3();
this._frustum2DWidth = 0.0;
+ this._eyeHeight = 0.0;
this._eyeHeight2D = new Cartesian2();
this._pixelRatio = 1.0;
this._orthographicIn3D = false;
@@ -672,9 +673,20 @@ Object.defineProperties(UniformState.prototype, {
},
/**
- * The the height (x
) and the height squared (y
)
- * in meters of the camera above the 2D world plane. This uniform is only valid
- * when the {@link SceneMode} equal to SCENE2D
.
+ * The height in meters of the eye (camera) above or below the ellipsoid.
+ * @memberof UniformState.prototype
+ * @type {Number}
+ */
+ eyeHeight: {
+ get: function () {
+ return this._eyeHeight;
+ },
+ },
+
+ /**
+ * The height (x
) and the height squared (y
)
+ * in meters of the eye (camera) above the 2D world plane. This uniform is only valid
+ * when the {@link SceneMode} is SCENE2D
.
* @memberof UniformState.prototype
* @type {Cartesian2}
*/
@@ -855,7 +867,7 @@ Object.defineProperties(UniformState.prototype, {
/**
* A scalar that represents the geometric tolerance per meter
- * @memberof UniformStat.prototype
+ * @memberof UniformState.prototype
* @type {Number}
*/
geometricToleranceOverMeter: {
@@ -1060,6 +1072,14 @@ function setCamera(uniformState, camera) {
Cartesian3.clone(camera.directionWC, uniformState._cameraDirection);
Cartesian3.clone(camera.rightWC, uniformState._cameraRight);
Cartesian3.clone(camera.upWC, uniformState._cameraUp);
+
+ var positionCartographic = camera.positionCartographic;
+ if (!defined(positionCartographic)) {
+ uniformState._eyeHeight = -uniformState._ellipsoid.maximumRadius;
+ } else {
+ uniformState._eyeHeight = positionCartographic.height;
+ }
+
uniformState._encodedCameraPositionMCDirty = true;
}
@@ -1286,10 +1306,14 @@ UniformState.prototype.update = function (frameState) {
var fov = camera.frustum.fov;
var viewport = this._viewport;
var pixelSizePerMeter;
- if (viewport.height > viewport.width) {
- pixelSizePerMeter = (Math.tan(0.5 * fov) * 2.0) / viewport.height;
+ if (defined(fov)) {
+ if (viewport.height > viewport.width) {
+ pixelSizePerMeter = (Math.tan(0.5 * fov) * 2.0) / viewport.height;
+ } else {
+ pixelSizePerMeter = (Math.tan(0.5 * fov) * 2.0) / viewport.width;
+ }
} else {
- pixelSizePerMeter = (Math.tan(0.5 * fov) * 2.0) / viewport.width;
+ pixelSizePerMeter = 1.0 / Math.max(viewport.width, viewport.height);
}
this._geometricToleranceOverMeter =
diff --git a/Source/Renderer/loadCubeMap.js b/Source/Renderer/loadCubeMap.js
index 70a30f5807bf..449f169a9853 100644
--- a/Source/Renderer/loadCubeMap.js
+++ b/Source/Renderer/loadCubeMap.js
@@ -9,7 +9,7 @@ import CubeMap from "./CubeMap.js";
* Asynchronously loads six images and creates a cube map. Returns a promise that
* will resolve to a {@link CubeMap} once loaded, or reject if any image fails to load.
*
- * @exports loadCubeMap
+ * @function loadCubeMap
*
* @param {Context} context The context to use to create the cube map.
* @param {Object} urls The source URL of each image. See the example below.
diff --git a/Source/Scene/Appearance.js b/Source/Scene/Appearance.js
index 26e507a2308b..88547f5a0b15 100644
--- a/Source/Scene/Appearance.js
+++ b/Source/Scene/Appearance.js
@@ -19,7 +19,7 @@ import CullFace from "./CullFace.js";
* @param {Material} [options.material=Material.ColorType] The material used to determine the fragment color.
* @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader.
* @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader.
- * @param {RenderState} [options.renderState] Optional render state to override the default render state.
+ * @param {Object} [options.renderState] Optional render state to override the default render state.
*
* @see MaterialAppearance
* @see EllipsoidSurfaceAppearance
diff --git a/Source/Scene/ArcGisMapServerImageryProvider.js b/Source/Scene/ArcGisMapServerImageryProvider.js
index 73e8f4d2523f..240154ae2e4b 100644
--- a/Source/Scene/ArcGisMapServerImageryProvider.js
+++ b/Source/Scene/ArcGisMapServerImageryProvider.js
@@ -21,16 +21,13 @@ import ImageryLayerFeatureInfo from "./ImageryLayerFeatureInfo.js";
import ImageryProvider from "./ImageryProvider.js";
/**
- * Provides tiled imagery hosted by an ArcGIS MapServer. By default, the server's pre-cached tiles are
- * used, if available.
+ * @typedef {Object} ArcGisMapServerImageryProvider.ConstructorOptions
*
- * @alias ArcGisMapServerImageryProvider
- * @constructor
+ * Initialization options for the ArcGisMapServerImageryProvider constructor
*
- * @param {Object} options Object with the following properties:
- * @param {Resource|String} options.url The URL of the ArcGIS MapServer service.
- * @param {String} [options.token] The ArcGIS token used to authenticate with the ArcGIS MapServer service.
- * @param {TileDiscardPolicy} [options.tileDiscardPolicy] The policy that determines if a tile
+ * @property {Resource|String} url The URL of the ArcGIS MapServer service.
+ * @property {String} [token] The ArcGIS token used to authenticate with the ArcGIS MapServer service.
+ * @property {TileDiscardPolicy} [tileDiscardPolicy] The policy that determines if a tile
* is invalid and should be discarded. If this value is not specified, a default
* {@link DiscardMissingTileImagePolicy} is used for tiled map servers, and a
* {@link NeverTileDiscardPolicy} is used for non-tiled map servers. In the former case,
@@ -41,27 +38,37 @@ import ImageryProvider from "./ImageryProvider.js";
* these defaults should be correct tile discarding for a standard ArcGIS Server. To ensure
* that no tiles are discarded, construct and pass a {@link NeverTileDiscardPolicy} for this
* parameter.
- * @param {Boolean} [options.usePreCachedTilesIfAvailable=true] If true, the server's pre-cached
+ * @property {Boolean} [usePreCachedTilesIfAvailable=true] If true, the server's pre-cached
* tiles are used if they are available. If false, any pre-cached tiles are ignored and the
* 'export' service is used.
- * @param {String} [options.layers] A comma-separated list of the layers to show, or undefined if all layers should be shown.
- * @param {Boolean} [options.enablePickFeatures=true] If true, {@link ArcGisMapServerImageryProvider#pickFeatures} will invoke
+ * @property {String} [layers] A comma-separated list of the layers to show, or undefined if all layers should be shown.
+ * @property {Boolean} [enablePickFeatures=true] If true, {@link ArcGisMapServerImageryProvider#pickFeatures} will invoke
* the Identify service on the MapServer and return the features included in the response. If false,
* {@link ArcGisMapServerImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features)
* without communicating with the server. Set this property to false if you don't want this provider's features to
* be pickable. Can be overridden by setting the {@link ArcGisMapServerImageryProvider#enablePickFeatures} property on the object.
- * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle of the layer. This parameter is ignored when accessing
+ * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle of the layer. This parameter is ignored when accessing
* a tiled layer.
- * @param {TilingScheme} [options.tilingScheme=new GeographicTilingScheme()] The tiling scheme to use to divide the world into tiles.
+ * @property {TilingScheme} [tilingScheme=new GeographicTilingScheme()] The tiling scheme to use to divide the world into tiles.
* This parameter is ignored when accessing a tiled server.
- * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified and used,
+ * @property {Ellipsoid} [ellipsoid] The ellipsoid. If the tilingScheme is specified and used,
* this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither
* parameter is specified, the WGS84 ellipsoid is used.
- * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. This parameter is ignored when accessing a tiled server.
- * @param {Number} [options.tileWidth=256] The width of each tile in pixels. This parameter is ignored when accessing a tiled server.
- * @param {Number} [options.tileHeight=256] The height of each tile in pixels. This parameter is ignored when accessing a tiled server.
- * @param {Number} [options.maximumLevel] The maximum tile level to request, or undefined if there is no maximum. This parameter is ignored when accessing
+ * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas. This parameter is ignored when accessing a tiled server.
+ * @property {Number} [tileWidth=256] The width of each tile in pixels. This parameter is ignored when accessing a tiled server.
+ * @property {Number} [tileHeight=256] The height of each tile in pixels. This parameter is ignored when accessing a tiled server.
+ * @property {Number} [maximumLevel] The maximum tile level to request, or undefined if there is no maximum. This parameter is ignored when accessing
* a tiled server.
+ */
+
+/**
+ * Provides tiled imagery hosted by an ArcGIS MapServer. By default, the server's pre-cached tiles are
+ * used, if available.
+ *
+ * @alias ArcGisMapServerImageryProvider
+ * @constructor
+ *
+ * @param {ArcGisMapServerImageryProvider.ConstructorOptions} options Object describing initialization options
*
* @see BingMapsImageryProvider
* @see GoogleEarthEnterpriseMapsProvider
@@ -90,6 +97,92 @@ function ArcGisMapServerImageryProvider(options) {
}
//>>includeEnd('debug');
+ /**
+ * The default alpha blending value of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultNightAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultDayAlpha = undefined;
+
+ /**
+ * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
+ * makes the imagery darker while greater than 1.0 makes it brighter.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultBrightness = undefined;
+
+ /**
+ * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
+ * the contrast while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultContrast = undefined;
+
+ /**
+ * The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultHue = undefined;
+
+ /**
+ * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
+ * saturation while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultSaturation = undefined;
+
+ /**
+ * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultGamma = undefined;
+
+ /**
+ * The default texture minification filter to apply to this provider.
+ *
+ * @type {TextureMinificationFilter}
+ * @default undefined
+ */
+ this.defaultMinificationFilter = undefined;
+
+ /**
+ * The default texture magnification filter to apply to this provider.
+ *
+ * @type {TextureMagnificationFilter}
+ * @default undefined
+ */
+ this.defaultMagnificationFilter = undefined;
+
var resource = Resource.createIfNeeded(options.url);
resource.appendForwardSlash();
@@ -449,7 +542,7 @@ Object.defineProperties(ArcGisMapServerImageryProvider.prototype, {
* Gets the maximum level-of-detail that can be requested. This function should
* not be called before {@link ArcGisMapServerImageryProvider#ready} returns true.
* @memberof ArcGisMapServerImageryProvider.prototype
- * @type {Number}
+ * @type {Number|undefined}
* @readonly
*/
maximumLevel: {
@@ -677,7 +770,7 @@ ArcGisMapServerImageryProvider.prototype.getTileCredits = function (
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level.
* @param {Request} [request] The request object. Intended for internal use only.
- * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
+ * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if there are too many active requests to the server, and the request
* should be retried later. The resolved image may be either an
* Image or a Canvas DOM object.
diff --git a/Source/Scene/AttributeType.js b/Source/Scene/AttributeType.js
index 23c0772204d2..36c7cae8848f 100644
--- a/Source/Scene/AttributeType.js
+++ b/Source/Scene/AttributeType.js
@@ -1,7 +1,7 @@
/**
* An enum describing the attribute type for glTF and 3D Tiles.
*
- * @exports AttributeType
+ * @enum {String}
*
* @private
*/
diff --git a/Source/Scene/Axis.js b/Source/Scene/Axis.js
index 160e3fbe0ee2..1baeb4b8fcba 100644
--- a/Source/Scene/Axis.js
+++ b/Source/Scene/Axis.js
@@ -6,8 +6,7 @@ import Matrix4 from "../Core/Matrix4.js";
/**
* An enum describing the x, y, and z axes and helper conversion functions.
*
- * @exports Axis
- * @private
+ * @enum {Number}
*/
var Axis = {
/**
@@ -33,79 +32,80 @@ var Axis = {
* @constant
*/
Z: 2,
+};
- /**
- * Matrix used to convert from y-up to z-up
- *
- * @type {Matrix4}
- * @constant
- */
- Y_UP_TO_Z_UP: Matrix4.fromRotationTranslation(
- Matrix3.fromRotationX(CesiumMath.PI_OVER_TWO)
- ),
+/**
+ * Matrix used to convert from y-up to z-up
+ *
+ * @type {Matrix4}
+ * @constant
+ */
+Axis.Y_UP_TO_Z_UP = Matrix4.fromRotationTranslation(
+ Matrix3.fromRotationX(CesiumMath.PI_OVER_TWO)
+);
- /**
- * Matrix used to convert from z-up to y-up
- *
- * @type {Matrix4}
- * @constant
- */
- Z_UP_TO_Y_UP: Matrix4.fromRotationTranslation(
- Matrix3.fromRotationX(-CesiumMath.PI_OVER_TWO)
- ),
+/**
+ * Matrix used to convert from z-up to y-up
+ *
+ * @type {Matrix4}
+ * @constant
+ */
+Axis.Z_UP_TO_Y_UP = Matrix4.fromRotationTranslation(
+ Matrix3.fromRotationX(-CesiumMath.PI_OVER_TWO)
+);
- /**
- * Matrix used to convert from x-up to z-up
- *
- * @type {Matrix4}
- * @constant
- */
- X_UP_TO_Z_UP: Matrix4.fromRotationTranslation(
- Matrix3.fromRotationY(-CesiumMath.PI_OVER_TWO)
- ),
+/**
+ * Matrix used to convert from x-up to z-up
+ *
+ * @type {Matrix4}
+ * @constant
+ */
+Axis.X_UP_TO_Z_UP = Matrix4.fromRotationTranslation(
+ Matrix3.fromRotationY(-CesiumMath.PI_OVER_TWO)
+);
- /**
- * Matrix used to convert from z-up to x-up
- *
- * @type {Matrix4}
- * @constant
- */
- Z_UP_TO_X_UP: Matrix4.fromRotationTranslation(
- Matrix3.fromRotationY(CesiumMath.PI_OVER_TWO)
- ),
+/**
+ * Matrix used to convert from z-up to x-up
+ *
+ * @type {Matrix4}
+ * @constant
+ */
+Axis.Z_UP_TO_X_UP = Matrix4.fromRotationTranslation(
+ Matrix3.fromRotationY(CesiumMath.PI_OVER_TWO)
+);
- /**
- * Matrix used to convert from x-up to y-up
- *
- * @type {Matrix4}
- * @constant
- */
- X_UP_TO_Y_UP: Matrix4.fromRotationTranslation(
- Matrix3.fromRotationZ(CesiumMath.PI_OVER_TWO)
- ),
+/**
+ * Matrix used to convert from x-up to y-up
+ *
+ * @type {Matrix4}
+ * @constant
+ */
+Axis.X_UP_TO_Y_UP = Matrix4.fromRotationTranslation(
+ Matrix3.fromRotationZ(CesiumMath.PI_OVER_TWO)
+);
- /**
- * Matrix used to convert from y-up to x-up
- *
- * @type {Matrix4}
- * @constant
- */
- Y_UP_TO_X_UP: Matrix4.fromRotationTranslation(
- Matrix3.fromRotationZ(-CesiumMath.PI_OVER_TWO)
- ),
+/**
+ * Matrix used to convert from y-up to x-up
+ *
+ * @type {Matrix4}
+ * @constant
+ */
+Axis.Y_UP_TO_X_UP = Matrix4.fromRotationTranslation(
+ Matrix3.fromRotationZ(-CesiumMath.PI_OVER_TWO)
+);
- /**
- * Gets the axis by name
- *
- * @param {String} name The name of the axis.
- * @returns {Number} The axis enum.
- */
- fromName: function (name) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.string("name", name);
- //>>includeEnd('debug');
+/**
+ * Gets the axis by name
+ *
+ * @param {String} name The name of the axis.
+ * @returns {Number} The axis enum.
+ */
+Axis.fromName = function (name) {
+ //>>includeStart('debug', pragmas.debug);
+ Check.typeOf.string("name", name);
+ //>>includeEnd('debug');
- return Axis[name];
- },
+ return Axis[name];
};
+
export default Object.freeze(Axis);
diff --git a/Source/Scene/BatchTable.js b/Source/Scene/BatchTable.js
index a6b130ff334a..bd1b86df97d7 100644
--- a/Source/Scene/BatchTable.js
+++ b/Source/Scene/BatchTable.js
@@ -426,7 +426,7 @@ BatchTable.prototype.update = function (frameState) {
/**
* Gets a function that will update a uniform map to contain values for looking up values in the batch table.
*
- * @returns {BatchTable~updateUniformMapCallback} A callback for updating uniform maps.
+ * @returns {BatchTable.updateUniformMapCallback} A callback for updating uniform maps.
*/
BatchTable.prototype.getUniformMapCallback = function () {
var that = this;
@@ -569,7 +569,7 @@ function getGlslAttributeFunction(batchTable, attributeIndex) {
/**
* Gets a function that will update a vertex shader to contain functions for looking up values in the batch table.
*
- * @returns {BatchTable~updateVertexShaderSourceCallback} A callback for updating a vertex shader source.
+ * @returns {BatchTable.updateVertexShaderSourceCallback} A callback for updating a vertex shader source.
*/
BatchTable.prototype.getVertexShaderCallback = function () {
var attributes = this._attributes;
@@ -628,7 +628,7 @@ BatchTable.prototype.destroy = function () {
/**
* A callback for updating uniform maps.
- * @callback BatchTable~updateUniformMapCallback
+ * @callback BatchTable.updateUniformMapCallback
*
* @param {Object} uniformMap The uniform map.
* @returns {Object} The new uniform map with properties for retrieving values from the batch table.
@@ -636,7 +636,7 @@ BatchTable.prototype.destroy = function () {
/**
* A callback for updating a vertex shader source.
- * @callback BatchTable~updateVertexShaderSourceCallback
+ * @callback BatchTable.updateVertexShaderSourceCallback
*
* @param {String} vertexShaderSource The vertex shader source.
* @returns {String} The new vertex shader source with the functions for retrieving batch table values injected.
diff --git a/Source/Scene/Billboard.js b/Source/Scene/Billboard.js
index 7584799377d9..38ed91290f7d 100644
--- a/Source/Scene/Billboard.js
+++ b/Source/Scene/Billboard.js
@@ -357,7 +357,7 @@ Object.defineProperties(Billboard.prototype, {
/**
* Gets or sets near and far scaling properties of a Billboard based on the billboard's distance from the camera.
* A billboard's scale will interpolate between the {@link NearFarScalar#nearValue} and
- * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds
+ * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds
* of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}.
* Outside of these ranges the billboard's scale remains clamped to the nearest bound. If undefined,
* scaleByDistance will be disabled.
@@ -400,7 +400,7 @@ Object.defineProperties(Billboard.prototype, {
/**
* Gets or sets near and far translucency properties of a Billboard based on the billboard's distance from the camera.
* A billboard's translucency will interpolate between the {@link NearFarScalar#nearValue} and
- * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds
+ * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds
* of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}.
* Outside of these ranges the billboard's translucency remains clamped to the nearest bound. If undefined,
* translucencyByDistance will be disabled.
@@ -446,7 +446,7 @@ Object.defineProperties(Billboard.prototype, {
/**
* Gets or sets near and far pixel offset scaling properties of a Billboard based on the billboard's distance from the camera.
* A billboard's pixel offset will be scaled between the {@link NearFarScalar#nearValue} and
- * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds
+ * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds
* of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}.
* Outside of these ranges the billboard's pixel offset scale remains clamped to the nearest bound. If undefined,
* pixelOffsetScaleByDistance will be disabled.
@@ -1192,7 +1192,7 @@ Billboard.prototype._loadImage = function () {
*
*
* @param {String} id The id of the image. This can be any string that uniquely identifies the image.
- * @param {Image|Canvas|String|Resource|Billboard~CreateImageCallback} image The image to load. This parameter
+ * @param {HTMLImageElement|HTMLCanvasElement|String|Resource|Billboard.CreateImageCallback} image The image to load. This parameter
* can either be a loaded Image or Canvas, a URL which will be loaded as an Image automatically,
* or a function which will be called to create the image if it hasn't been loaded already.
* @example
@@ -1528,8 +1528,8 @@ Billboard.prototype._destroy = function () {
/**
* A function that creates an image.
- * @callback Billboard~CreateImageCallback
+ * @callback Billboard.CreateImageCallback
* @param {String} id The identifier of the image to load.
- * @returns {Image|Canvas|Promise} The image, or a promise that will resolve to an image.
+ * @returns {HTMLImageElement|HTMLCanvasElement|Promise} The image, or a promise that will resolve to an image.
*/
export default Billboard;
diff --git a/Source/Scene/BillboardCollection.js b/Source/Scene/BillboardCollection.js
index 5dc810544a1c..939ab16ec6c6 100644
--- a/Source/Scene/BillboardCollection.js
+++ b/Source/Scene/BillboardCollection.js
@@ -785,7 +785,7 @@ function createVAF(
attributes.push({
index: attributeLocations.a_batchId,
componentsPerAttribute: 1,
- componentDatatyps: ComponentDatatype.FLOAT,
+ componentDatatype: ComponentDatatype.FLOAT,
bufferUsage: BufferUsage.STATIC_DRAW,
});
}
@@ -815,7 +815,7 @@ var writePositionScratch = new EncodedCartesian3();
function writePositionScaleAndRotation(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
@@ -889,7 +889,7 @@ var UPPER_LEFT = 1.0;
function writeCompressedAttrib0(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
@@ -1038,7 +1038,7 @@ function writeCompressedAttrib0(
function writeCompressedAttrib1(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
@@ -1124,7 +1124,7 @@ function writeCompressedAttrib1(
function writeCompressedAttrib2(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
@@ -1133,7 +1133,7 @@ function writeCompressedAttrib2(
var writer = vafWriters[attributeLocations.compressedAttribute2];
var color = billboard.color;
var pickColor = !defined(billboardCollection._batchTable)
- ? billboard.getPickId(context).color
+ ? billboard.getPickId(frameState.context).color
: Color.WHITE;
var sizeInMeters = billboard.sizeInMeters ? 1.0 : 0.0;
var validAlignedAxis =
@@ -1203,7 +1203,7 @@ function writeCompressedAttrib2(
function writeEyeOffset(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
@@ -1260,7 +1260,7 @@ function writeEyeOffset(
function writeScaleByDistance(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
@@ -1300,7 +1300,7 @@ function writeScaleByDistance(
function writePixelOffsetScaleByDistance(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
@@ -1340,7 +1340,7 @@ function writePixelOffsetScaleByDistance(
function writeCompressedAttribute3(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
@@ -1364,7 +1364,7 @@ function writeCompressedAttribute3(
var disableDepthTestDistance = billboard.disableDepthTestDistance;
var clampToGround =
billboard.heightReference === HeightReference.CLAMP_TO_GROUND &&
- billboardCollection._scene.context.depthTexture;
+ frameState.context.depthTexture;
if (!defined(disableDepthTestDistance)) {
disableDepthTestDistance = clampToGround ? 5000.0 : 0.0;
}
@@ -1431,14 +1431,21 @@ function writeCompressedAttribute3(
function writeTextureCoordinateBoundsOrLabelTranslate(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
) {
if (billboard.heightReference === HeightReference.CLAMP_TO_GROUND) {
+ var scene = billboardCollection._scene;
+ var context = frameState.context;
+ var globeTranslucent = frameState.globeTranslucencyState.translucent;
+ var depthTestAgainstTerrain =
+ defined(scene.globe) && scene.globe.depthTestAgainstTerrain;
+
+ // Only do manual depth test if the globe is opaque and writes depth
billboardCollection._shaderClampToGround =
- billboardCollection._scene.context.depthTexture;
+ context.depthTexture && !globeTranslucent && depthTestAgainstTerrain;
}
var i;
var writer =
@@ -1502,7 +1509,7 @@ function writeTextureCoordinateBoundsOrLabelTranslate(
function writeBatchId(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
@@ -1529,7 +1536,7 @@ function writeBatchId(
function writeSDF(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
@@ -1569,84 +1576,84 @@ function writeSDF(
function writeBillboard(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
) {
writePositionScaleAndRotation(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
);
writeCompressedAttrib0(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
);
writeCompressedAttrib1(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
);
writeCompressedAttrib2(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
);
writeEyeOffset(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
);
writeScaleByDistance(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
);
writePixelOffsetScaleByDistance(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
);
writeCompressedAttribute3(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
);
writeTextureCoordinateBoundsOrLabelTranslate(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
);
writeBatchId(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
);
writeSDF(
billboardCollection,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
@@ -1878,7 +1885,7 @@ BillboardCollection.prototype.update = function (frameState) {
billboard._dirty = false; // In case it needed an update.
writeBillboard(
this,
- context,
+ frameState,
textureAtlasCoordinates,
vafWriters,
billboard
@@ -1971,7 +1978,7 @@ BillboardCollection.prototype.update = function (frameState) {
b._dirty = false;
for (var n = 0; n < numWriters; ++n) {
- writers[n](this, context, textureAtlasCoordinates, vafWriters, b);
+ writers[n](this, frameState, textureAtlasCoordinates, vafWriters, b);
}
}
this._vaf.commit(getIndexBuffer(context));
@@ -1981,7 +1988,7 @@ BillboardCollection.prototype.update = function (frameState) {
bb._dirty = false;
for (var o = 0; o < numWriters; ++o) {
- writers[o](this, context, textureAtlasCoordinates, vafWriters, bb);
+ writers[o](this, frameState, textureAtlasCoordinates, vafWriters, bb);
}
if (this._instanced) {
diff --git a/Source/Scene/BingMapsImageryProvider.js b/Source/Scene/BingMapsImageryProvider.js
index fff7897960b6..16bedbb4bb3a 100644
--- a/Source/Scene/BingMapsImageryProvider.js
+++ b/Source/Scene/BingMapsImageryProvider.js
@@ -18,27 +18,34 @@ import DiscardEmptyTilePolicy from "./DiscardEmptyTileImagePolicy.js";
import ImageryProvider from "./ImageryProvider.js";
/**
- * Provides tiled imagery using the Bing Maps Imagery REST API.
+ * @typedef {Object} BingMapsImageryProvider.ConstructorOptions
*
- * @alias BingMapsImageryProvider
- * @constructor
+ * Initialization options for the BingMapsImageryProvider constructor
*
- * @param {Object} options Object with the following properties:
- * @param {Resource|String} options.url The url of the Bing Maps server hosting the imagery.
- * @param {String} [options.key] The Bing Maps key for your application, which can be
+ * @property {Resource|String} url The url of the Bing Maps server hosting the imagery.
+ * @property {String} [key] The Bing Maps key for your application, which can be
* created at {@link https://www.bingmapsportal.com/}.
* If this parameter is not provided, {@link BingMapsApi.defaultKey} is used, which is undefined by default.
- * @param {String} [options.tileProtocol] The protocol to use when loading tiles, e.g. 'http' or 'https'.
+ * @property {String} [tileProtocol] The protocol to use when loading tiles, e.g. 'http' or 'https'.
* By default, tiles are loaded using the same protocol as the page.
- * @param {BingMapsStyle} [options.mapStyle=BingMapsStyle.AERIAL] The type of Bing Maps imagery to load.
- * @param {String} [options.culture=''] The culture to use when requesting Bing Maps imagery. Not
+ * @property {BingMapsStyle} [mapStyle=BingMapsStyle.AERIAL] The type of Bing Maps imagery to load.
+ * @property {String} [culture=''] The culture to use when requesting Bing Maps imagery. Not
* all cultures are supported. See {@link http://msdn.microsoft.com/en-us/library/hh441729.aspx}
* for information on the supported cultures.
- * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
- * @param {TileDiscardPolicy} [options.tileDiscardPolicy] The policy that determines if a tile
+ * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
+ * @property {TileDiscardPolicy} [tileDiscardPolicy] The policy that determines if a tile
* is invalid and should be discarded. By default, a {@link DiscardEmptyTileImagePolicy}
* will be used, with the expectation that the Bing Maps server will send a zero-length response for missing tiles.
* To ensure that no tiles are discarded, construct and pass a {@link NeverTileDiscardPolicy} for this parameter.
+ */
+
+/**
+ * Provides tiled imagery using the Bing Maps Imagery REST API.
+ *
+ * @alias BingMapsImageryProvider
+ * @constructor
+ *
+ * @param {BingMapsImageryProvider.ConstructorOptions} options Object describing initialization options
*
* @see ArcGisMapServerImageryProvider
* @see GoogleEarthEnterpriseMapsProvider
@@ -69,6 +76,92 @@ function BingMapsImageryProvider(options) {
}
//>>includeEnd('debug');
+ /**
+ * The default alpha blending value of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultNightAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultDayAlpha = undefined;
+
+ /**
+ * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
+ * makes the imagery darker while greater than 1.0 makes it brighter.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultBrightness = undefined;
+
+ /**
+ * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
+ * the contrast while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultContrast = undefined;
+
+ /**
+ * The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultHue = undefined;
+
+ /**
+ * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
+ * saturation while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultSaturation = undefined;
+
+ /**
+ * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default 1.0
+ */
+ this.defaultGamma = 1.0;
+
+ /**
+ * The default texture minification filter to apply to this provider.
+ *
+ * @type {TextureMinificationFilter}
+ * @default undefined
+ */
+ this.defaultMinificationFilter = undefined;
+
+ /**
+ * The default texture magnification filter to apply to this provider.
+ *
+ * @type {TextureMagnificationFilter}
+ * @default undefined
+ */
+ this.defaultMagnificationFilter = undefined;
+
this._key = BingMapsApi.getKey(options.key);
this._resource = Resource.createIfNeeded(options.url);
this._resource.appendForwardSlash();
@@ -88,16 +181,6 @@ function BingMapsImageryProvider(options) {
'" title="Bing Imagery"/>'
);
- /**
- * The default {@link ImageryLayer#gamma} to use for imagery layers created for this provider.
- * Changing this value after creating an {@link ImageryLayer} for this provider will have
- * no effect. Instead, set the layer's {@link ImageryLayer#gamma} property.
- *
- * @type {Number}
- * @default 1.0
- */
- this.defaultGamma = 1.0;
-
this._tilingScheme = new WebMercatorTilingScheme({
numberOfLevelZeroTilesX: 2,
numberOfLevelZeroTilesY: 2,
@@ -339,7 +422,7 @@ Object.defineProperties(BingMapsImageryProvider.prototype, {
* Gets the maximum level-of-detail that can be requested. This function should
* not be called before {@link BingMapsImageryProvider#ready} returns true.
* @memberof BingMapsImageryProvider.prototype
- * @type {Number}
+ * @type {Number|undefined}
* @readonly
*/
maximumLevel: {
@@ -550,7 +633,7 @@ BingMapsImageryProvider.prototype.getTileCredits = function (x, y, level) {
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level.
* @param {Request} [request] The request object. Intended for internal use only.
- * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
+ * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if there are too many active requests to the server, and the request
* should be retried later. The resolved image may be either an
* Image or a Canvas DOM object.
diff --git a/Source/Scene/BingMapsStyle.js b/Source/Scene/BingMapsStyle.js
index de1f0b35bccf..0923588f2dd6 100644
--- a/Source/Scene/BingMapsStyle.js
+++ b/Source/Scene/BingMapsStyle.js
@@ -1,7 +1,7 @@
/**
* The types of imagery provided by Bing Maps.
*
- * @exports BingMapsStyle
+ * @enum {Number}
*
* @see BingMapsImageryProvider
*/
diff --git a/Source/Scene/BlendEquation.js b/Source/Scene/BlendEquation.js
index 1d70ebaa957a..d2f49cbe4d8f 100644
--- a/Source/Scene/BlendEquation.js
+++ b/Source/Scene/BlendEquation.js
@@ -3,7 +3,7 @@ import WebGLConstants from "../Core/WebGLConstants.js";
/**
* Determines how two pixels' values are combined.
*
- * @exports BlendEquation
+ * @enum {Number}
*/
var BlendEquation = {
/**
diff --git a/Source/Scene/BlendFunction.js b/Source/Scene/BlendFunction.js
index 0b1d91d5847f..f0232d2ebb75 100644
--- a/Source/Scene/BlendFunction.js
+++ b/Source/Scene/BlendFunction.js
@@ -3,7 +3,7 @@ import WebGLConstants from "../Core/WebGLConstants.js";
/**
* Determines how blending factors are computed.
*
- * @exports BlendFunction
+ * @enum {Number}
*/
var BlendFunction = {
/**
diff --git a/Source/Scene/BlendOption.js b/Source/Scene/BlendOption.js
index 0dc6e060a5c3..0af43ae1d41e 100644
--- a/Source/Scene/BlendOption.js
+++ b/Source/Scene/BlendOption.js
@@ -1,7 +1,7 @@
/**
* Determines how opaque and translucent parts of billboards, points, and labels are blended with the scene.
*
- * @exports BlendOption
+ * @enum {Number}
*/
var BlendOption = {
/**
diff --git a/Source/Scene/BlendingState.js b/Source/Scene/BlendingState.js
index f697e0a9c8bd..f01f1f68180f 100644
--- a/Source/Scene/BlendingState.js
+++ b/Source/Scene/BlendingState.js
@@ -9,7 +9,7 @@ import BlendFunction from "./BlendFunction.js";
* This is a helper when using custom render states with {@link Appearance#renderState}.
*
*
- * @exports BlendingState
+ * @namespace
*/
var BlendingState = {
/**
diff --git a/Source/Scene/Camera.js b/Source/Scene/Camera.js
index cbfedd8b73c8..d5927f7bf6d9 100644
--- a/Source/Scene/Camera.js
+++ b/Source/Scene/Camera.js
@@ -137,7 +137,7 @@ function Camera(scene) {
/**
* The region of space in view.
*
- * @type {Frustum}
+ * @type {PerspectiveFrustum|PerspectiveOffCenterFrustum|OrthographicFrustum}
* @default PerspectiveFrustum()
*
* @see PerspectiveFrustum
@@ -1145,6 +1145,7 @@ Camera.prototype._adjustOrthographicFrustum = function (zooming) {
rayIntersection = globe.pickWorldCoordinates(
ray,
scene,
+ true,
scratchRayIntersection
);
@@ -2804,8 +2805,9 @@ function pickMapColumbusView(camera, windowPosition, projection, result) {
* @param {Cartesian2} windowPosition The x and y coordinates of a pixel.
* @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid to pick.
* @param {Cartesian3} [result] The object onto which to store the result.
- * @returns {Cartesian3} If the ellipsoid or map was picked, returns the point on the surface of the ellipsoid or map
- * in world coordinates. If the ellipsoid or map was not picked, returns undefined.
+ * @returns {Cartesian3 | undefined} If the ellipsoid or map was picked,
+ * returns the point on the surface of the ellipsoid or map in world
+ * coordinates. If the ellipsoid or map was not picked, returns undefined.
*
* @example
* var canvas = viewer.scene.canvas;
@@ -3172,8 +3174,8 @@ var newOptions = {
};
/**
- * Cancels the current camera flight if one is in progress.
- * The camera is left at it's current location.
+ * Cancels the current camera flight and leaves the camera at its current location.
+ * If no flight is in progress, this this function does nothing.
*/
Camera.prototype.cancelFlight = function () {
if (defined(this._currentFlight)) {
@@ -3182,6 +3184,38 @@ Camera.prototype.cancelFlight = function () {
}
};
+/**
+ * Completes the current camera flight and moves the camera immediately to its final destination.
+ * If no flight is in progress, this this function does nothing.
+ */
+Camera.prototype.completeFlight = function () {
+ if (defined(this._currentFlight)) {
+ this._currentFlight.cancelTween();
+
+ var options = {
+ destination: undefined,
+ orientation: {
+ heading: undefined,
+ pitch: undefined,
+ roll: undefined,
+ },
+ };
+
+ options.destination = newOptions.destination;
+ options.orientation.heading = newOptions.heading;
+ options.orientation.pitch = newOptions.pitch;
+ options.orientation.roll = newOptions.roll;
+
+ this.setView(options);
+
+ if (defined(this._currentFlight.complete)) {
+ this._currentFlight.complete();
+ }
+
+ this._currentFlight = undefined;
+ }
+};
+
/**
* Flies the camera from its current position to a new position.
*
@@ -3191,15 +3225,15 @@ Camera.prototype.cancelFlight = function () {
* towards the center of the frame in 3D and in the negative z direction in Columbus view. The up direction will point towards local north in 3D and in the positive
* y direction in Columbus view. Orientation is not used in 2D when in infinite scrolling mode.
* @param {Number} [options.duration] The duration of the flight in seconds. If omitted, Cesium attempts to calculate an ideal duration based on the distance to be traveled by the flight.
- * @param {Camera~FlightCompleteCallback} [options.complete] The function to execute when the flight is complete.
- * @param {Camera~FlightCancelledCallback} [options.cancel] The function to execute if the flight is cancelled.
+ * @param {Camera.FlightCompleteCallback} [options.complete] The function to execute when the flight is complete.
+ * @param {Camera.FlightCancelledCallback} [options.cancel] The function to execute if the flight is cancelled.
* @param {Matrix4} [options.endTransform] Transform matrix representing the reference frame the camera will be in when the flight is completed.
* @param {Number} [options.maximumHeight] The maximum height at the peak of the flight.
* @param {Number} [options.pitchAdjustHeight] If camera flyes higher than that value, adjust pitch duiring the flight to look down, and keep Earth in viewport.
* @param {Number} [options.flyOverLongitude] There are always two ways between 2 points on globe. This option force camera to choose fight direction to fly over that longitude.
* @param {Number} [options.flyOverLongitudeWeight] Fly over the lon specifyed via flyOverLongitude only if that way is not longer than short way times flyOverLongitudeWeight.
* @param {Boolean} [options.convert] Whether to convert the destination from world coordinates to scene coordinates (only relevant when not using 3D). Defaults to true
.
- * @param {EasingFunction|EasingFunction~Callback} [options.easingFunction] Controls how the time is interpolated over the duration of the flight.
+ * @param {EasingFunction.Callback} [options.easingFunction] Controls how the time is interpolated over the duration of the flight.
*
* @exception {DeveloperError} If either direction or up is given, then both are required.
*
@@ -3459,14 +3493,14 @@ var scratchFlyToBoundingSphereMatrix3 = new Matrix3();
* @param {Object} [options] Object with the following properties:
* @param {Number} [options.duration] The duration of the flight in seconds. If omitted, Cesium attempts to calculate an ideal duration based on the distance to be traveled by the flight.
* @param {HeadingPitchRange} [options.offset] The offset from the target in the local east-north-up reference frame centered at the target.
- * @param {Camera~FlightCompleteCallback} [options.complete] The function to execute when the flight is complete.
- * @param {Camera~FlightCancelledCallback} [options.cancel] The function to execute if the flight is cancelled.
+ * @param {Camera.FlightCompleteCallback} [options.complete] The function to execute when the flight is complete.
+ * @param {Camera.FlightCancelledCallback} [options.cancel] The function to execute if the flight is cancelled.
* @param {Matrix4} [options.endTransform] Transform matrix representing the reference frame the camera will be in when the flight is completed.
* @param {Number} [options.maximumHeight] The maximum height at the peak of the flight.
* @param {Number} [options.pitchAdjustHeight] If camera flyes higher than that value, adjust pitch duiring the flight to look down, and keep Earth in viewport.
* @param {Number} [options.flyOverLongitude] There are always two ways between 2 points on globe. This option force camera to choose fight direction to fly over that longitude.
* @param {Number} [options.flyOverLongitudeWeight] Fly over the lon specifyed via flyOverLongitude only if that way is not longer than short way times flyOverLongitudeWeight.
- * @param {EasingFunction|EasingFunction~Callback} [options.easingFunction] Controls how the time is interpolated over the duration of the flight.
+ * @param {EasingFunction.Callback} [options.easingFunction] Controls how the time is interpolated over the duration of the flight.
*/
Camera.prototype.flyToBoundingSphere = function (boundingSphere, options) {
//>>includeStart('debug', pragmas.debug);
@@ -3852,11 +3886,11 @@ Camera.clone = function (camera, result) {
/**
* A function that will execute when a flight completes.
- * @callback Camera~FlightCompleteCallback
+ * @callback Camera.FlightCompleteCallback
*/
/**
* A function that will execute when a flight is cancelled.
- * @callback Camera~FlightCancelledCallback
+ * @callback Camera.FlightCancelledCallback
*/
export default Camera;
diff --git a/Source/Scene/CameraEventAggregator.js b/Source/Scene/CameraEventAggregator.js
index cdaaa41bc083..364ffaa4f41f 100644
--- a/Source/Scene/CameraEventAggregator.js
+++ b/Source/Scene/CameraEventAggregator.js
@@ -296,7 +296,7 @@ function listenMouseMove(aggregator, modifier) {
* @alias CameraEventAggregator
* @constructor
*
- * @param {Canvas} [canvas=document] The element to handle events for.
+ * @param {HTMLCanvasElement} [canvas=document] The element to handle events for.
*
* @see ScreenSpaceEventHandler
*/
diff --git a/Source/Scene/CameraEventType.js b/Source/Scene/CameraEventType.js
index 29e652544818..ec6ab41afed7 100644
--- a/Source/Scene/CameraEventType.js
+++ b/Source/Scene/CameraEventType.js
@@ -1,7 +1,7 @@
/**
* Enumerates the available input for interacting with the camera.
*
- * @exports CameraEventType
+ * @enum {Number}
*/
var CameraEventType = {
/**
diff --git a/Source/Scene/Cesium3DTileColorBlendMode.js b/Source/Scene/Cesium3DTileColorBlendMode.js
index 02e4bde25e00..3f096aafebb4 100644
--- a/Source/Scene/Cesium3DTileColorBlendMode.js
+++ b/Source/Scene/Cesium3DTileColorBlendMode.js
@@ -22,7 +22,7 @@
* }
*
*
- * @exports Cesium3DTileColorBlendMode
+ * @enum {Number}
*/
var Cesium3DTileColorBlendMode = {
/**
diff --git a/Source/Scene/Cesium3DTileFeature.js b/Source/Scene/Cesium3DTileFeature.js
index 2700ea5d3f82..a9d3436b2490 100644
--- a/Source/Scene/Cesium3DTileFeature.js
+++ b/Source/Scene/Cesium3DTileFeature.js
@@ -161,7 +161,7 @@ Cesium3DTileFeature.prototype.hasProperty = function (name) {
*
* @see {@link https://github.com/CesiumGS/3d-tiles/tree/master/extensions/3DTILES_batch_table_hierarchy}
*
- * @param {String[]} results An array into which to store the results.
+ * @param {String[]} [results] An array into which to store the results.
* @returns {String[]} The names of the feature's properties.
*/
Cesium3DTileFeature.prototype.getPropertyNames = function (results) {
diff --git a/Source/Scene/Cesium3DTileOptimizationHint.js b/Source/Scene/Cesium3DTileOptimizationHint.js
index 9469838d0f91..0ee1d97145e8 100644
--- a/Source/Scene/Cesium3DTileOptimizationHint.js
+++ b/Source/Scene/Cesium3DTileOptimizationHint.js
@@ -1,7 +1,7 @@
/**
* Hint defining optimization support for a 3D tile
*
- * @exports Cesium3DTileOptimizationHint
+ * @enum {Number}
*
* @private
*/
diff --git a/Source/Scene/Cesium3DTileOptimizations.js b/Source/Scene/Cesium3DTileOptimizations.js
index 9117b6e931cb..98a288f6ffa6 100644
--- a/Source/Scene/Cesium3DTileOptimizations.js
+++ b/Source/Scene/Cesium3DTileOptimizations.js
@@ -7,7 +7,7 @@ import TileOrientedBoundingBox from "./TileOrientedBoundingBox.js";
/**
* Utility functions for computing optimization hints for a {@link Cesium3DTileset}.
*
- * @exports Cesium3DTileOptimizations
+ * @namespace Cesium3DTileOptimizations
*
* @private
*/
diff --git a/Source/Scene/Cesium3DTilePointFeature.js b/Source/Scene/Cesium3DTilePointFeature.js
index 5c8cb77300f1..79ee6de46456 100644
--- a/Source/Scene/Cesium3DTilePointFeature.js
+++ b/Source/Scene/Cesium3DTilePointFeature.js
@@ -731,7 +731,7 @@ Cesium3DTilePointFeature.prototype.hasProperty = function (name) {
*
* @see {@link https://github.com/CesiumGS/3d-tiles/tree/master/extensions/3DTILES_batch_table_hierarchy}
*
- * @param {String[]} results An array into which to store the results.
+ * @param {String[]} [results] An array into which to store the results.
* @returns {String[]} The names of the feature's properties.
*/
Cesium3DTilePointFeature.prototype.getPropertyNames = function (results) {
diff --git a/Source/Scene/Cesium3DTileRefine.js b/Source/Scene/Cesium3DTileRefine.js
index c142ff7187d5..ade192c1ee03 100644
--- a/Source/Scene/Cesium3DTileRefine.js
+++ b/Source/Scene/Cesium3DTileRefine.js
@@ -5,7 +5,7 @@
* in the 3D Tiles spec.
*
*
- * @exports Cesium3DTileRefine
+ * @enum {Number}
*
* @private
*/
diff --git a/Source/Scene/Cesium3DTileStyle.js b/Source/Scene/Cesium3DTileStyle.js
index b62777b5bca1..e87efcfe4cf9 100644
--- a/Source/Scene/Cesium3DTileStyle.js
+++ b/Source/Scene/Cesium3DTileStyle.js
@@ -1638,7 +1638,7 @@ Object.defineProperties(Cesium3DTileStyle.prototype, {
* Gets the color shader function for this style.
*
* @param {String} functionName Name to give to the generated function.
- * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes.
+ * @param {String} propertyNameMap Maps property variable names to shader attribute names.
* @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent.
*
* @returns {String} The shader function.
@@ -1647,7 +1647,7 @@ Object.defineProperties(Cesium3DTileStyle.prototype, {
*/
Cesium3DTileStyle.prototype.getColorShaderFunction = function (
functionName,
- attributePrefix,
+ propertyNameMap,
shaderState
) {
if (this._colorShaderFunctionReady) {
@@ -1660,7 +1660,7 @@ Cesium3DTileStyle.prototype.getColorShaderFunction = function (
this._colorShaderFunction = defined(this.color)
? this.color.getShaderFunction(
functionName,
- attributePrefix,
+ propertyNameMap,
shaderState,
"vec4"
)
@@ -1673,7 +1673,7 @@ Cesium3DTileStyle.prototype.getColorShaderFunction = function (
* Gets the show shader function for this style.
*
* @param {String} functionName Name to give to the generated function.
- * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes.
+ * @param {String} propertyNameMap Maps property variable names to shader attribute names.
* @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent.
*
* @returns {String} The shader function.
@@ -1682,7 +1682,7 @@ Cesium3DTileStyle.prototype.getColorShaderFunction = function (
*/
Cesium3DTileStyle.prototype.getShowShaderFunction = function (
functionName,
- attributePrefix,
+ propertyNameMap,
shaderState
) {
if (this._showShaderFunctionReady) {
@@ -1694,7 +1694,7 @@ Cesium3DTileStyle.prototype.getShowShaderFunction = function (
this._showShaderFunction = defined(this.show)
? this.show.getShaderFunction(
functionName,
- attributePrefix,
+ propertyNameMap,
shaderState,
"bool"
)
@@ -1706,7 +1706,7 @@ Cesium3DTileStyle.prototype.getShowShaderFunction = function (
* Gets the pointSize shader function for this style.
*
* @param {String} functionName Name to give to the generated function.
- * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes.
+ * @param {String} propertyNameMap Maps property variable names to shader attribute names.
* @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent.
*
* @returns {String} The shader function.
@@ -1715,7 +1715,7 @@ Cesium3DTileStyle.prototype.getShowShaderFunction = function (
*/
Cesium3DTileStyle.prototype.getPointSizeShaderFunction = function (
functionName,
- attributePrefix,
+ propertyNameMap,
shaderState
) {
if (this._pointSizeShaderFunctionReady) {
@@ -1727,7 +1727,7 @@ Cesium3DTileStyle.prototype.getPointSizeShaderFunction = function (
this._pointSizeShaderFunction = defined(this.pointSize)
? this.pointSize.getShaderFunction(
functionName,
- attributePrefix,
+ propertyNameMap,
shaderState,
"float"
)
diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js
index 89370d7d43a4..45bfd2c01da9 100644
--- a/Source/Scene/Cesium3DTileset.js
+++ b/Source/Scene/Cesium3DTileset.js
@@ -72,7 +72,7 @@ import TileOrientedBoundingBox from "./TileOrientedBoundingBox.js";
* @param {Boolean} [options.foveatedScreenSpaceError=true] Optimization option. Prioritize loading tiles in the center of the screen by temporarily raising the screen space error for tiles around the edge of the screen. Screen space error returns to normal once all the tiles in the center of the screen as determined by the {@link Cesium3DTileset#foveatedConeSize} are loaded.
* @param {Number} [options.foveatedConeSize=0.1] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control the cone size that determines which tiles are deferred. Tiles that are inside this cone are loaded immediately. Tiles outside the cone are potentially deferred based on how far outside the cone they are and their screen space error. This is controlled by {@link Cesium3DTileset#foveatedInterpolationCallback} and {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation}. Setting this to 0.0 means the cone will be the line formed by the camera position and its view direction. Setting this to 1.0 means the cone encompasses the entire field of view of the camera, disabling the effect.
* @param {Number} [options.foveatedMinimumScreenSpaceErrorRelaxation=0.0] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control the starting screen space error relaxation for tiles outside the foveated cone. The screen space error will be raised starting with tileset value up to {@link Cesium3DTileset#maximumScreenSpaceError} based on the provided {@link Cesium3DTileset#foveatedInterpolationCallback}.
- * @param {Cesium3DTileset~foveatedInterpolationCallback} [options.foveatedInterpolationCallback=Math.lerp] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control how much to raise the screen space error for tiles outside the foveated cone, interpolating between {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation} and {@link Cesium3DTileset#maximumScreenSpaceError}
+ * @param {Cesium3DTileset.foveatedInterpolationCallback} [options.foveatedInterpolationCallback=Math.lerp] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control how much to raise the screen space error for tiles outside the foveated cone, interpolating between {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation} and {@link Cesium3DTileset#maximumScreenSpaceError}
* @param {Number} [options.foveatedTimeDelay=0.2] Optimization option. Used when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control how long in seconds to wait after the camera stops moving before deferred tiles start loading in. This time delay prevents requesting tiles around the edges of the screen when the camera is moving. Setting this to 0.0 will immediately request all tiles in any given view.
* @param {Boolean} [options.skipLevelOfDetail=false] Optimization option. Determines if level of detail skipping should be applied during the traversal.
* @param {Number} [options.baseScreenSpaceError=1024] When skipLevelOfDetail
is true
, the screen space error that must be reached before skipping levels of detail.
@@ -325,9 +325,10 @@ function Cesium3DTileset(options) {
);
/**
- * Gets a function that will update the foveated screen space error for a tile.
+ * Gets or sets a callback to control how much to raise the screen space error for tiles outside the foveated cone,
+ * interpolating between {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation} and {@link Cesium3DTileset#maximumScreenSpaceError}.
*
- * @type {Cesium3DTileset~foveatedInterpolationCallback} A callback to control how much to raise the screen space error for tiles outside the foveated cone, interpolating between {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation} and {@link Cesium3DTileset#maximumScreenSpaceError}.
+ * @type {Cesium3DTileset.foveatedInterpolationCallback}
*/
this.foveatedInterpolationCallback = defaultValue(
options.foveatedInterpolationCallback,
@@ -1202,7 +1203,7 @@ Object.defineProperties(Cesium3DTileset.prototype, {
*
* @memberof Cesium3DTileset.prototype
*
- * @type {Cesium3DTileStyle}
+ * @type {Cesium3DTileStyle|undefined}
*
* @default undefined
*
@@ -2219,7 +2220,7 @@ function updateTiles(tileset, frameState, passOptions) {
tileset._backfaceCommands.trim();
if (bivariateVisibilityTest) {
- /**
+ /*
* Consider 'effective leaf' tiles as selected tiles that have no selected descendants. They may have children,
* but they are currently our effective leaves because they do not have selected descendants. These tiles
* are those where with tile._finalResolution === true.
@@ -2618,7 +2619,7 @@ Cesium3DTileset.prototype.destroy = function () {
* Optimization option. Used as a callback when {@link Cesium3DTileset#foveatedScreenSpaceError} is true to control how much to raise the screen space error for tiles outside the foveated cone,
* interpolating between {@link Cesium3DTileset#foveatedMinimumScreenSpaceErrorRelaxation} and {@link Cesium3DTileset#maximumScreenSpaceError}.
*
- * @callback Cesium3DTileset~foveatedInterpolationCallback
+ * @callback Cesium3DTileset.foveatedInterpolationCallback
* @default Math.lerp
*
* @param {Number} p The start value to interpolate.
diff --git a/Source/Scene/ClassificationModel.js b/Source/Scene/ClassificationModel.js
index e9af83fcb4e4..679fa24cd0b0 100644
--- a/Source/Scene/ClassificationModel.js
+++ b/Source/Scene/ClassificationModel.js
@@ -628,7 +628,7 @@ function createProgram(model) {
uniformDecl +
"void main() {\n" +
computePosition +
- " gl_Position = czm_depthClampFarPlane(positionInClipCoords);\n" +
+ " gl_Position = czm_depthClamp(positionInClipCoords);\n" +
"}\n";
var fs =
"#ifdef GL_EXT_frag_depth\n" +
@@ -637,7 +637,7 @@ function createProgram(model) {
"void main() \n" +
"{ \n" +
" gl_FragColor = vec4(1.0); \n" +
- " czm_writeDepthClampedToFarPlane();\n" +
+ " czm_writeDepthClamp();\n" +
"}\n";
if (model.extensionsUsed.WEB3D_quantized_attributes) {
diff --git a/Source/Scene/ClassificationPrimitive.js b/Source/Scene/ClassificationPrimitive.js
index 47012dac112a..a2e060b7d4ce 100644
--- a/Source/Scene/ClassificationPrimitive.js
+++ b/Source/Scene/ClassificationPrimitive.js
@@ -155,8 +155,6 @@ function ClassificationPrimitive(options) {
this._spPick2D = undefined; // only derived if necessary
this._spColor2D = undefined; // only derived if necessary
- this._rsStencilPreloadPass = undefined;
- this._rsStencilPreloadPass3DTiles = undefined;
this._rsStencilDepthPass = undefined;
this._rsStencilDepthPass3DTiles = undefined;
this._rsColorPass = undefined;
@@ -357,7 +355,7 @@ ClassificationPrimitive.isSupported = function (scene) {
return scene.context.stencilBuffer;
};
-function getStencilPreloadRenderState(enableStencil, mask3DTiles) {
+function getStencilDepthRenderState(enableStencil, mask3DTiles) {
var stencilFunction = mask3DTiles
? StencilFunction.EQUAL
: StencilFunction.ALWAYS;
@@ -374,49 +372,13 @@ function getStencilPreloadRenderState(enableStencil, mask3DTiles) {
frontOperation: {
fail: StencilOperation.KEEP,
zFail: StencilOperation.DECREMENT_WRAP,
- zPass: StencilOperation.DECREMENT_WRAP,
+ zPass: StencilOperation.KEEP,
},
backFunction: stencilFunction,
backOperation: {
fail: StencilOperation.KEEP,
zFail: StencilOperation.INCREMENT_WRAP,
- zPass: StencilOperation.INCREMENT_WRAP,
- },
- reference: StencilConstants.CESIUM_3D_TILE_MASK,
- mask: StencilConstants.CESIUM_3D_TILE_MASK,
- },
- stencilMask: StencilConstants.CLASSIFICATION_MASK,
- depthTest: {
- enabled: false,
- },
- depthMask: false,
- };
-}
-
-function getStencilDepthRenderState(enableStencil, mask3DTiles) {
- var stencilFunction = mask3DTiles
- ? StencilFunction.EQUAL
- : StencilFunction.ALWAYS;
- return {
- colorMask: {
- red: false,
- green: false,
- blue: false,
- alpha: false,
- },
- stencilTest: {
- enabled: enableStencil,
- frontFunction: stencilFunction,
- frontOperation: {
- fail: StencilOperation.KEEP,
- zFail: StencilOperation.KEEP,
- zPass: StencilOperation.INCREMENT_WRAP,
- },
- backFunction: stencilFunction,
- backOperation: {
- fail: StencilOperation.KEEP,
- zFail: StencilOperation.KEEP,
- zPass: StencilOperation.DECREMENT_WRAP,
+ zPass: StencilOperation.KEEP,
},
reference: StencilConstants.CESIUM_3D_TILE_MASK,
mask: StencilConstants.CESIUM_3D_TILE_MASK,
@@ -436,15 +398,15 @@ function getColorRenderState(enableStencil) {
enabled: enableStencil,
frontFunction: StencilFunction.NOT_EQUAL,
frontOperation: {
- fail: StencilOperation.KEEP,
- zFail: StencilOperation.KEEP,
- zPass: StencilOperation.DECREMENT_WRAP,
+ fail: StencilOperation.ZERO,
+ zFail: StencilOperation.ZERO,
+ zPass: StencilOperation.ZERO,
},
backFunction: StencilFunction.NOT_EQUAL,
backOperation: {
- fail: StencilOperation.KEEP,
- zFail: StencilOperation.KEEP,
- zPass: StencilOperation.DECREMENT_WRAP,
+ fail: StencilOperation.ZERO,
+ zFail: StencilOperation.ZERO,
+ zPass: StencilOperation.ZERO,
},
reference: 0,
mask: StencilConstants.CLASSIFICATION_MASK,
@@ -454,7 +416,7 @@ function getColorRenderState(enableStencil) {
enabled: false,
},
depthMask: false,
- blending: BlendingState.ALPHA_BLEND,
+ blending: BlendingState.PRE_MULTIPLIED_ALPHA_BLEND,
};
}
@@ -463,15 +425,15 @@ var pickRenderState = {
enabled: true,
frontFunction: StencilFunction.NOT_EQUAL,
frontOperation: {
- fail: StencilOperation.KEEP,
- zFail: StencilOperation.KEEP,
- zPass: StencilOperation.DECREMENT_WRAP,
+ fail: StencilOperation.ZERO,
+ zFail: StencilOperation.ZERO,
+ zPass: StencilOperation.ZERO,
},
backFunction: StencilFunction.NOT_EQUAL,
backOperation: {
- fail: StencilOperation.KEEP,
- zFail: StencilOperation.KEEP,
- zPass: StencilOperation.DECREMENT_WRAP,
+ fail: StencilOperation.ZERO,
+ zFail: StencilOperation.ZERO,
+ zPass: StencilOperation.ZERO,
},
reference: 0,
mask: StencilConstants.CLASSIFICATION_MASK,
@@ -489,17 +451,11 @@ function createRenderStates(
appearance,
twoPasses
) {
- if (defined(classificationPrimitive._rsStencilPreloadPass)) {
+ if (defined(classificationPrimitive._rsStencilDepthPass)) {
return;
}
var stencilEnabled = !classificationPrimitive.debugShowShadowVolume;
- classificationPrimitive._rsStencilPreloadPass = RenderState.fromCache(
- getStencilPreloadRenderState(stencilEnabled, false)
- );
- classificationPrimitive._rsStencilPreloadPass3DTiles = RenderState.fromCache(
- getStencilPreloadRenderState(stencilEnabled, true)
- );
classificationPrimitive._rsStencilDepthPass = RenderState.fromCache(
getStencilDepthRenderState(stencilEnabled, false)
);
@@ -722,7 +678,7 @@ function createShaderProgram(classificationPrimitive, frameState) {
function createColorCommands(classificationPrimitive, colorCommands) {
var primitive = classificationPrimitive._primitive;
- var length = primitive._va.length * 3; // each geometry (pack of vertex attributes) needs 3 commands: front/back stencils and fill
+ var length = primitive._va.length * 2; // each geometry (pack of vertex attributes) needs 2 commands: front/back stencils and fill
colorCommands.length = length;
var i;
@@ -735,10 +691,10 @@ function createColorCommands(classificationPrimitive, colorCommands) {
var needs2DShader = classificationPrimitive._needs2DShader;
- for (i = 0; i < length; i += 3) {
+ for (i = 0; i < length; i += 2) {
var vertexArray = primitive._va[vaIndex++];
- // Stencil preload command
+ // Stencil depth command
command = colorCommands[i];
if (!defined(command)) {
command = colorCommands[i] = new DrawCommand({
@@ -747,30 +703,6 @@ function createColorCommands(classificationPrimitive, colorCommands) {
});
}
- command.vertexArray = vertexArray;
- command.renderState = classificationPrimitive._rsStencilPreloadPass;
- command.shaderProgram = classificationPrimitive._sp;
- command.uniformMap = uniformMap;
- command.pass = Pass.TERRAIN_CLASSIFICATION;
-
- derivedCommand = DrawCommand.shallowClone(
- command,
- command.derivedCommands.tileset
- );
- derivedCommand.renderState =
- classificationPrimitive._rsStencilPreloadPass3DTiles;
- derivedCommand.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION;
- command.derivedCommands.tileset = derivedCommand;
-
- // Stencil depth command
- command = colorCommands[i + 1];
- if (!defined(command)) {
- command = colorCommands[i + 1] = new DrawCommand({
- owner: classificationPrimitive,
- primitiveType: primitive._primitiveType,
- });
- }
-
command.vertexArray = vertexArray;
command.renderState = classificationPrimitive._rsStencilDepthPass;
command.shaderProgram = classificationPrimitive._sp;
@@ -787,9 +719,9 @@ function createColorCommands(classificationPrimitive, colorCommands) {
command.derivedCommands.tileset = derivedCommand;
// Color command
- command = colorCommands[i + 2];
+ command = colorCommands[i + 1];
if (!defined(command)) {
- command = colorCommands[i + 2] = new DrawCommand({
+ command = colorCommands[i + 1] = new DrawCommand({
owner: classificationPrimitive,
primitiveType: primitive._primitiveType,
});
@@ -839,9 +771,9 @@ function createColorCommands(classificationPrimitive, colorCommands) {
var spStencil = classificationPrimitive._spStencil;
var commandIndex = 0;
- length = commandsIgnoreShow.length = (length / 3) * 2;
+ length = commandsIgnoreShow.length = length / 2;
- for (var j = 0; j < length; j += 2) {
+ for (var j = 0; j < length; ++j) {
var commandIgnoreShow = (commandsIgnoreShow[j] = DrawCommand.shallowClone(
colorCommands[commandIndex],
commandsIgnoreShow[j]
@@ -849,14 +781,7 @@ function createColorCommands(classificationPrimitive, colorCommands) {
commandIgnoreShow.shaderProgram = spStencil;
commandIgnoreShow.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW;
- commandIgnoreShow = commandsIgnoreShow[j + 1] = DrawCommand.shallowClone(
- colorCommands[commandIndex + 1],
- commandsIgnoreShow[j + 1]
- );
- commandIgnoreShow.shaderProgram = spStencil;
- commandIgnoreShow.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW;
-
- commandIndex += 3;
+ commandIndex += 2;
}
}
@@ -864,7 +789,7 @@ function createPickCommands(classificationPrimitive, pickCommands) {
var usePickOffsets = classificationPrimitive._usePickOffsets;
var primitive = classificationPrimitive._primitive;
- var length = primitive._va.length * 3; // each geometry (pack of vertex attributes) needs 3 commands: front/back stencils and fill
+ var length = primitive._va.length * 2; // each geometry (pack of vertex attributes) needs 2 commands: front/back stencils and fill
// Fallback for batching same-color geometry instances
var pickOffsets;
@@ -872,7 +797,7 @@ function createPickCommands(classificationPrimitive, pickCommands) {
var pickOffset;
if (usePickOffsets) {
pickOffsets = primitive._pickOffsets;
- length = pickOffsets.length * 3;
+ length = pickOffsets.length * 2;
}
pickCommands.length = length;
@@ -887,14 +812,14 @@ function createPickCommands(classificationPrimitive, pickCommands) {
var needs2DShader = classificationPrimitive._needs2DShader;
- for (j = 0; j < length; j += 3) {
+ for (j = 0; j < length; j += 2) {
var vertexArray = primitive._va[vaIndex++];
if (usePickOffsets) {
pickOffset = pickOffsets[pickIndex++];
vertexArray = primitive._va[pickOffset.index];
}
- // Stencil preload command
+ // Stencil depth command
command = pickCommands[j];
if (!defined(command)) {
command = pickCommands[j] = new DrawCommand({
@@ -904,36 +829,6 @@ function createPickCommands(classificationPrimitive, pickCommands) {
});
}
- command.vertexArray = vertexArray;
- command.renderState = classificationPrimitive._rsStencilPreloadPass;
- command.shaderProgram = classificationPrimitive._sp;
- command.uniformMap = uniformMap;
- command.pass = Pass.TERRAIN_CLASSIFICATION;
- if (usePickOffsets) {
- command.offset = pickOffset.offset;
- command.count = pickOffset.count;
- }
-
- // Derive for 3D Tiles classification
- derivedCommand = DrawCommand.shallowClone(
- command,
- command.derivedCommands.tileset
- );
- derivedCommand.renderState =
- classificationPrimitive._rsStencilPreloadPass3DTiles;
- derivedCommand.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION;
- command.derivedCommands.tileset = derivedCommand;
-
- // Stencil depth command
- command = pickCommands[j + 1];
- if (!defined(command)) {
- command = pickCommands[j + 1] = new DrawCommand({
- owner: classificationPrimitive,
- primitiveType: primitive._primitiveType,
- pickOnly: true,
- });
- }
-
command.vertexArray = vertexArray;
command.renderState = classificationPrimitive._rsStencilDepthPass;
command.shaderProgram = classificationPrimitive._sp;
@@ -955,9 +850,9 @@ function createPickCommands(classificationPrimitive, pickCommands) {
command.derivedCommands.tileset = derivedCommand;
// Pick color command
- command = pickCommands[j + 2];
+ command = pickCommands[j + 1];
if (!defined(command)) {
- command = pickCommands[j + 2] = new DrawCommand({
+ command = pickCommands[j + 1] = new DrawCommand({
owner: classificationPrimitive,
primitiveType: primitive._primitiveType,
pickOnly: true,
@@ -1016,7 +911,7 @@ function createCommands(
}
function boundingVolumeIndex(commandIndex, length) {
- return Math.floor((commandIndex % length) / 3);
+ return Math.floor((commandIndex % length) / 2);
}
function updateAndQueueRenderCommand(
@@ -1119,7 +1014,7 @@ function updateAndQueueCommands(
var ignoreShowCommands = classificationPrimitive._commandsIgnoreShow;
var ignoreShowCommandsLength = ignoreShowCommands.length;
for (i = 0; i < ignoreShowCommandsLength; ++i) {
- boundingVolume = boundingVolumes[Math.floor(i / 2)];
+ boundingVolume = boundingVolumes[i];
command = ignoreShowCommands[i];
updateAndQueueRenderCommand(
command,
@@ -1411,12 +1306,6 @@ ClassificationPrimitive.prototype.update = function (frameState) {
this._ready
) {
this._debugShowShadowVolume = true;
- this._rsStencilPreloadPass = RenderState.fromCache(
- getStencilPreloadRenderState(false, false)
- );
- this._rsStencilPreloadPass3DTiles = RenderState.fromCache(
- getStencilPreloadRenderState(false, true)
- );
this._rsStencilDepthPass = RenderState.fromCache(
getStencilDepthRenderState(false, false)
);
@@ -1426,12 +1315,6 @@ ClassificationPrimitive.prototype.update = function (frameState) {
this._rsColorPass = RenderState.fromCache(getColorRenderState(false));
} else if (!this.debugShowShadowVolume && this._debugShowShadowVolume) {
this._debugShowShadowVolume = false;
- this._rsStencilPreloadPass = RenderState.fromCache(
- getStencilPreloadRenderState(true, false)
- );
- this._rsStencilPreloadPass3DTiles = RenderState.fromCache(
- getStencilPreloadRenderState(true, true)
- );
this._rsStencilDepthPass = RenderState.fromCache(
getStencilDepthRenderState(true, false)
);
diff --git a/Source/Scene/ClassificationType.js b/Source/Scene/ClassificationType.js
index 1989b2cd63c0..259ca16ec0b0 100644
--- a/Source/Scene/ClassificationType.js
+++ b/Source/Scene/ClassificationType.js
@@ -1,7 +1,7 @@
/**
* Whether a classification affects terrain, 3D Tiles or both.
*
- * @exports ClassificationType
+ * @enum {Number}
*/
var ClassificationType = {
/**
@@ -25,9 +25,11 @@ var ClassificationType = {
* @constant
*/
BOTH: 2,
- /**
- * @private
- */
- NUMBER_OF_CLASSIFICATION_TYPES: 3,
};
+
+/**
+ * @private
+ */
+ClassificationType.NUMBER_OF_CLASSIFICATION_TYPES = 3;
+
export default Object.freeze(ClassificationType);
diff --git a/Source/Scene/ColorBlendMode.js b/Source/Scene/ColorBlendMode.js
index 95dbfed023ff..696c101a2c83 100644
--- a/Source/Scene/ColorBlendMode.js
+++ b/Source/Scene/ColorBlendMode.js
@@ -7,7 +7,7 @@ import CesiumMath from "../Core/Math.js";
* REPLACE replaces the source color with the target color
* MIX blends the source color and target color together
*
- * @exports ColorBlendMode
+ * @enum {Number}
*
* @see Model.colorBlendMode
*/
diff --git a/Source/Scene/ConditionsExpression.js b/Source/Scene/ConditionsExpression.js
index e3fa7f45bf56..37133d9e3f28 100644
--- a/Source/Scene/ConditionsExpression.js
+++ b/Source/Scene/ConditionsExpression.js
@@ -136,7 +136,7 @@ ConditionsExpression.prototype.evaluateColor = function (feature, result) {
* Returns undefined if the shader function can't be generated from this expression.
*
* @param {String} functionName Name to give to the generated function.
- * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes.
+ * @param {String} propertyNameMap Maps property variable names to shader attribute names.
* @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent.
* @param {String} returnType The return type of the generated function.
*
@@ -146,7 +146,7 @@ ConditionsExpression.prototype.evaluateColor = function (feature, result) {
*/
ConditionsExpression.prototype.getShaderFunction = function (
functionName,
- attributePrefix,
+ propertyNameMap,
shaderState,
returnType
) {
@@ -161,11 +161,11 @@ ConditionsExpression.prototype.getShaderFunction = function (
var statement = conditions[i];
var condition = statement.condition.getShaderExpression(
- attributePrefix,
+ propertyNameMap,
shaderState
);
var expression = statement.expression.getShaderExpression(
- attributePrefix,
+ propertyNameMap,
shaderState
);
diff --git a/Source/Scene/CullFace.js b/Source/Scene/CullFace.js
index 7be2cb95c7d6..ecd2676270f1 100644
--- a/Source/Scene/CullFace.js
+++ b/Source/Scene/CullFace.js
@@ -3,7 +3,7 @@ import WebGLConstants from "../Core/WebGLConstants.js";
/**
* Determines which triangles, if any, are culled.
*
- * @exports CullFace
+ * @enum {Number}
*/
var CullFace = {
/**
diff --git a/Source/Scene/DebugAppearance.js b/Source/Scene/DebugAppearance.js
index c321a41d0302..fc2c720d9a78 100644
--- a/Source/Scene/DebugAppearance.js
+++ b/Source/Scene/DebugAppearance.js
@@ -20,7 +20,7 @@ import Appearance from "./Appearance.js";
* @param {String} [options.glslDatatype='vec3'] The GLSL datatype of the attribute. Supported datatypes are float
, vec2
, vec3
, and vec4
.
* @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader.
* @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader.
- * @param {RenderState} [options.renderState] Optional render state to override the default render state.
+ * @param {Object} [options.renderState] Optional render state to override the default render state.
*
* @exception {DeveloperError} options.glslDatatype must be float, vec2, vec3, or vec4.
*
diff --git a/Source/Scene/DebugCameraPrimitive.js b/Source/Scene/DebugCameraPrimitive.js
index fef7764854f3..e7c76410acba 100644
--- a/Source/Scene/DebugCameraPrimitive.js
+++ b/Source/Scene/DebugCameraPrimitive.js
@@ -25,6 +25,7 @@ import Primitive from "./Primitive.js";
*
* @param {Object} options Object with the following properties:
* @param {Camera} options.camera The camera.
+ * @param {Number[]} [options.frustumSplits] Distances to the near and far planes of the camera frustums. This overrides the camera's frustum near and far values.
* @param {Color} [options.color=Color.CYAN] The color of the debug outline.
* @param {Boolean} [options.updateOnChange=true] Whether the primitive updates when the underlying camera changes.
* @param {Boolean} [options.show=true] Determines if this primitive will be shown.
@@ -46,6 +47,7 @@ function DebugCameraPrimitive(options) {
//>>includeEnd('debug');
this._camera = options.camera;
+ this._frustumSplits = options.frustumSplits;
this._color = defaultValue(options.color, Color.CYAN);
this._updateOnChange = defaultValue(options.updateOnChange, true);
@@ -124,13 +126,16 @@ DebugCameraPrimitive.prototype.update = function (frameState) {
}
frustum = cameraFrustum.clone(frustum);
- var frustumSplits = frameState.frustumSplits;
- var numFrustums = frustumSplits.length - 1;
- if (numFrustums <= 0) {
- frustumSplits = scratchSplits; // Use near and far planes if no splits created
+ var numFrustums;
+ var frustumSplits = this._frustumSplits;
+ if (!defined(frustumSplits) || frustumSplits.length <= 1) {
+ // Use near and far planes if no splits created
+ frustumSplits = scratchSplits;
frustumSplits[0] = this._camera.frustum.near;
frustumSplits[1] = this._camera.frustum.far;
numFrustums = 1;
+ } else {
+ numFrustums = frustumSplits.length - 1;
}
var position = camera.positionWC;
diff --git a/Source/Scene/DepthFunction.js b/Source/Scene/DepthFunction.js
index 75ca750a45cc..e84970b58ea7 100644
--- a/Source/Scene/DepthFunction.js
+++ b/Source/Scene/DepthFunction.js
@@ -3,7 +3,7 @@ import WebGLConstants from "../Core/WebGLConstants.js";
/**
* Determines the function used to compare two depths for the depth test.
*
- * @exports DepthFunction
+ * @enum {Number}
*/
var DepthFunction = {
/**
diff --git a/Source/Scene/DepthPlane.js b/Source/Scene/DepthPlane.js
index bf3f0cdbadf4..f5a37313f7ac 100644
--- a/Source/Scene/DepthPlane.js
+++ b/Source/Scene/DepthPlane.js
@@ -5,6 +5,7 @@ import defined from "../Core/defined.js";
import FeatureDetection from "../Core/FeatureDetection.js";
import Geometry from "../Core/Geometry.js";
import GeometryAttribute from "../Core/GeometryAttribute.js";
+import OrthographicFrustum from "../Core/OrthographicFrustum.js";
import PrimitiveType from "../Core/PrimitiveType.js";
import BufferUsage from "../Renderer/BufferUsage.js";
import DrawCommand from "../Renderer/DrawCommand.js";
@@ -36,69 +37,72 @@ var scratchCartesian1 = new Cartesian3();
var scratchCartesian2 = new Cartesian3();
var scratchCartesian3 = new Cartesian3();
var scratchCartesian4 = new Cartesian3();
+var scratchCartesian5 = new Cartesian3();
function computeDepthQuad(ellipsoid, frameState) {
var radii = ellipsoid.radii;
- var p = frameState.camera.positionWC;
-
- // Find the corresponding position in the scaled space of the ellipsoid.
- var q = Cartesian3.multiplyComponents(
- ellipsoid.oneOverRadii,
- p,
- scratchCartesian1
- );
-
- var qMagnitude = Cartesian3.magnitude(q);
- var qUnit = Cartesian3.normalize(q, scratchCartesian2);
-
- // Determine the east and north directions at q.
- var eUnit = Cartesian3.normalize(
- Cartesian3.cross(Cartesian3.UNIT_Z, q, scratchCartesian3),
- scratchCartesian3
- );
- var nUnit = Cartesian3.normalize(
- Cartesian3.cross(qUnit, eUnit, scratchCartesian4),
- scratchCartesian4
- );
-
- // Determine the radius of the 'limb' of the ellipsoid.
- var wMagnitude = Math.sqrt(Cartesian3.magnitudeSquared(q) - 1.0);
-
- // Compute the center and offsets.
- var center = Cartesian3.multiplyByScalar(
- qUnit,
- 1.0 / qMagnitude,
- scratchCartesian1
- );
- var scalar = wMagnitude / qMagnitude;
- var eastOffset = Cartesian3.multiplyByScalar(
- eUnit,
- scalar,
- scratchCartesian2
- );
- var northOffset = Cartesian3.multiplyByScalar(
- nUnit,
- scalar,
- scratchCartesian3
- );
+ var camera = frameState.camera;
+ var center, eastOffset, northOffset;
+
+ if (camera.frustum instanceof OrthographicFrustum) {
+ center = Cartesian3.ZERO;
+ eastOffset = camera.rightWC;
+ northOffset = camera.upWC;
+ } else {
+ var p = camera.positionWC;
+
+ // Find the corresponding position in the scaled space of the ellipsoid.
+ var q = Cartesian3.multiplyComponents(
+ ellipsoid.oneOverRadii,
+ p,
+ scratchCartesian1
+ );
+
+ var qUnit = Cartesian3.normalize(q, scratchCartesian2);
+
+ // Determine the east and north directions at q.
+ var eUnit = Cartesian3.normalize(
+ Cartesian3.cross(Cartesian3.UNIT_Z, q, scratchCartesian3),
+ scratchCartesian3
+ );
+ var nUnit = Cartesian3.normalize(
+ Cartesian3.cross(qUnit, eUnit, scratchCartesian4),
+ scratchCartesian4
+ );
+
+ var qMagnitude = Cartesian3.magnitude(q);
+
+ // Determine the radius of the 'limb' of the ellipsoid.
+ var wMagnitude = Math.sqrt(qMagnitude * qMagnitude - 1.0);
+
+ // Compute the center and offsets.
+ center = Cartesian3.multiplyByScalar(
+ qUnit,
+ 1.0 / qMagnitude,
+ scratchCartesian1
+ );
+ var scalar = wMagnitude / qMagnitude;
+ eastOffset = Cartesian3.multiplyByScalar(eUnit, scalar, scratchCartesian2);
+ northOffset = Cartesian3.multiplyByScalar(nUnit, scalar, scratchCartesian3);
+ }
// A conservative measure for the longitudes would be to use the min/max longitudes of the bounding frustum.
- var upperLeft = Cartesian3.add(center, northOffset, scratchCartesian4);
+ var upperLeft = Cartesian3.add(center, northOffset, scratchCartesian5);
Cartesian3.subtract(upperLeft, eastOffset, upperLeft);
Cartesian3.multiplyComponents(radii, upperLeft, upperLeft);
Cartesian3.pack(upperLeft, depthQuadScratch, 0);
- var lowerLeft = Cartesian3.subtract(center, northOffset, scratchCartesian4);
+ var lowerLeft = Cartesian3.subtract(center, northOffset, scratchCartesian5);
Cartesian3.subtract(lowerLeft, eastOffset, lowerLeft);
Cartesian3.multiplyComponents(radii, lowerLeft, lowerLeft);
Cartesian3.pack(lowerLeft, depthQuadScratch, 3);
- var upperRight = Cartesian3.add(center, northOffset, scratchCartesian4);
+ var upperRight = Cartesian3.add(center, northOffset, scratchCartesian5);
Cartesian3.add(upperRight, eastOffset, upperRight);
Cartesian3.multiplyComponents(radii, upperRight, upperRight);
Cartesian3.pack(upperRight, depthQuadScratch, 6);
- var lowerRight = Cartesian3.subtract(center, northOffset, scratchCartesian4);
+ var lowerRight = Cartesian3.subtract(center, northOffset, scratchCartesian5);
Cartesian3.add(lowerRight, eastOffset, lowerRight);
Cartesian3.multiplyComponents(radii, lowerRight, lowerRight);
Cartesian3.pack(lowerRight, depthQuadScratch, 9);
diff --git a/Source/Scene/DiscardEmptyTileImagePolicy.js b/Source/Scene/DiscardEmptyTileImagePolicy.js
index 40d4322ba9aa..90fb289b678f 100644
--- a/Source/Scene/DiscardEmptyTileImagePolicy.js
+++ b/Source/Scene/DiscardEmptyTileImagePolicy.js
@@ -23,7 +23,7 @@ DiscardEmptyTileImagePolicy.prototype.isReady = function () {
/**
* Given a tile image, decide whether to discard that image.
*
- * @param {Image} image An image to test.
+ * @param {HTMLImageElement} image An image to test.
* @returns {Boolean} True if the image should be discarded; otherwise, false.
*/
DiscardEmptyTileImagePolicy.prototype.shouldDiscardImage = function (image) {
@@ -35,7 +35,7 @@ var emptyImage;
Object.defineProperties(DiscardEmptyTileImagePolicy, {
/**
* Default value for representing an empty image.
- * @type {Image}
+ * @type {HTMLImageElement}
* @readonly
* @memberof DiscardEmptyTileImagePolicy
*/
diff --git a/Source/Scene/DiscardMissingTileImagePolicy.js b/Source/Scene/DiscardMissingTileImagePolicy.js
index ce7ce5dd17ac..66b5110124dc 100644
--- a/Source/Scene/DiscardMissingTileImagePolicy.js
+++ b/Source/Scene/DiscardMissingTileImagePolicy.js
@@ -104,7 +104,7 @@ DiscardMissingTileImagePolicy.prototype.isReady = function () {
/**
* Given a tile image, decide whether to discard that image.
*
- * @param {Image} image An image to test.
+ * @param {HTMLImageElement} image An image to test.
* @returns {Boolean} True if the image should be discarded; otherwise, false.
*
* @exception {DeveloperError} shouldDiscardImage
must not be called before the discard policy is ready.
diff --git a/Source/Scene/EllipsoidSurfaceAppearance.js b/Source/Scene/EllipsoidSurfaceAppearance.js
index 84f6836af07b..1457e7115551 100644
--- a/Source/Scene/EllipsoidSurfaceAppearance.js
+++ b/Source/Scene/EllipsoidSurfaceAppearance.js
@@ -24,7 +24,7 @@ import Material from "./Material.js";
* @param {Material} [options.material=Material.ColorType] The material used to determine the fragment color.
* @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader.
* @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader.
- * @param {RenderState} [options.renderState] Optional render state to override the default render state.
+ * @param {Object} [options.renderState] Optional render state to override the default render state.
*
* @see {@link https://github.com/CesiumGS/cesium/wiki/Fabric|Fabric}
*
diff --git a/Source/Scene/Expression.js b/Source/Scene/Expression.js
index 9f8582ff7f91..245238fa414f 100644
--- a/Source/Scene/Expression.js
+++ b/Source/Scene/Expression.js
@@ -171,7 +171,7 @@ Expression.prototype.evaluateColor = function (feature, result) {
* Returns undefined if the shader function can't be generated from this expression.
*
* @param {String} functionName Name to give to the generated function.
- * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes.
+ * @param {String} propertyNameMap Maps property variable names to shader attribute names.
* @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent.
* @param {String} returnType The return type of the generated function.
*
@@ -181,11 +181,11 @@ Expression.prototype.evaluateColor = function (feature, result) {
*/
Expression.prototype.getShaderFunction = function (
functionName,
- attributePrefix,
+ propertyNameMap,
shaderState,
returnType
) {
- var shaderExpression = this.getShaderExpression(attributePrefix, shaderState);
+ var shaderExpression = this.getShaderExpression(propertyNameMap, shaderState);
shaderExpression =
returnType +
@@ -205,7 +205,7 @@ Expression.prototype.getShaderFunction = function (
* Gets the shader expression for this expression.
* Returns undefined if the shader expression can't be generated from this expression.
*
- * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes.
+ * @param {String} propertyNameMap Maps property variable names to shader attribute names.
* @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent.
*
* @returns {String} The shader expression.
@@ -213,10 +213,10 @@ Expression.prototype.getShaderFunction = function (
* @private
*/
Expression.prototype.getShaderExpression = function (
- attributePrefix,
+ propertyNameMap,
shaderState
) {
- return this._runtimeAst.getShaderExpression(attributePrefix, shaderState);
+ return this._runtimeAst.getShaderExpression(propertyNameMap, shaderState);
};
var unaryOperators = ["!", "-", "+"];
@@ -1967,12 +1967,12 @@ function colorToVec4(color) {
return "vec4(" + r + ", " + g + ", " + b + ", " + a + ")";
}
-function getExpressionArray(array, attributePrefix, shaderState, parent) {
+function getExpressionArray(array, propertyNameMap, shaderState, parent) {
var length = array.length;
var expressions = new Array(length);
for (var i = 0; i < length; ++i) {
expressions[i] = array[i].getShaderExpression(
- attributePrefix,
+ propertyNameMap,
shaderState,
parent
);
@@ -1980,10 +1980,22 @@ function getExpressionArray(array, attributePrefix, shaderState, parent) {
return expressions;
}
+function getVariableName(variableName, propertyNameMap) {
+ if (!defined(propertyNameMap[variableName])) {
+ throw new RuntimeError(
+ 'Style references a property "' +
+ variableName +
+ '" that does not exist or is not styleable.'
+ );
+ }
+
+ return propertyNameMap[variableName];
+}
+
var nullSentinel = "czm_infinity"; // null just needs to be some sentinel value that will cause "[expression] === null" to be false in nearly all cases. GLSL doesn't have a NaN constant so use czm_infinity.
Node.prototype.getShaderExpression = function (
- attributePrefix,
+ propertyNameMap,
shaderState,
parent
) {
@@ -1998,28 +2010,31 @@ Node.prototype.getShaderExpression = function (
if (defined(this._left)) {
if (Array.isArray(this._left)) {
// Left can be an array if the type is LITERAL_COLOR or LITERAL_VECTOR
- left = getExpressionArray(this._left, attributePrefix, shaderState, this);
+ left = getExpressionArray(this._left, propertyNameMap, shaderState, this);
} else {
- left = this._left.getShaderExpression(attributePrefix, shaderState, this);
+ left = this._left.getShaderExpression(propertyNameMap, shaderState, this);
}
}
if (defined(this._right)) {
- right = this._right.getShaderExpression(attributePrefix, shaderState, this);
+ right = this._right.getShaderExpression(propertyNameMap, shaderState, this);
}
if (defined(this._test)) {
- test = this._test.getShaderExpression(attributePrefix, shaderState, this);
+ test = this._test.getShaderExpression(propertyNameMap, shaderState, this);
}
if (Array.isArray(this._value)) {
// For ARRAY type
- value = getExpressionArray(this._value, attributePrefix, shaderState, this);
+ value = getExpressionArray(this._value, propertyNameMap, shaderState, this);
}
switch (type) {
case ExpressionNodeType.VARIABLE:
- return attributePrefix + value;
+ if (checkFeature(this)) {
+ return undefined;
+ }
+ return getVariableName(value, propertyNameMap);
case ExpressionNodeType.UNARY:
// Supported types: +, -, !, Boolean, Number
if (value === "Boolean") {
@@ -2071,6 +2086,9 @@ Node.prototype.getShaderExpression = function (
case ExpressionNodeType.CONDITIONAL:
return "(" + test + " ? " + left + " : " + right + ")";
case ExpressionNodeType.MEMBER:
+ if (checkFeature(this._left)) {
+ return getVariableName(right, propertyNameMap);
+ }
// This is intended for accessing the components of vector properties. String members aren't supported.
// Check for 0.0 rather than 0 because all numbers are previously converted to decimals.
if (right === "r" || right === "x" || right === "0.0") {
@@ -2132,7 +2150,8 @@ Node.prototype.getShaderExpression = function (
value === "x" ||
value === "y" ||
value === "z" ||
- value === "w"
+ value === "w" ||
+ checkFeature(parent._left)
) {
return value;
}
diff --git a/Source/Scene/FrameState.js b/Source/Scene/FrameState.js
index af2d537d7074..8c5e706a8bc5 100644
--- a/Source/Scene/FrameState.js
+++ b/Source/Scene/FrameState.js
@@ -135,6 +135,14 @@ function FrameState(context, creditDisplay, jobScheduler) {
*/
this.cameraUnderground = false;
+ /**
+ * The {@link GlobeTranslucencyState} object used by the scene.
+ *
+ * @type {GlobeTranslucencyState}
+ * @default undefined
+ */
+ this.globeTranslucencyState = undefined;
+
/**
* The culling volume.
*
@@ -169,40 +177,37 @@ function FrameState(context, creditDisplay, jobScheduler) {
*/
this.pixelRatio = 1.0;
+ /**
+ * @typedef FrameState.Passes
+ * @type {Object}
+ * @property {Boolean} render true
if the primitive should update for a render pass, false
otherwise.
+ * @property {Boolean} pick true
if the primitive should update for a picking pass, false
otherwise.
+ * @property {Boolean} depth true
if the primitive should update for a depth only pass, false
otherwise.
+ * @property {Boolean} postProcess true
if the primitive should update for a per-feature post-process pass, false
otherwise.
+ * @property {Boolean} offscreen true
if the primitive should update for an offscreen pass, false
otherwise.
+ */
+
+ /**
+ * @type {FrameState.Passes}
+ */
this.passes = {
/**
- * true
if the primitive should update for a render pass, false
otherwise.
- *
- * @type {Boolean}
* @default false
*/
render: false,
-
/**
- * true
if the primitive should update for a picking pass, false
otherwise.
- *
- * @type {Boolean}
* @default false
*/
pick: false,
-
/**
- * true
if the primitive should update for a depth only pass, false
otherwise.
- * @type {Boolean}
* @default false
*/
depth: false,
-
/**
- * true
if the primitive should update for a per-feature post-process pass, false
otherwise.
- * @type {Boolean}
* @default false
*/
postProcess: false,
-
/**
- * true
if the primitive should update for an offscreen pass, false
otherwise.
- * @type {Boolean}
* @default false
*/
offscreen: false,
@@ -225,7 +230,7 @@ function FrameState(context, creditDisplay, jobScheduler) {
* directly in update
functions.
*
*
- * @type {FrameState~AfterRenderCallback[]}
+ * @type {FrameState.AfterRenderCallback[]}
*
* @example
* frameState.afterRender.push(function() {
@@ -242,33 +247,26 @@ function FrameState(context, creditDisplay, jobScheduler) {
*/
this.scene3DOnly = false;
+ /**
+ * @typedef FrameState.Fog
+ * @type {Object}
+ * @property {Boolean} enabled true
if fog is enabled, false
otherwise.
+ * @property {Number} density A positive number used to mix the color and fog color based on camera distance.
+ * @property {Number} sse A scalar used to modify the screen space error of geometry partially in fog.
+ * @property {Number} minimumBrightness The minimum brightness of terrain with fog applied.
+ */
+
+ /**
+ * @type {FrameState.Fog}
+ */
+
this.fog = {
/**
- * true
if fog is enabled, false
otherwise.
- * @type {Boolean}
* @default false
*/
enabled: false,
- /**
- * A positive number used to mix the color and fog color based on camera distance.
- *
- * @type {Number}
- * @default undefined
- */
density: undefined,
- /**
- * A scalar used to modify the screen space error of geometry partially in fog.
- *
- * @type {Number}
- * @default undefined
- */
sse: undefined,
- /**
- * The minimum brightness of terrain with fog applied.
- *
- * @type {Number}
- * @default undefined
- */
minimumBrightness: undefined,
};
@@ -279,57 +277,49 @@ function FrameState(context, creditDisplay, jobScheduler) {
*/
this.terrainExaggeration = 1.0;
- this.shadowState = {
- /**
- * Whether there are any active shadow maps this frame.
- * @type {Boolean}
- */
- shadowsEnabled: true,
+ /**
+ * @typedef FrameState.ShadowState
+ * @type {Object}
+ * @property {Boolean} shadowsEnabled Whether there are any active shadow maps this frame.
+ * @property {Boolean} lightShadowsEnabled Whether there are any active shadow maps that originate from light sources. Does not include shadow maps that are used for analytical purposes.
+ * @property {ShadowMap[]} shadowMaps All shadow maps that are enabled this frame.
+ * @property {ShadowMap[]} lightShadowMaps Shadow maps that originate from light sources. Does not include shadow maps that are used for analytical purposes. Only these shadow maps will be used to generate receive shadows shaders.
+ * @property {Number} nearPlane The near plane of the scene's frustum commands. Used for fitting cascaded shadow maps.
+ * @property {Number} farPlane The far plane of the scene's frustum commands. Used for fitting cascaded shadow maps.
+ * @property {Number} closestObjectSize The size of the bounding volume that is closest to the camera. This is used to place more shadow detail near the object.
+ * @property {Number} lastDirtyTime The time when a shadow map was last dirty
+ * @property {Boolean} outOfView Whether the shadows maps are out of view this frame
+ */
- /**
- * Whether there are any active shadow maps that originate from light sources. Does not
- * include shadow maps that are used for analytical purposes.
- */
- lightShadowsEnabled: true,
+ /**
+ * @type {FrameState.ShadowState}
+ */
+ this.shadowState = {
/**
- * All shadow maps that are enabled this frame.
+ * @default true
*/
+ shadowsEnabled: true,
shadowMaps: [],
-
- /**
- * Shadow maps that originate from light sources. Does not include shadow maps that are used for
- * analytical purposes. Only these shadow maps will be used to generate receive shadows shaders.
- */
lightShadowMaps: [],
-
/**
- * The near plane of the scene's frustum commands. Used for fitting cascaded shadow maps.
- * @type {Number}
+ * @default 1.0
*/
nearPlane: 1.0,
-
/**
- * The far plane of the scene's frustum commands. Used for fitting cascaded shadow maps.
- * @type {Number}
+ * @default 5000.0
*/
farPlane: 5000.0,
-
/**
- * The size of the bounding volume that is closest to the camera. This is used to place more shadow detail near the object.
- * @type {Number}
+ * @default 1000.0
*/
closestObjectSize: 1000.0,
-
/**
- * The time when a shadow map was last dirty
- * @type {Number}
+ * @default 0
*/
lastDirtyTime: 0,
-
/**
- * Whether the shadows maps are out of view this frame
- * @type {Boolean}
+ * @default true
*/
outOfView: true,
};
@@ -412,6 +402,6 @@ function FrameState(context, creditDisplay, jobScheduler) {
/**
* A function that will be called at the end of the frame.
*
- * @callback FrameState~AfterRenderCallback
+ * @callback FrameState.AfterRenderCallback
*/
export default FrameState;
diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js
index 39dbb29d9496..9d34422954c9 100644
--- a/Source/Scene/Globe.js
+++ b/Source/Scene/Globe.js
@@ -2,6 +2,7 @@ import BoundingSphere from "../Core/BoundingSphere.js";
import buildModuleUrl from "../Core/buildModuleUrl.js";
import Cartesian3 from "../Core/Cartesian3.js";
import Cartographic from "../Core/Cartographic.js";
+import Color from "../Core/Color.js";
import defaultValue from "../Core/defaultValue.js";
import defined from "../Core/defined.js";
import destroyObject from "../Core/destroyObject.js";
@@ -10,6 +11,7 @@ import Ellipsoid from "../Core/Ellipsoid.js";
import EllipsoidTerrainProvider from "../Core/EllipsoidTerrainProvider.js";
import Event from "../Core/Event.js";
import IntersectionTests from "../Core/IntersectionTests.js";
+import NearFarScalar from "../Core/NearFarScalar.js";
import Ray from "../Core/Ray.js";
import Rectangle from "../Core/Rectangle.js";
import Resource from "../Core/Resource.js";
@@ -21,6 +23,7 @@ import GroundAtmosphere from "../Shaders/GroundAtmosphere.js";
import when from "../ThirdParty/when.js";
import GlobeSurfaceShaderSet from "./GlobeSurfaceShaderSet.js";
import GlobeSurfaceTileProvider from "./GlobeSurfaceTileProvider.js";
+import GlobeTranslucency from "./GlobeTranslucency.js";
import ImageryLayerCollection from "./ImageryLayerCollection.js";
import QuadtreePrimitive from "./QuadtreePrimitive.js";
import SceneMode from "./SceneMode.js";
@@ -60,6 +63,16 @@ function Globe(ellipsoid) {
this._terrainProvider = terrainProvider;
this._terrainProviderChanged = new Event();
+ this._undergroundColor = Color.clone(Color.BLACK);
+ this._undergroundColorAlphaByDistance = new NearFarScalar(
+ ellipsoid.maximumRadius / 1000.0,
+ 0.0,
+ ellipsoid.maximumRadius / 5.0,
+ 1.0
+ );
+
+ this._translucency = new GlobeTranslucency();
+
makeShadersDirty(this);
/**
@@ -271,7 +284,7 @@ function Globe(ellipsoid) {
/**
* Whether to show terrain skirts. Terrain skirts are geometry extending downwards from a tile's edges used to hide seams between neighboring tiles.
- * It may be desirable to hide terrain skirts if terrain is translucent or when viewing terrain from below the surface.
+ * Skirts are always hidden when the camera is underground or translucency is enabled.
*
* @type {Boolean}
* @default true
@@ -279,7 +292,7 @@ function Globe(ellipsoid) {
this.showSkirts = true;
/**
- * Whether to cull back-facing terrain. Set this to false when viewing terrain from below the surface.
+ * Whether to cull back-facing terrain. Back faces are not culled when the camera is underground or translucency is enabled.
*
* @type {Boolean}
* @default true
@@ -374,9 +387,9 @@ Object.defineProperties(Globe.prototype, {
* A property specifying a {@link Rectangle} used to limit globe rendering to a cartographic area.
* Defaults to the maximum extent of cartographic coordinates.
*
- * @member Globe.prototype
+ * @memberof Globe.prototype
* @type {Rectangle}
- * @default Rectangle.MAX_VALUE
+ * @default {@link Rectangle.MAX_VALUE}
*/
cartographicLimitRectangle: {
get: function () {
@@ -469,6 +482,75 @@ Object.defineProperties(Globe.prototype, {
}
},
},
+
+ /**
+ * The color to render the back side of the globe when the camera is underground or the globe is translucent,
+ * blended with the globe color based on the camera's distance.
+ *
+ * To disable underground coloring, set undergroundColor
to undefined
.
+ *
+ * @memberof Globe.prototype
+ * @type {Color}
+ * @default {@link Color.BLACK}
+ *
+ * @see Globe#undergroundColorAlphaByDistance
+ */
+ undergroundColor: {
+ get: function () {
+ return this._undergroundColor;
+ },
+ set: function (value) {
+ this._undergroundColor = Color.clone(value, this._undergroundColor);
+ },
+ },
+
+ /**
+ * Gets or sets the near and far distance for blending {@link Globe#undergroundColor} with the globe color.
+ * The alpha will interpolate between the {@link NearFarScalar#nearValue} and
+ * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds
+ * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}.
+ * Outside of these ranges the alpha remains clamped to the nearest bound. If undefined,
+ * the underground color will not be blended with the globe color.
+ *
+ * When the camera is above the ellipsoid the distance is computed from the nearest
+ * point on the ellipsoid instead of the camera's position.
+ *
+ * @memberof Globe.prototype
+ * @type {NearFarScalar}
+ *
+ * @see Globe#undergroundColor
+ *
+ */
+ undergroundColorAlphaByDistance: {
+ get: function () {
+ return this._undergroundColorAlphaByDistance;
+ },
+ set: function (value) {
+ //>>includeStart('debug', pragmas.debug);
+ if (defined(value) && value.far < value.near) {
+ throw new DeveloperError(
+ "far distance must be greater than near distance."
+ );
+ }
+ //>>includeEnd('debug');
+ this._undergroundColorAlphaByDistance = NearFarScalar.clone(
+ value,
+ this._undergroundColorAlphaByDistance
+ );
+ },
+ },
+
+ /**
+ * Properties for controlling globe translucency.
+ *
+ * @memberof Globe.prototype
+ * @type {GlobeTranslucency}
+ */
+ translucency: {
+ get: function () {
+ return this._translucency;
+ },
+ },
});
function makeShadersDirty(globe) {
@@ -486,9 +568,9 @@ function makeShadersDirty(globe) {
) {
fragmentSources.push(globe._material.shaderSource);
defines.push("APPLY_MATERIAL");
- globe._surface._tileProvider.uniformMap = globe._material._uniforms;
+ globe._surface._tileProvider.materialUniformMap = globe._material._uniforms;
} else {
- globe._surface._tileProvider.uniformMap = undefined;
+ globe._surface._tileProvider.materialUniformMap = undefined;
}
fragmentSources.push(GlobeFS);
@@ -530,12 +612,18 @@ var scratchSphereIntersectionResult = {
*
* @param {Ray} ray The ray to test for intersection.
* @param {Scene} scene The scene.
+ * @param {Boolean} [cullBackFaces=true] Set to true to not pick back faces.
* @param {Cartesian3} [result] The object onto which to store the result.
* @returns {Cartesian3|undefined} The intersection or undefined
if none was found. The returned position is in projected coordinates for 2D and Columbus View.
*
* @private
*/
-Globe.prototype.pickWorldCoordinates = function (ray, scene, result) {
+Globe.prototype.pickWorldCoordinates = function (
+ ray,
+ scene,
+ cullBackFaces,
+ result
+) {
//>>includeStart('debug', pragmas.debug);
if (!defined(ray)) {
throw new DeveloperError("ray is required");
@@ -545,6 +633,8 @@ Globe.prototype.pickWorldCoordinates = function (ray, scene, result) {
}
//>>includeEnd('debug');
+ cullBackFaces = defaultValue(cullBackFaces, true);
+
var mode = scene.mode;
var projection = scene.mapProjection;
@@ -609,7 +699,7 @@ Globe.prototype.pickWorldCoordinates = function (ray, scene, result) {
ray,
scene.mode,
scene.mapProjection,
- true,
+ cullBackFaces,
result
);
if (defined(intersection)) {
@@ -635,7 +725,7 @@ var cartoScratch = new Cartographic();
* var intersection = globe.pick(ray, scene);
*/
Globe.prototype.pick = function (ray, scene, result) {
- result = this.pickWorldCoordinates(ray, scene, result);
+ result = this.pickWorldCoordinates(ray, scene, true, result);
if (defined(result) && scene.mode !== SceneMode.SCENE3D) {
result = Cartesian3.fromElements(result.y, result.z, result.x, result);
var carto = scene.mapProjection.unproject(result, cartoScratch);
@@ -868,6 +958,8 @@ Globe.prototype.beginFrame = function (frameState) {
tileProvider.fillHighlightColor = this.fillHighlightColor;
tileProvider.showSkirts = this.showSkirts;
tileProvider.backFaceCulling = this.backFaceCulling;
+ tileProvider.undergroundColor = this._undergroundColor;
+ tileProvider.undergroundColorAlphaByDistance = this._undergroundColorAlphaByDistance;
surface.beginFrame(frameState);
}
};
diff --git a/Source/Scene/GlobeSurfaceShaderSet.js b/Source/Scene/GlobeSurfaceShaderSet.js
index c96f89c2a6ac..df662a8f69c2 100644
--- a/Source/Scene/GlobeSurfaceShaderSet.js
+++ b/Source/Scene/GlobeSurfaceShaderSet.js
@@ -80,6 +80,7 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
var applySaturation = options.applySaturation;
var applyGamma = options.applyGamma;
var applyAlpha = options.applyAlpha;
+ var applyDayNightAlpha = options.applyDayNightAlpha;
var applySplit = options.applySplit;
var showReflectiveOcean = options.showReflectiveOcean;
var showOceanWaves = options.showOceanWaves;
@@ -99,6 +100,8 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
var colorCorrect = options.colorCorrect;
var highlightFillTile = options.highlightFillTile;
var colorToAlpha = options.colorToAlpha;
+ var showUndergroundColor = options.showUndergroundColor;
+ var translucent = options.translucent;
var quantization = 0;
var quantizationDefine = "";
@@ -151,7 +154,10 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
(imageryCutoutFlag << 22) |
(colorCorrect << 23) |
(highlightFillTile << 24) |
- (colorToAlpha << 25);
+ (colorToAlpha << 25) |
+ (showUndergroundColor << 26) |
+ (translucent << 27) |
+ (applyDayNightAlpha << 28);
var currentClippingShaderState = 0;
if (defined(clippingPlanes) && clippingPlanes.length > 0) {
@@ -217,6 +223,9 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
if (applyAlpha) {
fs.defines.push("APPLY_ALPHA");
}
+ if (applyDayNightAlpha) {
+ fs.defines.push("APPLY_DAY_NIGHT_ALPHA");
+ }
if (showReflectiveOcean) {
fs.defines.push("SHOW_REFLECTIVE_OCEAN");
vs.defines.push("SHOW_REFLECTIVE_OCEAN");
@@ -227,7 +236,14 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
if (colorToAlpha) {
fs.defines.push("APPLY_COLOR_TO_ALPHA");
}
-
+ if (showUndergroundColor) {
+ vs.defines.push("UNDERGROUND_COLOR");
+ fs.defines.push("UNDERGROUND_COLOR");
+ }
+ if (translucent) {
+ vs.defines.push("TRANSLUCENT");
+ fs.defines.push("TRANSLUCENT");
+ }
if (enableLighting) {
if (hasVertexNormals) {
vs.defines.push("ENABLE_VERTEX_LIGHTING");
@@ -279,7 +295,7 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
var computeDayColor =
"\
- vec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates)\n\
+ vec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates, float nightBlend)\n\
{\n\
vec4 color = initialColor;\n";
@@ -322,6 +338,10 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
(applyAlpha ? "u_dayTextureAlpha[" + i + "]" : "1.0") +
",\n\
" +
+ (applyDayNightAlpha ? "u_dayTextureNightAlpha[" + i + "]" : "1.0") +
+ ",\n" +
+ (applyDayNightAlpha ? "u_dayTextureDayAlpha[" + i + "]" : "1.0") +
+ ",\n" +
(applyBrightness ? "u_dayTextureBrightness[" + i + "]" : "0.0") +
",\n\
" +
@@ -341,7 +361,8 @@ GlobeSurfaceShaderSet.prototype.getShaderProgram = function (options) {
",\n\
" +
(colorToAlpha ? "u_colorsToAlpha[" + i + "]" : "vec4(0.0)") +
- "\n\
+ ",\n\
+ nightBlend\
);\n";
if (hasImageryLayerCutout) {
computeDayColor +=
diff --git a/Source/Scene/GlobeSurfaceTileProvider.js b/Source/Scene/GlobeSurfaceTileProvider.js
index 2f43ecd92c3a..fe9e2bc7eed9 100644
--- a/Source/Scene/GlobeSurfaceTileProvider.js
+++ b/Source/Scene/GlobeSurfaceTileProvider.js
@@ -19,6 +19,7 @@ import IndexDatatype from "../Core/IndexDatatype.js";
import Intersect from "../Core/Intersect.js";
import CesiumMath from "../Core/Math.js";
import Matrix4 from "../Core/Matrix4.js";
+import NearFarScalar from "../Core/NearFarScalar.js";
import OrientedBoundingBox from "../Core/OrientedBoundingBox.js";
import OrthographicFrustum from "../Core/OrthographicFrustum.js";
import PrimitiveType from "../Core/PrimitiveType.js";
@@ -104,6 +105,11 @@ function GlobeSurfaceTileProvider(options) {
this.showSkirts = true;
this.backFaceCulling = true;
+ this.undergroundColor = undefined;
+ this.undergroundColorAlphaByDistance = undefined;
+
+ this.materialUniformMap = undefined;
+ this._materialUniformMap = undefined;
this._quadtree = undefined;
this._terrainProvider = options.terrainProvider;
@@ -484,6 +490,20 @@ GlobeSurfaceTileProvider.prototype.endUpdate = function (frameState) {
}
};
+function pushCommand(command, frameState) {
+ var globeTranslucencyState = frameState.globeTranslucencyState;
+ if (globeTranslucencyState.translucent) {
+ var isBlendCommand = command.renderState.blending.enabled;
+ globeTranslucencyState.pushDerivedCommands(
+ command,
+ isBlendCommand,
+ frameState
+ );
+ } else {
+ frameState.commandList.push(command);
+ }
+}
+
/**
* Adds draw commands for tiles rendered in the previous frame for a pick pass.
*
@@ -493,7 +513,7 @@ GlobeSurfaceTileProvider.prototype.updateForPick = function (frameState) {
// Add the tile pick commands from the tiles drawn last frame.
var drawCommands = this._drawCommands;
for (var i = 0, length = this._usedDrawCommands; i < length; ++i) {
- frameState.commandList.push(drawCommands[i]);
+ pushCommand(drawCommands[i], frameState);
}
};
@@ -599,6 +619,36 @@ function clipRectangleAntimeridian(tileRectangle, cartographicLimitRectangle) {
return splitRectangle;
}
+function isUndergroundVisible(tileProvider, frameState) {
+ if (frameState.cameraUnderground) {
+ return true;
+ }
+
+ if (frameState.globeTranslucencyState.translucent) {
+ return true;
+ }
+
+ if (tileProvider.backFaceCulling) {
+ return false;
+ }
+
+ var clippingPlanes = tileProvider._clippingPlanes;
+ if (defined(clippingPlanes) && clippingPlanes.enabled) {
+ return true;
+ }
+
+ if (
+ !Rectangle.equals(
+ tileProvider.cartographicLimitRectangle,
+ Rectangle.MAX_VALUE
+ )
+ ) {
+ return true;
+ }
+
+ return false;
+}
+
/**
* Determines the visibility of a given tile. The tile may be fully visible, partially visible, or not
* visible at all. Tiles that are renderable and are at least partially visible will be shown by a call
@@ -618,7 +668,9 @@ GlobeSurfaceTileProvider.prototype.computeTileVisibility = function (
var distance = this.computeDistanceToTile(tile, frameState);
tile._distance = distance;
- if (frameState.fog.enabled && !frameState.cameraUnderground) {
+ var undergroundVisible = isUndergroundVisible(this, frameState);
+
+ if (frameState.fog.enabled && !undergroundVisible) {
if (CesiumMath.fog(distance, frameState.fog.density) >= 1.0) {
// Tile is completely in fog so return that it is not visible.
return Visibility.NONE;
@@ -713,7 +765,7 @@ GlobeSurfaceTileProvider.prototype.computeTileVisibility = function (
frameState.mode === SceneMode.SCENE3D &&
!ortho3D &&
defined(occluders) &&
- !frameState.cameraUnderground
+ !undergroundVisible
) {
var occludeePointInScaledSpace = surfaceTile.occludeePointInScaledSpace;
if (!defined(occludeePointInScaledSpace)) {
@@ -925,6 +977,7 @@ var modifiedModelViewScratch = new Matrix4();
var modifiedModelViewProjectionScratch = new Matrix4();
var tileRectangleScratch = new Cartesian4();
var localizedCartographicLimitRectangleScratch = new Cartesian4();
+var localizedTranslucencyRectangleScratch = new Cartesian4();
var rtcScratch = new Cartesian3();
var centerEyeScratch = new Cartesian3();
var southwestScratch = new Cartesian3();
@@ -1507,6 +1560,12 @@ function createTileUniformMap(frameState, globeSurfaceTileProvider) {
u_dayTextureAlpha: function () {
return this.properties.dayTextureAlpha;
},
+ u_dayTextureNightAlpha: function () {
+ return this.properties.dayTextureNightAlpha;
+ },
+ u_dayTextureDayAlpha: function () {
+ return this.properties.dayTextureDayAlpha;
+ },
u_dayTextureBrightness: function () {
return this.properties.dayTextureBrightness;
},
@@ -1584,6 +1643,21 @@ function createTileUniformMap(frameState, globeSurfaceTileProvider) {
u_colorsToAlpha: function () {
return this.properties.colorsToAlpha;
},
+ u_frontFaceAlphaByDistance: function () {
+ return this.properties.frontFaceAlphaByDistance;
+ },
+ u_backFaceAlphaByDistance: function () {
+ return this.properties.backFaceAlphaByDistance;
+ },
+ u_translucencyRectangle: function () {
+ return this.properties.localizedTranslucencyRectangle;
+ },
+ u_undergroundColor: function () {
+ return this.properties.undergroundColor;
+ },
+ u_undergroundColorAlphaByDistance: function () {
+ return this.properties.undergroundColorAlphaByDistance;
+ },
// make a separate object so that changes to the properties are seen on
// derived commands that combine another uniform map with this one.
@@ -1606,6 +1680,8 @@ function createTileUniformMap(frameState, globeSurfaceTileProvider) {
dayTextureTexCoordsRectangle: [],
dayTextureUseWebMercatorT: [],
dayTextureAlpha: [],
+ dayTextureNightAlpha: [],
+ dayTextureDayAlpha: [],
dayTextureBrightness: [],
dayTextureContrast: [],
dayTextureHue: [],
@@ -1628,9 +1704,19 @@ function createTileUniformMap(frameState, globeSurfaceTileProvider) {
clippingPlanesEdgeWidth: 0.0,
localizedCartographicLimitRectangle: new Cartesian4(),
+
+ frontFaceAlphaByDistance: new Cartesian4(),
+ backFaceAlphaByDistance: new Cartesian4(),
+ localizedTranslucencyRectangle: new Cartesian4(),
+ undergroundColor: Color.clone(Color.TRANSPARENT),
+ undergroundColorAlphaByDistance: new Cartesian4(),
},
};
+ if (defined(globeSurfaceTileProvider.materialUniformMap)) {
+ return combine(uniformMap, globeSurfaceTileProvider.materialUniformMap);
+ }
+
return uniformMap;
}
@@ -1802,6 +1888,7 @@ var surfaceShaderSetOptionsScratch = {
applySaturation: undefined,
applyGamma: undefined,
applyAlpha: undefined,
+ applyDayNightAlpha: undefined,
applySplit: undefined,
showReflectiveOcean: undefined,
showOceanWaves: undefined,
@@ -1821,6 +1908,9 @@ var surfaceShaderSetOptionsScratch = {
colorToAlpha: undefined,
};
+var defaultUndergroundColor = Color.TRANSPARENT;
+var defaultundergroundColorAlphaByDistance = new NearFarScalar();
+
function addDrawCommandsForTile(tileProvider, tile, frameState) {
var surfaceTile = tile.data;
@@ -1860,6 +1950,28 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
var cameraUnderground = frameState.cameraUnderground;
+ var globeTranslucencyState = frameState.globeTranslucencyState;
+ var translucent = globeTranslucencyState.translucent;
+ var frontFaceAlphaByDistance =
+ globeTranslucencyState.frontFaceAlphaByDistance;
+ var backFaceAlphaByDistance = globeTranslucencyState.backFaceAlphaByDistance;
+ var translucencyRectangle = globeTranslucencyState.rectangle;
+
+ var undergroundColor = defaultValue(
+ tileProvider.undergroundColor,
+ defaultUndergroundColor
+ );
+ var undergroundColorAlphaByDistance = defaultValue(
+ tileProvider.undergroundColorAlphaByDistance,
+ defaultundergroundColorAlphaByDistance
+ );
+ var showUndergroundColor =
+ isUndergroundVisible(tileProvider, frameState) &&
+ frameState.mode === SceneMode.SCENE3D &&
+ undergroundColor.alpha > 0.0 &&
+ (undergroundColorAlphaByDistance.nearValue > 0.0 ||
+ undergroundColorAlphaByDistance.farValue > 0.0);
+
var showReflectiveOcean =
tileProvider.hasWaterMask && defined(waterMaskTexture);
var oceanNormalMap = tileProvider.oceanNormalMap;
@@ -1868,9 +1980,12 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
tileProvider.terrainProvider.ready &&
tileProvider.terrainProvider.hasVertexNormals;
var enableFog = frameState.fog.enabled && !cameraUnderground;
- var showGroundAtmosphere = tileProvider.showGroundAtmosphere;
- var castShadows = ShadowMode.castShadows(tileProvider.shadows);
- var receiveShadows = ShadowMode.receiveShadows(tileProvider.shadows);
+ var showGroundAtmosphere =
+ tileProvider.showGroundAtmosphere && frameState.mode === SceneMode.SCENE3D;
+ var castShadows =
+ ShadowMode.castShadows(tileProvider.shadows) && !translucent;
+ var receiveShadows =
+ ShadowMode.receiveShadows(tileProvider.shadows) && !translucent;
var hueShift = tileProvider.hueShift;
var saturationShift = tileProvider.saturationShift;
@@ -1884,18 +1999,8 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
var perFragmentGroundAtmosphere = false;
if (showGroundAtmosphere) {
- var mode = frameState.mode;
- var camera = frameState.camera;
- var cameraDistance;
- if (mode === SceneMode.SCENE2D || mode === SceneMode.COLUMBUS_VIEW) {
- cameraDistance = camera.positionCartographic.height;
- } else {
- cameraDistance = Cartesian3.magnitude(camera.positionWC);
- }
+ var cameraDistance = Cartesian3.magnitude(frameState.camera.positionWC);
var fadeOutDistance = tileProvider.nightFadeOutDistance;
- if (mode !== SceneMode.SCENE3D) {
- fadeOutDistance -= frameState.mapProjection.ellipsoid.maximumRadius;
- }
perFragmentGroundAtmosphere = cameraDistance > fadeOutDistance;
}
@@ -1905,7 +2010,6 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
if (showOceanWaves) {
--maxTextures;
}
-
if (
defined(frameState.shadowState) &&
frameState.shadowState.shadowsEnabled
@@ -1919,6 +2023,8 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
--maxTextures;
}
+ maxTextures -= globeTranslucencyState.numberOfTextureUniforms;
+
var mesh = surfaceTile.renderedMesh;
var rtc = mesh.center;
var encoding = mesh.encoding;
@@ -2016,8 +2122,10 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
var imageryIndex = 0;
var imageryLen = tileImageryCollection.length;
- var showSkirts = tileProvider.showSkirts && !cameraUnderground;
- var backFaceCulling = tileProvider.backFaceCulling && !cameraUnderground;
+ var showSkirts =
+ tileProvider.showSkirts && !cameraUnderground && !translucent;
+ var backFaceCulling =
+ tileProvider.backFaceCulling && !cameraUnderground && !translucent;
var firstPassRenderState = backFaceCulling
? tileProvider._renderState
: tileProvider._disableCullingRenderState;
@@ -2034,6 +2142,19 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
debugDestroyPrimitive();
}
+ var materialUniformMapChanged =
+ tileProvider._materialUniformMap !== tileProvider.materialUniformMap;
+ if (materialUniformMapChanged) {
+ tileProvider._materialUniformMap = tileProvider.materialUniformMap;
+ var drawCommandsLength = tileProvider._drawCommands.length;
+ for (var i = 0; i < drawCommandsLength; ++i) {
+ tileProvider._uniformMaps[i] = createTileUniformMap(
+ frameState,
+ tileProvider
+ );
+ }
+ }
+
do {
var numberOfDayTextures = 0;
@@ -2087,6 +2208,39 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
uniformMapProperties.zoomedOutOceanSpecularIntensity =
tileProvider.zoomedOutOceanSpecularIntensity;
+ var frontFaceAlphaByDistanceFinal = cameraUnderground
+ ? backFaceAlphaByDistance
+ : frontFaceAlphaByDistance;
+ var backFaceAlphaByDistanceFinal = cameraUnderground
+ ? frontFaceAlphaByDistance
+ : backFaceAlphaByDistance;
+
+ if (defined(frontFaceAlphaByDistanceFinal)) {
+ Cartesian4.fromElements(
+ frontFaceAlphaByDistanceFinal.near,
+ frontFaceAlphaByDistanceFinal.nearValue,
+ frontFaceAlphaByDistanceFinal.far,
+ frontFaceAlphaByDistanceFinal.farValue,
+ uniformMapProperties.frontFaceAlphaByDistance
+ );
+ Cartesian4.fromElements(
+ backFaceAlphaByDistanceFinal.near,
+ backFaceAlphaByDistanceFinal.nearValue,
+ backFaceAlphaByDistanceFinal.far,
+ backFaceAlphaByDistanceFinal.farValue,
+ uniformMapProperties.backFaceAlphaByDistance
+ );
+ }
+
+ Cartesian4.fromElements(
+ undergroundColorAlphaByDistance.near,
+ undergroundColorAlphaByDistance.nearValue,
+ undergroundColorAlphaByDistance.far,
+ undergroundColorAlphaByDistance.farValue,
+ uniformMapProperties.undergroundColorAlphaByDistance
+ );
+ Color.clone(undergroundColor, uniformMapProperties.undergroundColor);
+
var highlightFillTile =
!defined(surfaceTile.vertexArray) &&
defined(tileProvider.fillHighlightColor) &&
@@ -2114,6 +2268,12 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
tileProvider.cartographicLimitRectangle
);
+ var localizedTranslucencyRectangle = localizedTranslucencyRectangleScratch;
+ var clippedTranslucencyRectangle = clipRectangleAntimeridian(
+ tile.rectangle,
+ translucencyRectangle
+ );
+
Cartesian3.fromElements(
hueShift,
saturationShift,
@@ -2142,6 +2302,24 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
uniformMapProperties.localizedCartographicLimitRectangle
);
+ localizedTranslucencyRectangle.x =
+ (clippedTranslucencyRectangle.west - cartographicTileRectangle.west) *
+ inverseTileWidth;
+ localizedTranslucencyRectangle.y =
+ (clippedTranslucencyRectangle.south - cartographicTileRectangle.south) *
+ inverseTileHeight;
+ localizedTranslucencyRectangle.z =
+ (clippedTranslucencyRectangle.east - cartographicTileRectangle.west) *
+ inverseTileWidth;
+ localizedTranslucencyRectangle.w =
+ (clippedTranslucencyRectangle.north - cartographicTileRectangle.south) *
+ inverseTileHeight;
+
+ Cartesian4.clone(
+ localizedTranslucencyRectangle,
+ uniformMapProperties.localizedTranslucencyRectangle
+ );
+
// For performance, use fog in the shader only when the tile is in fog.
var applyFog =
enableFog &&
@@ -2155,6 +2333,7 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
var applySaturation = false;
var applyGamma = false;
var applyAlpha = false;
+ var applyDayNightAlpha = false;
var applySplit = false;
var applyCutout = false;
var applyColorToAlpha = false;
@@ -2211,6 +2390,18 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
applyAlpha ||
uniformMapProperties.dayTextureAlpha[numberOfDayTextures] !== 1.0;
+ uniformMapProperties.dayTextureNightAlpha[numberOfDayTextures] =
+ imageryLayer.nightAlpha;
+ applyDayNightAlpha =
+ applyDayNightAlpha ||
+ uniformMapProperties.dayTextureNightAlpha[numberOfDayTextures] !== 1.0;
+
+ uniformMapProperties.dayTextureDayAlpha[numberOfDayTextures] =
+ imageryLayer.dayAlpha;
+ applyDayNightAlpha =
+ applyDayNightAlpha ||
+ uniformMapProperties.dayTextureDayAlpha[numberOfDayTextures] !== 1.0;
+
uniformMapProperties.dayTextureBrightness[numberOfDayTextures] =
imageryLayer.brightness;
applyBrightness =
@@ -2351,10 +2542,6 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
uniformMapProperties.clippingPlanesEdgeWidth = clippingPlanes.edgeWidth;
}
- if (defined(tileProvider.uniformMap)) {
- uniformMap = combine(uniformMap, tileProvider.uniformMap);
- }
-
surfaceShaderSetOptions.numberOfDayTextures = numberOfDayTextures;
surfaceShaderSetOptions.applyBrightness = applyBrightness;
surfaceShaderSetOptions.applyContrast = applyContrast;
@@ -2362,6 +2549,7 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
surfaceShaderSetOptions.applySaturation = applySaturation;
surfaceShaderSetOptions.applyGamma = applyGamma;
surfaceShaderSetOptions.applyAlpha = applyAlpha;
+ surfaceShaderSetOptions.applyDayNightAlpha = applyDayNightAlpha;
surfaceShaderSetOptions.applySplit = applySplit;
surfaceShaderSetOptions.enableFog = applyFog;
surfaceShaderSetOptions.enableClippingPlanes = clippingPlanesEnabled;
@@ -2370,6 +2558,8 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
surfaceShaderSetOptions.colorCorrect = colorCorrect;
surfaceShaderSetOptions.highlightFillTile = highlightFillTile;
surfaceShaderSetOptions.colorToAlpha = applyColorToAlpha;
+ surfaceShaderSetOptions.showUndergroundColor = showUndergroundColor;
+ surfaceShaderSetOptions.translucent = translucent;
var count = surfaceTile.renderedMesh.indices.length;
if (!showSkirts) {
@@ -2436,7 +2626,12 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
}
command.dirty = true;
- frameState.commandList.push(command);
+
+ if (translucent) {
+ globeTranslucencyState.updateDerivedCommands(command, frameState);
+ }
+
+ pushCommand(command, frameState);
renderState = otherPassesRenderState;
initialColor = otherPassesInitialColor;
diff --git a/Source/Scene/GlobeTranslucency.js b/Source/Scene/GlobeTranslucency.js
new file mode 100644
index 000000000000..85a6db5bcbb2
--- /dev/null
+++ b/Source/Scene/GlobeTranslucency.js
@@ -0,0 +1,239 @@
+import Check from "../Core/Check.js";
+import defined from "../Core/defined.js";
+import DeveloperError from "../Core/DeveloperError.js";
+import NearFarScalar from "../Core/NearFarScalar.js";
+import Rectangle from "../Core/Rectangle.js";
+
+/**
+ * Properties for controlling globe translucency.
+ *
+ * @alias GlobeTranslucency
+ * @constructor
+ */
+function GlobeTranslucency() {
+ this._enabled = false;
+ this._frontFaceAlpha = 1.0;
+ this._frontFaceAlphaByDistance = undefined;
+ this._backFaceAlpha = 1.0;
+ this._backFaceAlphaByDistance = undefined;
+ this._rectangle = Rectangle.clone(Rectangle.MAX_VALUE);
+}
+
+Object.defineProperties(GlobeTranslucency.prototype, {
+ /**
+ * When true, the globe is rendered as a translucent surface.
+ *
+ * The alpha is computed by blending {@link Globe#material}, {@link Globe#imageryLayers},
+ * and {@link Globe#baseColor}, all of which may contain translucency, and then multiplying by
+ * {@link GlobeTranslucency#frontFaceAlpha} and {@link GlobeTranslucency#frontFaceAlphaByDistance} for front faces and
+ * {@link GlobeTranslucency#backFaceAlpha} and {@link GlobeTranslucency#backFaceAlphaByDistance} for back faces.
+ * When the camera is underground back faces and front faces are swapped, i.e. back-facing geometry
+ * is considered front facing.
+ *
+ * Translucency is disabled by default.
+ *
+ * @memberof GlobeTranslucency.prototype
+ *
+ * @type {Boolean}
+ * @default false
+ *
+ * @see GlobeTranslucency#frontFaceAlpha
+ * @see GlobeTranslucency#frontFaceAlphaByDistance
+ * @see GlobeTranslucency#backFaceAlpha
+ * @see GlobeTranslucency#backFaceAlphaByDistance
+ */
+ enabled: {
+ get: function () {
+ return this._enabled;
+ },
+ set: function (value) {
+ //>>includeStart('debug', pragmas.debug);
+ Check.typeOf.bool("enabled", value);
+ //>>includeEnd('debug');
+ this._enabled = value;
+ },
+ },
+
+ /**
+ * A constant translucency to apply to front faces of the globe.
+ *
+ * {@link GlobeTranslucency#enabled} must be set to true for this option to take effect.
+ *
+ * @memberof GlobeTranslucency.prototype
+ *
+ * @type {Number}
+ * @default 1.0
+ *
+ * @see GlobeTranslucency#enabled
+ * @see GlobeTranslucency#frontFaceAlphaByDistance
+ *
+ * @example
+ * // Set front face translucency to 0.5.
+ * globe.translucency.frontFaceAlpha = 0.5;
+ * globe.translucency.enabled = true;
+ */
+ frontFaceAlpha: {
+ get: function () {
+ return this._frontFaceAlpha;
+ },
+ set: function (value) {
+ //>>includeStart('debug', pragmas.debug);
+ Check.typeOf.number.greaterThanOrEquals("frontFaceAlpha", value, 0.0);
+ Check.typeOf.number.lessThanOrEquals("frontFaceAlpha", value, 1.0);
+ //>>includeEnd('debug');
+ this._frontFaceAlpha = value;
+ },
+ },
+ /**
+ * Gets or sets near and far translucency properties of front faces of the globe based on the distance to the camera.
+ * The translucency will interpolate between the {@link NearFarScalar#nearValue} and
+ * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds
+ * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}.
+ * Outside of these ranges the translucency remains clamped to the nearest bound. If undefined,
+ * frontFaceAlphaByDistance will be disabled.
+ *
+ * {@link GlobeTranslucency#enabled} must be set to true for this option to take effect.
+ *
+ * @memberof GlobeTranslucency.prototype
+ *
+ * @type {NearFarScalar}
+ * @default undefined
+ *
+ * @see GlobeTranslucency#enabled
+ * @see GlobeTranslucency#frontFaceAlpha
+ *
+ * @example
+ * // Example 1.
+ * // Set front face translucency to 0.5 when the
+ * // camera is 1500 meters from the surface and 1.0
+ * // as the camera distance approaches 8.0e6 meters.
+ * globe.translucency.frontFaceAlphaByDistance = new Cesium.NearFarScalar(1.5e2, 0.5, 8.0e6, 1.0);
+ * globe.translucency.enabled = true;
+ *
+ * @example
+ * // Example 2.
+ * // Disable front face translucency by distance
+ * globe.translucency.frontFaceAlphaByDistance = undefined;
+ */
+ frontFaceAlphaByDistance: {
+ get: function () {
+ return this._frontFaceAlphaByDistance;
+ },
+ set: function (value) {
+ //>>includeStart('debug', pragmas.debug);
+ if (defined(value) && value.far < value.near) {
+ throw new DeveloperError(
+ "far distance must be greater than near distance."
+ );
+ }
+ //>>includeEnd('debug');
+ this._frontFaceAlphaByDistance = NearFarScalar.clone(
+ value,
+ this._frontFaceAlphaByDistance
+ );
+ },
+ },
+
+ /**
+ * A constant translucency to apply to back faces of the globe.
+ *
+ * {@link GlobeTranslucency#enabled} must be set to true for this option to take effect.
+ *
+ * @memberof GlobeTranslucency.prototype
+ *
+ * @type {Number}
+ * @default 1.0
+ *
+ * @see GlobeTranslucency#enabled
+ * @see GlobeTranslucency#backFaceAlphaByDistance
+ *
+ * @example
+ * // Set back face translucency to 0.5.
+ * globe.translucency.backFaceAlpha = 0.5;
+ * globe.translucency.enabled = true;
+ */
+ backFaceAlpha: {
+ get: function () {
+ return this._backFaceAlpha;
+ },
+ set: function (value) {
+ //>>includeStart('debug', pragmas.debug);
+ Check.typeOf.number.greaterThanOrEquals("backFaceAlpha", value, 0.0);
+ Check.typeOf.number.lessThanOrEquals("backFaceAlpha", value, 1.0);
+ //>>includeEnd('debug');
+ this._backFaceAlpha = value;
+ },
+ },
+ /**
+ * Gets or sets near and far translucency properties of back faces of the globe based on the distance to the camera.
+ * The translucency will interpolate between the {@link NearFarScalar#nearValue} and
+ * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds
+ * of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}.
+ * Outside of these ranges the translucency remains clamped to the nearest bound. If undefined,
+ * backFaceAlphaByDistance will be disabled.
+ *
+ * {@link GlobeTranslucency#enabled} must be set to true for this option to take effect.
+ *
+ * @memberof GlobeTranslucency.prototype
+ *
+ * @type {NearFarScalar}
+ * @default undefined
+ *
+ * @see GlobeTranslucency#enabled
+ * @see GlobeTranslucency#backFaceAlpha
+ *
+ * @example
+ * // Example 1.
+ * // Set back face translucency to 0.5 when the
+ * // camera is 1500 meters from the surface and 1.0
+ * // as the camera distance approaches 8.0e6 meters.
+ * globe.translucency.backFaceAlphaByDistance = new Cesium.NearFarScalar(1.5e2, 0.5, 8.0e6, 1.0);
+ * globe.translucency.enabled = true;
+ *
+ * @example
+ * // Example 2.
+ * // Disable back face translucency by distance
+ * globe.translucency.backFaceAlphaByDistance = undefined;
+ */
+ backFaceAlphaByDistance: {
+ get: function () {
+ return this._backFaceAlphaByDistance;
+ },
+ set: function (value) {
+ //>>includeStart('debug', pragmas.debug);
+ if (defined(value) && value.far < value.near) {
+ throw new DeveloperError(
+ "far distance must be greater than near distance."
+ );
+ }
+ //>>includeEnd('debug');
+ this._backFaceAlphaByDistance = NearFarScalar.clone(
+ value,
+ this._backFaceAlphaByDistance
+ );
+ },
+ },
+
+ /**
+ * A property specifying a {@link Rectangle} used to limit translucency to a cartographic area.
+ * Defaults to the maximum extent of cartographic coordinates.
+ *
+ * @memberof GlobeTranslucency.prototype
+ *
+ * @type {Rectangle}
+ * @default {@link Rectangle.MAX_VALUE}
+ */
+ rectangle: {
+ get: function () {
+ return this._rectangle;
+ },
+ set: function (value) {
+ if (!defined(value)) {
+ value = Rectangle.clone(Rectangle.MAX_VALUE);
+ }
+ Rectangle.clone(value, this._rectangle);
+ },
+ },
+});
+
+export default GlobeTranslucency;
diff --git a/Source/Scene/GlobeTranslucencyFramebuffer.js b/Source/Scene/GlobeTranslucencyFramebuffer.js
new file mode 100644
index 000000000000..1d280dfc7215
--- /dev/null
+++ b/Source/Scene/GlobeTranslucencyFramebuffer.js
@@ -0,0 +1,259 @@
+import BoundingRectangle from "../Core/BoundingRectangle.js";
+import Color from "../Core/Color.js";
+import defined from "../Core/defined.js";
+import destroyObject from "../Core/destroyObject.js";
+import PixelFormat from "../Core/PixelFormat.js";
+import ClearCommand from "../Renderer/ClearCommand.js";
+import Framebuffer from "../Renderer/Framebuffer.js";
+import PixelDatatype from "../Renderer/PixelDatatype.js";
+import Renderbuffer from "../Renderer/Renderbuffer.js";
+import RenderbufferFormat from "../Renderer/RenderbufferFormat.js";
+import RenderState from "../Renderer/RenderState.js";
+import Sampler from "../Renderer/Sampler.js";
+import Texture from "../Renderer/Texture.js";
+import PassThroughDepth from "../Shaders/PostProcessStages/PassThroughDepth.js";
+
+/**
+ * @private
+ */
+function GlobeTranslucencyFramebuffer() {
+ this._colorTexture = undefined;
+ this._depthStencilTexture = undefined;
+ this._depthStencilRenderbuffer = undefined;
+ this._framebuffer = undefined;
+
+ this._packedDepthTexture = undefined;
+ this._packedDepthFramebuffer = undefined;
+
+ this._renderState = undefined;
+
+ this._packedDepthCommand = undefined;
+ this._clearCommand = undefined;
+
+ this._viewport = new BoundingRectangle();
+ this._useScissorTest = false;
+ this._scissorRectangle = undefined;
+ this._useHdr = undefined;
+}
+
+Object.defineProperties(GlobeTranslucencyFramebuffer.prototype, {
+ classificationTexture: {
+ get: function () {
+ return this._colorTexture;
+ },
+ },
+ classificationFramebuffer: {
+ get: function () {
+ return this._framebuffer;
+ },
+ },
+});
+
+function destroyResources(globeTranslucency) {
+ globeTranslucency._colorTexture =
+ globeTranslucency._colorTexture &&
+ !globeTranslucency._colorTexture.isDestroyed() &&
+ globeTranslucency._colorTexture.destroy();
+ globeTranslucency._depthStencilTexture =
+ globeTranslucency._depthStencilTexture &&
+ !globeTranslucency._depthStencilTexture.isDestroyed() &&
+ globeTranslucency._depthStencilTexture.destroy();
+ globeTranslucency._depthStencilRenderbuffer =
+ globeTranslucency._depthStencilRenderbuffer &&
+ !globeTranslucency._depthStencilRenderbuffer.isDestroyed() &&
+ globeTranslucency._depthStencilRenderbuffer.destroy();
+ globeTranslucency._framebuffer =
+ globeTranslucency._framebuffer &&
+ !globeTranslucency._framebuffer.isDestroyed() &&
+ globeTranslucency._framebuffer.destroy();
+ globeTranslucency._packedDepthTexture =
+ globeTranslucency._packedDepthTexture &&
+ !globeTranslucency._packedDepthTexture.isDestroyed() &&
+ globeTranslucency._packedDepthTexture.destroy();
+ globeTranslucency._packedDepthFramebuffer =
+ globeTranslucency._packedDepthFramebuffer &&
+ !globeTranslucency._packedDepthFramebuffer.isDestroyed() &&
+ globeTranslucency._packedDepthFramebuffer.destroy();
+}
+
+function createResources(globeTranslucency, context, width, height, hdr) {
+ var pixelDatatype = hdr
+ ? context.halfFloatingPointTexture
+ ? PixelDatatype.HALF_FLOAT
+ : PixelDatatype.FLOAT
+ : PixelDatatype.UNSIGNED_BYTE;
+ globeTranslucency._colorTexture = new Texture({
+ context: context,
+ width: width,
+ height: height,
+ pixelFormat: PixelFormat.RGBA,
+ pixelDatatype: pixelDatatype,
+ sampler: Sampler.NEAREST,
+ });
+
+ if (context.depthTexture) {
+ globeTranslucency._depthStencilTexture = new Texture({
+ context: context,
+ width: width,
+ height: height,
+ pixelFormat: PixelFormat.DEPTH_STENCIL,
+ pixelDatatype: PixelDatatype.UNSIGNED_INT_24_8,
+ });
+ } else {
+ globeTranslucency._depthStencilRenderbuffer = new Renderbuffer({
+ context: context,
+ width: width,
+ height: height,
+ format: RenderbufferFormat.DEPTH_STENCIL,
+ });
+ }
+
+ globeTranslucency._framebuffer = new Framebuffer({
+ context: context,
+ colorTextures: [globeTranslucency._colorTexture],
+ depthStencilTexture: globeTranslucency._depthStencilTexture,
+ depthStencilRenderbuffer: globeTranslucency._depthStencilRenderbuffer,
+ destroyAttachments: false,
+ });
+
+ globeTranslucency._packedDepthTexture = new Texture({
+ context: context,
+ width: width,
+ height: height,
+ pixelFormat: PixelFormat.RGBA,
+ pixelDatatype: PixelDatatype.UNSIGNED_BYTE,
+ sampler: Sampler.NEAREST,
+ });
+
+ globeTranslucency._packedDepthFramebuffer = new Framebuffer({
+ context: context,
+ colorTextures: [globeTranslucency._packedDepthTexture],
+ destroyAttachments: false,
+ });
+}
+
+function updateResources(globeTranslucency, context, width, height, hdr) {
+ var colorTexture = globeTranslucency._colorTexture;
+ var textureChanged =
+ !defined(colorTexture) ||
+ colorTexture.width !== width ||
+ colorTexture.height !== height ||
+ hdr !== globeTranslucency._useHdr;
+ if (textureChanged) {
+ destroyResources(globeTranslucency);
+ createResources(globeTranslucency, context, width, height, hdr);
+ }
+}
+
+function updateCommands(globeTranslucency, context, width, height, passState) {
+ globeTranslucency._viewport.width = width;
+ globeTranslucency._viewport.height = height;
+
+ var useScissorTest = !BoundingRectangle.equals(
+ globeTranslucency._viewport,
+ passState.viewport
+ );
+ var updateScissor = useScissorTest !== globeTranslucency._useScissorTest;
+ globeTranslucency._useScissorTest = useScissorTest;
+
+ if (
+ !BoundingRectangle.equals(
+ globeTranslucency._scissorRectangle,
+ passState.viewport
+ )
+ ) {
+ globeTranslucency._scissorRectangle = BoundingRectangle.clone(
+ passState.viewport,
+ globeTranslucency._scissorRectangle
+ );
+ updateScissor = true;
+ }
+
+ if (
+ !defined(globeTranslucency._renderState) ||
+ !BoundingRectangle.equals(
+ globeTranslucency._viewport,
+ globeTranslucency._renderState.viewport
+ ) ||
+ updateScissor
+ ) {
+ globeTranslucency._renderState = RenderState.fromCache({
+ viewport: globeTranslucency._viewport,
+ scissorTest: {
+ enabled: globeTranslucency._useScissorTest,
+ rectangle: globeTranslucency._scissorRectangle,
+ },
+ });
+ }
+
+ if (!defined(globeTranslucency._packedDepthCommand)) {
+ globeTranslucency._packedDepthCommand = context.createViewportQuadCommand(
+ PassThroughDepth,
+ {
+ uniformMap: {
+ u_depthTexture: function () {
+ return globeTranslucency._depthStencilTexture;
+ },
+ },
+ owner: globeTranslucency,
+ }
+ );
+ }
+
+ if (!defined(globeTranslucency._clearCommand)) {
+ globeTranslucency._clearCommand = new ClearCommand({
+ color: new Color(0.0, 0.0, 0.0, 0.0),
+ depth: 1.0,
+ stencil: 0.0,
+ owner: globeTranslucency,
+ });
+ }
+
+ globeTranslucency._packedDepthCommand.framebuffer =
+ globeTranslucency._packedDepthFramebuffer;
+ globeTranslucency._packedDepthCommand.renderState =
+ globeTranslucency._renderState;
+ globeTranslucency._clearCommand.framebuffer = globeTranslucency._framebuffer;
+ globeTranslucency._clearCommand.renderState = globeTranslucency._renderState;
+}
+
+GlobeTranslucencyFramebuffer.prototype.updateAndClear = function (
+ hdr,
+ viewport,
+ context,
+ passState
+) {
+ var width = viewport.width;
+ var height = viewport.height;
+
+ updateResources(this, context, width, height, hdr);
+ updateCommands(this, context, width, height, passState);
+
+ this._useHdr = hdr;
+};
+
+GlobeTranslucencyFramebuffer.prototype.clearClassification = function (
+ context,
+ passState
+) {
+ this._clearCommand.execute(context, passState);
+};
+
+GlobeTranslucencyFramebuffer.prototype.packDepth = function (
+ context,
+ passState
+) {
+ this._packedDepthCommand.execute(context, passState);
+ return this._packedDepthTexture;
+};
+
+GlobeTranslucencyFramebuffer.prototype.isDestroyed = function () {
+ return false;
+};
+
+GlobeTranslucencyFramebuffer.prototype.destroy = function () {
+ destroyResources(this);
+ return destroyObject(this);
+};
+
+export default GlobeTranslucencyFramebuffer;
diff --git a/Source/Scene/GlobeTranslucencyState.js b/Source/Scene/GlobeTranslucencyState.js
new file mode 100644
index 000000000000..a5dadbf03c54
--- /dev/null
+++ b/Source/Scene/GlobeTranslucencyState.js
@@ -0,0 +1,1117 @@
+import combine from "../Core/combine.js";
+import defaultValue from "../Core/defaultValue.js";
+import defined from "../Core/defined.js";
+import NearFarScalar from "../Core/NearFarScalar.js";
+import Rectangle from "../Core/Rectangle.js";
+import DrawCommand from "../Renderer/DrawCommand.js";
+import Pass from "../Renderer/Pass.js";
+import RenderState from "../Renderer/RenderState.js";
+import ShaderSource from "../Renderer/ShaderSource.js";
+import BlendingState from "./BlendingState.js";
+import CullFace from "./CullFace.js";
+import SceneMode from "./SceneMode.js";
+
+var DerivedCommandType = {
+ OPAQUE_FRONT_FACE: 0,
+ OPAQUE_BACK_FACE: 1,
+ DEPTH_ONLY_FRONT_FACE: 2,
+ DEPTH_ONLY_BACK_FACE: 3,
+ DEPTH_ONLY_FRONT_AND_BACK_FACE: 4,
+ TRANSLUCENT_FRONT_FACE: 5,
+ TRANSLUCENT_BACK_FACE: 6,
+ TRANSLUCENT_FRONT_FACE_MANUAL_DEPTH_TEST: 7,
+ TRANSLUCENT_BACK_FACE_MANUAL_DEPTH_TEST: 8,
+ PICK_FRONT_FACE: 9,
+ PICK_BACK_FACE: 10,
+ DERIVED_COMMANDS_MAXIMUM_LENGTH: 11,
+};
+
+var derivedCommandsMaximumLength =
+ DerivedCommandType.DERIVED_COMMANDS_MAXIMUM_LENGTH;
+
+var DerivedCommandNames = [
+ "opaqueFrontFaceCommand",
+ "opaqueBackFaceCommand",
+ "depthOnlyFrontFaceCommand",
+ "depthOnlyBackFaceCommand",
+ "depthOnlyFrontAndBackFaceCommand",
+ "translucentFrontFaceCommand",
+ "translucentBackFaceCommand",
+ "translucentFrontFaceManualDepthTestCommand",
+ "translucentBackFaceManualDepthTestCommand",
+ "pickFrontFaceCommand",
+ "pickBackFaceCommand",
+];
+
+/**
+ * @private
+ */
+function GlobeTranslucencyState() {
+ this._frontFaceAlphaByDistance = new NearFarScalar(0.0, 1.0, 0.0, 1.0);
+ this._backFaceAlphaByDistance = new NearFarScalar(0.0, 1.0, 0.0, 1.0);
+
+ this._frontFaceTranslucent = false;
+ this._backFaceTranslucent = false;
+ this._requiresManualDepthTest = false;
+ this._sunVisibleThroughGlobe = false;
+ this._environmentVisible = false;
+ this._useDepthPlane = false;
+ this._numberOfTextureUniforms = 0;
+ this._globeTranslucencyFramebuffer = undefined;
+ this._rectangle = Rectangle.clone(Rectangle.MAX_VALUE);
+
+ this._derivedCommandKey = 0;
+ this._derivedCommandsDirty = false;
+ this._derivedCommandPacks = undefined;
+
+ this._derivedCommandTypes = new Array(derivedCommandsMaximumLength);
+ this._derivedBlendCommandTypes = new Array(derivedCommandsMaximumLength);
+ this._derivedPickCommandTypes = new Array(derivedCommandsMaximumLength);
+ this._derivedCommandTypesToUpdate = new Array(derivedCommandsMaximumLength);
+
+ this._derivedCommandsLength = 0;
+ this._derivedBlendCommandsLength = 0;
+ this._derivedPickCommandsLength = 0;
+ this._derivedCommandsToUpdateLength = 0;
+}
+
+Object.defineProperties(GlobeTranslucencyState.prototype, {
+ frontFaceAlphaByDistance: {
+ get: function () {
+ return this._frontFaceAlphaByDistance;
+ },
+ },
+ backFaceAlphaByDistance: {
+ get: function () {
+ return this._backFaceAlphaByDistance;
+ },
+ },
+ translucent: {
+ get: function () {
+ return this._frontFaceTranslucent;
+ },
+ },
+ sunVisibleThroughGlobe: {
+ get: function () {
+ return this._sunVisibleThroughGlobe;
+ },
+ },
+ environmentVisible: {
+ get: function () {
+ return this._environmentVisible;
+ },
+ },
+ useDepthPlane: {
+ get: function () {
+ return this._useDepthPlane;
+ },
+ },
+ numberOfTextureUniforms: {
+ get: function () {
+ return this._numberOfTextureUniforms;
+ },
+ },
+ rectangle: {
+ get: function () {
+ return this._rectangle;
+ },
+ },
+});
+
+GlobeTranslucencyState.prototype.update = function (scene) {
+ var globe = scene.globe;
+ if (!defined(globe) || !globe.show) {
+ this._frontFaceTranslucent = false;
+ this._backFaceTranslucent = false;
+ this._sunVisibleThroughGlobe = true;
+ this._environmentVisible = true;
+ this._useDepthPlane = false;
+ return;
+ }
+
+ this._frontFaceAlphaByDistance = updateAlphaByDistance(
+ globe.translucency.enabled,
+ globe.translucency.frontFaceAlpha,
+ globe.translucency.frontFaceAlphaByDistance,
+ this._frontFaceAlphaByDistance
+ );
+ this._backFaceAlphaByDistance = updateAlphaByDistance(
+ globe.translucency.enabled,
+ globe.translucency.backFaceAlpha,
+ globe.translucency.backFaceAlphaByDistance,
+ this._backFaceAlphaByDistance
+ );
+
+ this._frontFaceTranslucent = isFaceTranslucent(
+ globe.translucency.enabled,
+ this._frontFaceAlphaByDistance,
+ globe
+ );
+ this._backFaceTranslucent = isFaceTranslucent(
+ globe.translucency.enabled,
+ this._backFaceAlphaByDistance,
+ globe
+ );
+
+ this._requiresManualDepthTest = requiresManualDepthTest(this, scene, globe);
+
+ this._sunVisibleThroughGlobe = isSunVisibleThroughGlobe(this, scene);
+ this._environmentVisible = isEnvironmentVisible(this, scene);
+ this._useDepthPlane = useDepthPlane(this, scene);
+ this._numberOfTextureUniforms = getNumberOfTextureUniforms(this);
+
+ this._rectangle = Rectangle.clone(
+ globe.translucency.rectangle,
+ this._rectangle
+ );
+
+ gatherDerivedCommandRequirements(this, scene);
+};
+
+function updateAlphaByDistance(enabled, alpha, alphaByDistance, result) {
+ if (!enabled) {
+ result.nearValue = 1.0;
+ result.farValue = 1.0;
+ return result;
+ }
+
+ if (!defined(alphaByDistance)) {
+ result.nearValue = alpha;
+ result.farValue = alpha;
+ return result;
+ }
+
+ NearFarScalar.clone(alphaByDistance, result);
+ result.nearValue *= alpha;
+ result.farValue *= alpha;
+ return result;
+}
+
+function isFaceTranslucent(translucencyEnabled, alphaByDistance, globe) {
+ return (
+ translucencyEnabled &&
+ (globe.baseColor.alpha < 1.0 ||
+ alphaByDistance.nearValue < 1.0 ||
+ alphaByDistance.farValue < 1.0)
+ );
+}
+
+function isSunVisibleThroughGlobe(state, scene) {
+ // The sun is visible through the globe if the front and back faces are translucent when above ground
+ // or if front faces are translucent when below ground
+ var frontTranslucent = state._frontFaceTranslucent;
+ var backTranslucent = state._backFaceTranslucent;
+ return frontTranslucent && (scene.cameraUnderground || backTranslucent);
+}
+
+function isEnvironmentVisible(state, scene) {
+ // The environment is visible if the camera is above ground or underground with translucency
+ return !scene.cameraUnderground || state._frontFaceTranslucent;
+}
+
+function useDepthPlane(state, scene) {
+ // Use the depth plane when the camera is above ground and the globe is opaque
+ return !scene.cameraUnderground && !state._frontFaceTranslucent;
+}
+
+function requiresManualDepthTest(state, scene, globe) {
+ return (
+ state._frontFaceTranslucent &&
+ !state._backFaceTranslucent &&
+ !globe.depthTestAgainstTerrain &&
+ scene.mode !== SceneMode.SCENE2D &&
+ scene.context.depthTexture
+ );
+}
+
+function getNumberOfTextureUniforms(state) {
+ var numberOfTextureUniforms = 0;
+
+ if (state._frontFaceTranslucent) {
+ ++numberOfTextureUniforms; // classification texture
+ }
+
+ if (state._requiresManualDepthTest) {
+ ++numberOfTextureUniforms; // czm_globeDepthTexture for manual depth testing
+ }
+
+ return numberOfTextureUniforms;
+}
+
+function gatherDerivedCommandRequirements(state, scene) {
+ state._derivedCommandsLength = getDerivedCommandTypes(
+ state,
+ scene,
+ false,
+ false,
+ state._derivedCommandTypes
+ );
+
+ state._derivedBlendCommandsLength = getDerivedCommandTypes(
+ state,
+ scene,
+ true,
+ false,
+ state._derivedBlendCommandTypes
+ );
+
+ state._derivedPickCommandsLength = getDerivedCommandTypes(
+ state,
+ scene,
+ false,
+ true,
+ state._derivedPickCommandTypes
+ );
+
+ var i;
+
+ var derivedCommandKey = 0;
+ for (i = 0; i < state._derivedCommandsLength; ++i) {
+ derivedCommandKey |= 1 << state._derivedCommandTypes[i];
+ }
+ for (i = 0; i < state._derivedBlendCommandsLength; ++i) {
+ derivedCommandKey |= 1 << state._derivedBlendCommandTypes[i];
+ }
+ for (i = 0; i < state._derivedPickCommandsLength; ++i) {
+ derivedCommandKey |= 1 << state._derivedPickCommandTypes[i];
+ }
+
+ var derivedCommandsToUpdateLength = 0;
+ for (i = 0; i < derivedCommandsMaximumLength; ++i) {
+ if ((derivedCommandKey & (1 << i)) > 0) {
+ state._derivedCommandTypesToUpdate[derivedCommandsToUpdateLength++] = i;
+ }
+ }
+ state._derivedCommandsToUpdateLength = derivedCommandsToUpdateLength;
+
+ var derivedCommandsDirty = derivedCommandKey !== state._derivedCommandKey;
+ state._derivedCommandKey = derivedCommandKey;
+ state._derivedCommandsDirty = derivedCommandsDirty;
+
+ if (!defined(state._derivedCommandPacks) && state._frontFaceTranslucent) {
+ state._derivedCommandPacks = createDerivedCommandPacks();
+ }
+}
+
+function getDerivedCommandTypes(
+ state,
+ scene,
+ isBlendCommand,
+ isPickCommand,
+ types
+) {
+ var length = 0;
+
+ var frontTranslucent = state._frontFaceTranslucent;
+ var backTranslucent = state._backFaceTranslucent;
+
+ if (!frontTranslucent) {
+ // Don't use derived commands if the globe is opaque
+ return length;
+ }
+
+ var cameraUnderground = scene.cameraUnderground;
+ var requiresManualDepthTest = state._requiresManualDepthTest;
+
+ var translucentFrontFaceCommandType = isPickCommand
+ ? DerivedCommandType.PICK_FRONT_FACE
+ : requiresManualDepthTest
+ ? DerivedCommandType.TRANSLUCENT_FRONT_FACE_MANUAL_DEPTH_TEST
+ : DerivedCommandType.TRANSLUCENT_FRONT_FACE;
+
+ var translucentBackFaceCommandType = isPickCommand
+ ? DerivedCommandType.PICK_BACK_FACE
+ : requiresManualDepthTest
+ ? DerivedCommandType.TRANSLUCENT_BACK_FACE_MANUAL_DEPTH_TEST
+ : DerivedCommandType.TRANSLUCENT_BACK_FACE;
+
+ if (scene.mode === SceneMode.SCENE2D) {
+ types[length++] = DerivedCommandType.DEPTH_ONLY_FRONT_FACE;
+ types[length++] = translucentFrontFaceCommandType;
+ return length;
+ }
+
+ if (backTranslucent) {
+ // Push depth-only command for classification. Blend commands do not need to write depth.
+ // Push translucent commands for front and back faces.
+ if (!isBlendCommand) {
+ types[length++] = DerivedCommandType.DEPTH_ONLY_FRONT_AND_BACK_FACE;
+ }
+ if (cameraUnderground) {
+ types[length++] = translucentFrontFaceCommandType;
+ types[length++] = translucentBackFaceCommandType;
+ } else {
+ types[length++] = translucentBackFaceCommandType;
+ types[length++] = translucentFrontFaceCommandType;
+ }
+ } else {
+ // Push opaque command for the face that appears in back.
+ // Push depth-only command and translucent command for the face that appears in front.
+ // eslint-disable-next-line no-lonely-if
+ if (cameraUnderground) {
+ if (!isBlendCommand) {
+ types[length++] = DerivedCommandType.DEPTH_ONLY_BACK_FACE;
+ }
+ types[length++] = DerivedCommandType.OPAQUE_FRONT_FACE;
+ types[length++] = translucentBackFaceCommandType;
+ } else {
+ if (!isBlendCommand) {
+ types[length++] = DerivedCommandType.DEPTH_ONLY_FRONT_FACE;
+ }
+ types[length++] = DerivedCommandType.OPAQUE_BACK_FACE;
+ types[length++] = translucentFrontFaceCommandType;
+ }
+ }
+
+ return length;
+}
+
+function removeDefine(defines, defineToRemove) {
+ var index = defines.indexOf(defineToRemove);
+ if (index > -1) {
+ defines.splice(index, 1);
+ }
+}
+
+function hasDefine(defines, define) {
+ return defines.indexOf(define) > -1;
+}
+
+function getOpaqueFrontFaceShaderProgram(vs, fs) {
+ removeDefine(vs.defines, "TRANSLUCENT");
+ removeDefine(fs.defines, "TRANSLUCENT");
+}
+
+function getOpaqueBackFaceShaderProgram(vs, fs) {
+ removeDefine(vs.defines, "GROUND_ATMOSPHERE");
+ removeDefine(fs.defines, "GROUND_ATMOSPHERE");
+ removeDefine(vs.defines, "FOG");
+ removeDefine(fs.defines, "FOG");
+ removeDefine(vs.defines, "TRANSLUCENT");
+ removeDefine(fs.defines, "TRANSLUCENT");
+}
+
+function getDepthOnlyShaderProgram(vs, fs) {
+ if (
+ hasDefine(fs.defines, "TILE_LIMIT_RECTANGLE") ||
+ hasDefine(fs.defines, "ENABLE_CLIPPING_PLANES")
+ ) {
+ // Need to execute the full shader if discard is called
+ return;
+ }
+
+ var depthOnlyShader =
+ "void main() \n" + "{ \n" + " gl_FragColor = vec4(1.0); \n" + "} \n";
+
+ fs.sources = [depthOnlyShader];
+}
+
+function getTranslucentShaderProgram(vs, fs) {
+ var sources = fs.sources;
+ var length = sources.length;
+ for (var i = 0; i < length; ++i) {
+ sources[i] = ShaderSource.replaceMain(
+ sources[i],
+ "czm_globe_translucency_main"
+ );
+ }
+
+ var globeTranslucencyMain =
+ "\n\n" +
+ "uniform sampler2D u_classificationTexture; \n" +
+ "void main() \n" +
+ "{ \n" +
+ " vec2 st = gl_FragCoord.xy / czm_viewport.zw; \n" +
+ "#ifdef MANUAL_DEPTH_TEST \n" +
+ " float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, st)); \n" +
+ " if (logDepthOrDepth != 0.0) \n" +
+ " { \n" +
+ " vec4 eyeCoordinate = czm_windowToEyeCoordinates(gl_FragCoord.xy, logDepthOrDepth); \n" +
+ " float depthEC = eyeCoordinate.z / eyeCoordinate.w; \n" +
+ " if (v_positionEC.z < depthEC) \n" +
+ " { \n" +
+ " discard; \n" +
+ " } \n" +
+ " } \n" +
+ "#endif \n" +
+ " czm_globe_translucency_main(); \n" +
+ " vec4 classificationColor = texture2D(u_classificationTexture, st); \n" +
+ " if (classificationColor.a > 0.0) \n" +
+ " { \n" +
+ " // Reverse premultiplication process to get the correct composited result of the classification primitives \n" +
+ " classificationColor.rgb /= classificationColor.a; \n" +
+ " } \n" +
+ " gl_FragColor = classificationColor * vec4(classificationColor.aaa, 1.0) + gl_FragColor * (1.0 - classificationColor.a); \n" +
+ "} \n";
+
+ sources.push(globeTranslucencyMain);
+}
+
+function getTranslucentBackFaceShaderProgram(vs, fs) {
+ getTranslucentShaderProgram(vs, fs);
+ removeDefine(vs.defines, "GROUND_ATMOSPHERE");
+ removeDefine(fs.defines, "GROUND_ATMOSPHERE");
+ removeDefine(vs.defines, "FOG");
+ removeDefine(fs.defines, "FOG");
+}
+
+function getTranslucentFrontFaceManualDepthTestShaderProgram(vs, fs) {
+ getTranslucentShaderProgram(vs, fs);
+ vs.defines.push("GENERATE_POSITION");
+ fs.defines.push("MANUAL_DEPTH_TEST");
+}
+
+function getTranslucentBackFaceManualDepthTestShaderProgram(vs, fs) {
+ getTranslucentBackFaceShaderProgram(vs, fs);
+ vs.defines.push("GENERATE_POSITION");
+ fs.defines.push("MANUAL_DEPTH_TEST");
+}
+
+function getPickShaderProgram(vs, fs) {
+ var pickShader =
+ "uniform sampler2D u_classificationTexture; \n" +
+ "void main() \n" +
+ "{ \n" +
+ " vec2 st = gl_FragCoord.xy / czm_viewport.zw; \n" +
+ " vec4 pickColor = texture2D(u_classificationTexture, st); \n" +
+ " if (pickColor == vec4(0.0)) \n" +
+ " { \n" +
+ " discard; \n" +
+ " } \n" +
+ " gl_FragColor = pickColor; \n" +
+ "} \n";
+
+ fs.sources = [pickShader];
+}
+
+function getDerivedShaderProgram(
+ context,
+ shaderProgram,
+ derivedShaderProgram,
+ shaderProgramDirty,
+ getShaderProgramFunction,
+ cacheName
+) {
+ if (!defined(getShaderProgramFunction)) {
+ return shaderProgram;
+ }
+
+ if (!shaderProgramDirty && defined(derivedShaderProgram)) {
+ return derivedShaderProgram;
+ }
+
+ var shader = context.shaderCache.getDerivedShaderProgram(
+ shaderProgram,
+ cacheName
+ );
+ if (!defined(shader)) {
+ var attributeLocations = shaderProgram._attributeLocations;
+ var vs = shaderProgram.vertexShaderSource.clone();
+ var fs = shaderProgram.fragmentShaderSource.clone();
+ vs.defines = defined(vs.defines) ? vs.defines.slice(0) : [];
+ fs.defines = defined(fs.defines) ? fs.defines.slice(0) : [];
+
+ getShaderProgramFunction(vs, fs);
+
+ shader = context.shaderCache.createDerivedShaderProgram(
+ shaderProgram,
+ cacheName,
+ {
+ vertexShaderSource: vs,
+ fragmentShaderSource: fs,
+ attributeLocations: attributeLocations,
+ }
+ );
+ }
+
+ return shader;
+}
+
+function getOpaqueFrontFaceRenderState(renderState) {
+ renderState.cull.face = CullFace.BACK;
+ renderState.cull.enabled = true;
+}
+
+function getOpaqueBackFaceRenderState(renderState) {
+ renderState.cull.face = CullFace.FRONT;
+ renderState.cull.enabled = true;
+}
+
+function getDepthOnlyFrontFaceRenderState(renderState) {
+ renderState.cull.face = CullFace.BACK;
+ renderState.cull.enabled = true;
+ renderState.colorMask = {
+ red: false,
+ green: false,
+ blue: false,
+ alpha: false,
+ };
+}
+
+function getDepthOnlyBackFaceRenderState(renderState) {
+ renderState.cull.face = CullFace.FRONT;
+ renderState.cull.enabled = true;
+ renderState.colorMask = {
+ red: false,
+ green: false,
+ blue: false,
+ alpha: false,
+ };
+}
+
+function getDepthOnlyFrontAndBackFaceRenderState(renderState) {
+ renderState.cull.enabled = false;
+ renderState.colorMask = {
+ red: false,
+ green: false,
+ blue: false,
+ alpha: false,
+ };
+}
+
+function getTranslucentFrontFaceRenderState(renderState) {
+ renderState.cull.face = CullFace.BACK;
+ renderState.cull.enabled = true;
+ renderState.depthMask = false;
+ renderState.blending = BlendingState.ALPHA_BLEND;
+}
+
+function getTranslucentBackFaceRenderState(renderState) {
+ renderState.cull.face = CullFace.FRONT;
+ renderState.cull.enabled = true;
+ renderState.depthMask = false;
+ renderState.blending = BlendingState.ALPHA_BLEND;
+}
+
+function getPickFrontFaceRenderState(renderState) {
+ renderState.cull.face = CullFace.BACK;
+ renderState.cull.enabled = true;
+ renderState.blending.enabled = false;
+}
+
+function getPickBackFaceRenderState(renderState) {
+ renderState.cull.face = CullFace.FRONT;
+ renderState.cull.enabled = true;
+ renderState.blending.enabled = false;
+}
+
+function getDerivedRenderState(
+ renderState,
+ derivedRenderState,
+ renderStateDirty,
+ getRenderStateFunction,
+ cache
+) {
+ if (!defined(getRenderStateFunction)) {
+ return renderState;
+ }
+
+ if (!renderStateDirty && defined(derivedRenderState)) {
+ return derivedRenderState;
+ }
+
+ var cachedRenderState = cache[renderState.id];
+ if (!defined(cachedRenderState)) {
+ var rs = RenderState.getState(renderState);
+ getRenderStateFunction(rs);
+ cachedRenderState = RenderState.fromCache(rs);
+ cache[renderState.id] = cachedRenderState;
+ }
+
+ return cachedRenderState;
+}
+
+function getTranslucencyUniformMap(state) {
+ return {
+ u_classificationTexture: function () {
+ return state._globeTranslucencyFramebuffer.classificationTexture;
+ },
+ };
+}
+
+function getDerivedUniformMap(
+ state,
+ uniformMap,
+ derivedUniformMap,
+ uniformMapDirty,
+ getDerivedUniformMapFunction
+) {
+ if (!defined(getDerivedUniformMapFunction)) {
+ return uniformMap;
+ }
+
+ if (!uniformMapDirty && defined(derivedUniformMap)) {
+ return derivedUniformMap;
+ }
+
+ return combine(uniformMap, getDerivedUniformMapFunction(state), false);
+}
+
+function DerivedCommandPack(options) {
+ this.pass = options.pass;
+ this.pickOnly = options.pickOnly;
+ this.getShaderProgramFunction = options.getShaderProgramFunction;
+ this.getRenderStateFunction = options.getRenderStateFunction;
+ this.getUniformMapFunction = options.getUniformMapFunction;
+ this.renderStateCache = {};
+}
+
+function createDerivedCommandPacks() {
+ return [
+ // opaqueFrontFaceCommand
+ new DerivedCommandPack({
+ pass: Pass.GLOBE,
+ pickOnly: false,
+ getShaderProgramFunction: getOpaqueFrontFaceShaderProgram,
+ getRenderStateFunction: getOpaqueFrontFaceRenderState,
+ getUniformMapFunction: undefined,
+ }),
+ // opaqueBackFaceCommand
+ new DerivedCommandPack({
+ pass: Pass.GLOBE,
+ pickOnly: false,
+ getShaderProgramFunction: getOpaqueBackFaceShaderProgram,
+ getRenderStateFunction: getOpaqueBackFaceRenderState,
+ getUniformMapFunction: undefined,
+ }),
+ // depthOnlyFrontFaceCommand
+ new DerivedCommandPack({
+ pass: Pass.GLOBE,
+ pickOnly: false,
+ getShaderProgramFunction: getDepthOnlyShaderProgram,
+ getRenderStateFunction: getDepthOnlyFrontFaceRenderState,
+ getUniformMapFunction: undefined,
+ }),
+ // depthOnlyBackFaceCommand
+ new DerivedCommandPack({
+ pass: Pass.GLOBE,
+ pickOnly: false,
+ getShaderProgramFunction: getDepthOnlyShaderProgram,
+ getRenderStateFunction: getDepthOnlyBackFaceRenderState,
+ getUniformMapFunction: undefined,
+ }),
+ // depthOnlyFrontAndBackFaceCommand
+ new DerivedCommandPack({
+ pass: Pass.GLOBE,
+ pickOnly: false,
+ getShaderProgramFunction: getDepthOnlyShaderProgram,
+ getRenderStateFunction: getDepthOnlyFrontAndBackFaceRenderState,
+ getUniformMapFunction: undefined,
+ }),
+ // translucentFrontFaceCommand
+ new DerivedCommandPack({
+ pass: Pass.TRANSLUCENT,
+ pickOnly: false,
+ getShaderProgramFunction: getTranslucentShaderProgram,
+ getRenderStateFunction: getTranslucentFrontFaceRenderState,
+ getUniformMapFunction: getTranslucencyUniformMap,
+ }),
+ // translucentBackFaceCommand
+ new DerivedCommandPack({
+ pass: Pass.TRANSLUCENT,
+ pickOnly: false,
+ getShaderProgramFunction: getTranslucentBackFaceShaderProgram,
+ getRenderStateFunction: getTranslucentBackFaceRenderState,
+ getUniformMapFunction: getTranslucencyUniformMap,
+ }),
+ // translucentFrontFaceManualDepthTestCommand
+ new DerivedCommandPack({
+ pass: Pass.TRANSLUCENT,
+ pickOnly: false,
+ getShaderProgramFunction: getTranslucentFrontFaceManualDepthTestShaderProgram,
+ getRenderStateFunction: getTranslucentFrontFaceRenderState,
+ getUniformMapFunction: getTranslucencyUniformMap,
+ }),
+ // translucentBackFaceManualDepthTestCommand
+ new DerivedCommandPack({
+ pass: Pass.TRANSLUCENT,
+ pickOnly: false,
+ getShaderProgramFunction: getTranslucentBackFaceManualDepthTestShaderProgram,
+ getRenderStateFunction: getTranslucentBackFaceRenderState,
+ getUniformMapFunction: getTranslucencyUniformMap,
+ }),
+ // pickFrontFaceCommand
+ new DerivedCommandPack({
+ pass: Pass.TRANSLUCENT,
+ pickOnly: true,
+ getShaderProgramFunction: getPickShaderProgram,
+ getRenderStateFunction: getPickFrontFaceRenderState,
+ getUniformMapFunction: getTranslucencyUniformMap,
+ }),
+ // pickBackFaceCommand
+ new DerivedCommandPack({
+ pass: Pass.TRANSLUCENT,
+ pickOnly: true,
+ getShaderProgramFunction: getPickShaderProgram,
+ getRenderStateFunction: getPickBackFaceRenderState,
+ getUniformMapFunction: getTranslucencyUniformMap,
+ }),
+ ];
+}
+
+var derivedCommandNames = new Array(derivedCommandsMaximumLength);
+var derivedCommandPacks = new Array(derivedCommandsMaximumLength);
+
+GlobeTranslucencyState.prototype.updateDerivedCommands = function (
+ command,
+ frameState
+) {
+ var derivedCommandTypes = this._derivedCommandTypesToUpdate;
+ var derivedCommandsLength = this._derivedCommandsToUpdateLength;
+
+ if (derivedCommandsLength === 0) {
+ return;
+ }
+
+ for (var i = 0; i < derivedCommandsLength; ++i) {
+ derivedCommandPacks[i] = this._derivedCommandPacks[derivedCommandTypes[i]];
+ derivedCommandNames[i] = DerivedCommandNames[derivedCommandTypes[i]];
+ }
+
+ updateDerivedCommands(
+ this,
+ command,
+ derivedCommandsLength,
+ derivedCommandTypes,
+ derivedCommandNames,
+ derivedCommandPacks,
+ frameState
+ );
+};
+
+function updateDerivedCommands(
+ state,
+ command,
+ derivedCommandsLength,
+ derivedCommandTypes,
+ derivedCommandNames,
+ derivedCommandPacks,
+ frameState
+) {
+ var derivedCommandsObject = command.derivedCommands.globeTranslucency;
+ var derivedCommandsDirty = state._derivedCommandsDirty;
+
+ if (
+ command.dirty ||
+ !defined(derivedCommandsObject) ||
+ derivedCommandsDirty
+ ) {
+ command.dirty = false;
+
+ if (!defined(derivedCommandsObject)) {
+ derivedCommandsObject = {};
+ command.derivedCommands.globeTranslucency = derivedCommandsObject;
+ }
+
+ var frameNumber = frameState.frameNumber;
+
+ var uniformMapDirtyFrame = defaultValue(
+ derivedCommandsObject.uniformMapDirtyFrame,
+ 0
+ );
+ var shaderProgramDirtyFrame = defaultValue(
+ derivedCommandsObject.shaderProgramDirtyFrame,
+ 0
+ );
+ var renderStateDirtyFrame = defaultValue(
+ derivedCommandsObject.renderStateDirtyFrame,
+ 0
+ );
+
+ var uniformMapDirty =
+ derivedCommandsObject.uniformMap !== command.uniformMap;
+
+ var shaderProgramDirty =
+ derivedCommandsObject.shaderProgramId !== command.shaderProgram.id;
+
+ var renderStateDirty =
+ derivedCommandsObject.renderStateId !== command.renderState.id;
+
+ if (uniformMapDirty) {
+ derivedCommandsObject.uniformMapDirtyFrame = frameNumber;
+ }
+ if (shaderProgramDirty) {
+ derivedCommandsObject.shaderProgramDirtyFrame = frameNumber;
+ }
+ if (renderStateDirty) {
+ derivedCommandsObject.renderStateDirtyFrame = frameNumber;
+ }
+
+ derivedCommandsObject.uniformMap = command.uniformMap;
+ derivedCommandsObject.shaderProgramId = command.shaderProgram.id;
+ derivedCommandsObject.renderStateId = command.renderState.id;
+
+ for (var i = 0; i < derivedCommandsLength; ++i) {
+ var derivedCommandPack = derivedCommandPacks[i];
+ var derivedCommandType = derivedCommandTypes[i];
+ var derivedCommandName = derivedCommandNames[i];
+ var derivedCommand = derivedCommandsObject[derivedCommandName];
+
+ var derivedUniformMap;
+ var derivedShaderProgram;
+ var derivedRenderState;
+
+ if (defined(derivedCommand)) {
+ derivedUniformMap = derivedCommand.uniformMap;
+ derivedShaderProgram = derivedCommand.shaderProgram;
+ derivedRenderState = derivedCommand.renderState;
+ } else {
+ derivedUniformMap = undefined;
+ derivedShaderProgram = undefined;
+ derivedRenderState = undefined;
+ }
+
+ derivedCommand = DrawCommand.shallowClone(command, derivedCommand);
+ derivedCommandsObject[derivedCommandName] = derivedCommand;
+
+ var derivedUniformMapDirtyFrame = defaultValue(
+ derivedCommand.derivedCommands.uniformMapDirtyFrame,
+ 0
+ );
+ var derivedShaderProgramDirtyFrame = defaultValue(
+ derivedCommand.derivedCommands.shaderProgramDirtyFrame,
+ 0
+ );
+ var derivedRenderStateDirtyFrame = defaultValue(
+ derivedCommand.derivedCommands.renderStateDirtyFrame,
+ 0
+ );
+
+ var derivedUniformMapDirty =
+ uniformMapDirty || derivedUniformMapDirtyFrame < uniformMapDirtyFrame;
+ var derivedShaderProgramDirty =
+ shaderProgramDirty ||
+ derivedShaderProgramDirtyFrame < shaderProgramDirtyFrame;
+ var derivedRenderStateDirty =
+ renderStateDirty ||
+ derivedRenderStateDirtyFrame < renderStateDirtyFrame;
+
+ if (derivedUniformMapDirty) {
+ derivedCommand.derivedCommands.uniformMapDirtyFrame = frameNumber;
+ }
+ if (derivedShaderProgramDirty) {
+ derivedCommand.derivedCommands.shaderProgramDirtyFrame = frameNumber;
+ }
+ if (derivedRenderStateDirty) {
+ derivedCommand.derivedCommands.renderStateDirtyFrame = frameNumber;
+ }
+
+ derivedCommand.derivedCommands.type = derivedCommandType;
+ derivedCommand.pass = derivedCommandPack.pass;
+ derivedCommand.pickOnly = derivedCommandPack.pickOnly;
+ derivedCommand.uniformMap = getDerivedUniformMap(
+ state,
+ command.uniformMap,
+ derivedUniformMap,
+ derivedUniformMapDirty,
+ derivedCommandPack.getUniformMapFunction
+ );
+ derivedCommand.shaderProgram = getDerivedShaderProgram(
+ frameState.context,
+ command.shaderProgram,
+ derivedShaderProgram,
+ derivedShaderProgramDirty,
+ derivedCommandPack.getShaderProgramFunction,
+ derivedCommandName
+ );
+ derivedCommand.renderState = getDerivedRenderState(
+ command.renderState,
+ derivedRenderState,
+ derivedRenderStateDirty,
+ derivedCommandPack.getRenderStateFunction,
+ derivedCommandPack.renderStateCache
+ );
+ }
+ }
+}
+
+GlobeTranslucencyState.prototype.pushDerivedCommands = function (
+ command,
+ isBlendCommand,
+ frameState
+) {
+ var picking = frameState.passes.pick;
+ if (picking && isBlendCommand) {
+ // No need to push blend commands in the pick pass
+ return;
+ }
+
+ var derivedCommandTypes = this._derivedCommandTypes;
+ var derivedCommandsLength = this._derivedCommandsLength;
+
+ if (picking) {
+ derivedCommandTypes = this._derivedPickCommandTypes;
+ derivedCommandsLength = this._derivedPickCommandsLength;
+ } else if (isBlendCommand) {
+ derivedCommandTypes = this._derivedBlendCommandTypes;
+ derivedCommandsLength = this._derivedBlendCommandsLength;
+ }
+
+ if (derivedCommandsLength === 0) {
+ // No derived commands to push so just push the globe command
+ frameState.commandList.push(command);
+ return;
+ }
+
+ // Push derived commands
+ var derivedCommands = command.derivedCommands.globeTranslucency;
+ for (var i = 0; i < derivedCommandsLength; ++i) {
+ var derivedCommandName = DerivedCommandNames[derivedCommandTypes[i]];
+ frameState.commandList.push(derivedCommands[derivedCommandName]);
+ }
+};
+
+function executeCommandsMatchingType(
+ commands,
+ commandsLength,
+ executeCommandFunction,
+ scene,
+ context,
+ passState,
+ types
+) {
+ for (var i = 0; i < commandsLength; ++i) {
+ var command = commands[i];
+ var type = command.derivedCommands.type;
+ if (!defined(types) || types.indexOf(type) > -1) {
+ executeCommandFunction(command, scene, context, passState);
+ }
+ }
+}
+
+function executeCommands(
+ commands,
+ commandsLength,
+ executeCommandFunction,
+ scene,
+ context,
+ passState
+) {
+ for (var i = 0; i < commandsLength; ++i) {
+ executeCommandFunction(commands[i], scene, context, passState);
+ }
+}
+
+var opaqueTypes = [
+ DerivedCommandType.OPAQUE_FRONT_FACE,
+ DerivedCommandType.OPAQUE_BACK_FACE,
+];
+var depthOnlyTypes = [
+ DerivedCommandType.DEPTH_ONLY_FRONT_FACE,
+ DerivedCommandType.DEPTH_ONLY_BACK_FACE,
+ DerivedCommandType.DEPTH_ONLY_FRONT_AND_BACK_FACE,
+];
+
+GlobeTranslucencyState.prototype.executeGlobeCommands = function (
+ frustumCommands,
+ executeCommandFunction,
+ globeTranslucencyFramebuffer,
+ scene,
+ passState
+) {
+ var context = scene.context;
+ var globeCommands = frustumCommands.commands[Pass.GLOBE];
+ var globeCommandsLength = frustumCommands.indices[Pass.GLOBE];
+
+ if (globeCommandsLength === 0) {
+ return;
+ }
+
+ this._globeTranslucencyFramebuffer = globeTranslucencyFramebuffer;
+ globeTranslucencyFramebuffer.clearClassification(context, passState);
+
+ // Render opaque commands like normal
+ executeCommandsMatchingType(
+ globeCommands,
+ globeCommandsLength,
+ executeCommandFunction,
+ scene,
+ context,
+ passState,
+ opaqueTypes
+ );
+};
+
+GlobeTranslucencyState.prototype.executeGlobeClassificationCommands = function (
+ frustumCommands,
+ executeCommandFunction,
+ globeTranslucencyFramebuffer,
+ scene,
+ passState
+) {
+ var context = scene.context;
+ var globeCommands = frustumCommands.commands[Pass.GLOBE];
+ var globeCommandsLength = frustumCommands.indices[Pass.GLOBE];
+ var classificationCommands =
+ frustumCommands.commands[Pass.TERRAIN_CLASSIFICATION];
+ var classificationCommandsLength =
+ frustumCommands.indices[Pass.TERRAIN_CLASSIFICATION];
+
+ if (globeCommandsLength === 0 || classificationCommandsLength === 0) {
+ return;
+ }
+
+ var frontTranslucent = this._frontFaceTranslucent;
+ var backTranslucent = this._backFaceTranslucent;
+
+ if (!frontTranslucent || !backTranslucent) {
+ // Render classification on opaque faces like normal
+ executeCommands(
+ classificationCommands,
+ classificationCommandsLength,
+ executeCommandFunction,
+ scene,
+ context,
+ passState
+ );
+ }
+
+ if (!frontTranslucent && !backTranslucent) {
+ // No translucent commands to render. Skip translucent classification.
+ return;
+ }
+
+ this._globeTranslucencyFramebuffer = globeTranslucencyFramebuffer;
+
+ var originalGlobeDepthTexture = context.uniformState.globeDepthTexture;
+ var originalFramebuffer = passState.framebuffer;
+
+ // Render to internal framebuffer and get the first depth peel
+ passState.framebuffer =
+ globeTranslucencyFramebuffer.classificationFramebuffer;
+
+ executeCommandsMatchingType(
+ globeCommands,
+ globeCommandsLength,
+ executeCommandFunction,
+ scene,
+ context,
+ passState,
+ depthOnlyTypes
+ );
+
+ if (context.depthTexture) {
+ // Pack depth into separate texture for ground polylines and textured ground primitives
+ var packedDepthTexture = globeTranslucencyFramebuffer.packDepth(
+ context,
+ passState
+ );
+ context.uniformState.globeDepthTexture = packedDepthTexture;
+ }
+
+ // Render classification on translucent faces
+ executeCommands(
+ classificationCommands,
+ classificationCommandsLength,
+ executeCommandFunction,
+ scene,
+ context,
+ passState
+ );
+
+ // Unset temporary state
+ context.uniformState.globeDepthTexture = originalGlobeDepthTexture;
+ passState.framebuffer = originalFramebuffer;
+};
+
+export default GlobeTranslucencyState;
diff --git a/Source/Scene/GoogleEarthEnterpriseImageryProvider.js b/Source/Scene/GoogleEarthEnterpriseImageryProvider.js
index 6104a29af1b9..54013f15f698 100644
--- a/Source/Scene/GoogleEarthEnterpriseImageryProvider.js
+++ b/Source/Scene/GoogleEarthEnterpriseImageryProvider.js
@@ -16,6 +16,9 @@ import TileProviderError from "../Core/TileProviderError.js";
import protobuf from "../ThirdParty/protobuf-minimal.js";
import when from "../ThirdParty/when.js";
+/**
+ * @private
+ */
function GoogleEarthEnterpriseDiscardPolicy() {
this._image = new Image();
}
@@ -31,7 +34,7 @@ GoogleEarthEnterpriseDiscardPolicy.prototype.isReady = function () {
/**
* Given a tile image, decide whether to discard that image.
*
- * @param {Image} image An image to test.
+ * @param {HTMLImageElement} image An image to test.
* @returns {Boolean} True if the image should be discarded; otherwise, false.
*/
GoogleEarthEnterpriseDiscardPolicy.prototype.shouldDiscardImage = function (
@@ -40,6 +43,20 @@ GoogleEarthEnterpriseDiscardPolicy.prototype.shouldDiscardImage = function (
return image === this._image;
};
+/**
+ * @typedef {Object} GoogleEarthEnterpriseImageryProvider.ConstructorOptions
+ *
+ * Initialization options for the GoogleEarthEnterpriseImageryProvider constructor
+ *
+ * @property {Resource|String} url The url of the Google Earth Enterprise server hosting the imagery.
+ * @property {GoogleEarthEnterpriseMetadata} metadata A metadata object that can be used to share metadata requests with a GoogleEarthEnterpriseTerrainProvider.
+ * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
+ * @property {TileDiscardPolicy} [tileDiscardPolicy] The policy that determines if a tile
+ * is invalid and should be discarded. If this value is not specified, a default
+ * is to discard tiles that fail to download.
+ * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas.
+ */
+
/**
* Provides tiled imagery using the Google Earth Enterprise REST API.
*
@@ -49,14 +66,7 @@ GoogleEarthEnterpriseDiscardPolicy.prototype.shouldDiscardImage = function (
* @alias GoogleEarthEnterpriseImageryProvider
* @constructor
*
- * @param {Object} options Object with the following properties:
- * @param {Resource|String} options.url The url of the Google Earth Enterprise server hosting the imagery.
- * @param {GoogleEarthEnterpriseMetadata} options.metadata A metadata object that can be used to share metadata requests with a GoogleEarthEnterpriseTerrainProvider.
- * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
- * @param {TileDiscardPolicy} [options.tileDiscardPolicy] The policy that determines if a tile
- * is invalid and should be discarded. If this value is not specified, a default
- * is to discard tiles that fail to download.
- * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas.
+ * @param {GoogleEarthEnterpriseImageryProvider.ConstructorOptions} options Object describing initialization options
*
* @see GoogleEarthEnterpriseTerrainProvider
* @see ArcGisMapServerImageryProvider
@@ -86,6 +96,92 @@ function GoogleEarthEnterpriseImageryProvider(options) {
}
//>>includeEnd('debug');
+ /**
+ * The default alpha blending value of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultNightAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultDayAlpha = undefined;
+
+ /**
+ * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
+ * makes the imagery darker while greater than 1.0 makes it brighter.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultBrightness = undefined;
+
+ /**
+ * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
+ * the contrast while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultContrast = undefined;
+
+ /**
+ * The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultHue = undefined;
+
+ /**
+ * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
+ * saturation while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultSaturation = undefined;
+
+ /**
+ * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultGamma = undefined;
+
+ /**
+ * The default texture minification filter to apply to this provider.
+ *
+ * @type {TextureMinificationFilter}
+ * @default undefined
+ */
+ this.defaultMinificationFilter = undefined;
+
+ /**
+ * The default texture magnification filter to apply to this provider.
+ *
+ * @type {TextureMagnificationFilter}
+ * @default undefined
+ */
+ this.defaultMagnificationFilter = undefined;
+
var metadata;
if (defined(options.metadata)) {
metadata = options.metadata;
@@ -237,7 +333,7 @@ Object.defineProperties(GoogleEarthEnterpriseImageryProvider.prototype, {
* Gets the maximum level-of-detail that can be requested. This function should
* not be called before {@link GoogleEarthEnterpriseImageryProvider#ready} returns true.
* @memberof GoogleEarthEnterpriseImageryProvider.prototype
- * @type {Number}
+ * @type {Number|undefined}
* @readonly
*/
maximumLevel: {
@@ -451,7 +547,7 @@ GoogleEarthEnterpriseImageryProvider.prototype.getTileCredits = function (
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level.
* @param {Request} [request] The request object. Intended for internal use only.
- * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
+ * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if there are too many active requests to the server, and the request
* should be retried later. The resolved image may be either an
* Image or a Canvas DOM object.
diff --git a/Source/Scene/GoogleEarthEnterpriseMapsProvider.js b/Source/Scene/GoogleEarthEnterpriseMapsProvider.js
index caed15af4bea..5ac25bf96b81 100644
--- a/Source/Scene/GoogleEarthEnterpriseMapsProvider.js
+++ b/Source/Scene/GoogleEarthEnterpriseMapsProvider.js
@@ -15,26 +15,12 @@ import when from "../ThirdParty/when.js";
import ImageryProvider from "./ImageryProvider.js";
/**
- * Provides tiled imagery using the Google Earth Imagery API.
- *
- * Notes: This imagery provider does not work with the public Google Earth servers. It works with the
- * Google Earth Enterprise Server.
- *
- * By default the Google Earth Enterprise server does not set the
- * {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} headers. You can either
- * use a proxy server which adds these headers, or in the /opt/google/gehttpd/conf/gehttpd.conf
- * and add the 'Header set Access-Control-Allow-Origin "*"' option to the '<Directory />' and
- * '<Directory "/opt/google/gehttpd/htdocs">' directives.
- *
- * This provider is for use with 2D Maps API as part of Google Earth Enterprise. For 3D Earth API uses, it
- * is necessary to use {@link GoogleEarthEnterpriseImageryProvider}
+ * @typedef {Object} GoogleEarthEnterpriseMapsProvider.ConstructorOptions
*
- * @alias GoogleEarthEnterpriseMapsProvider
- * @constructor
+ * Initialization options for the GoogleEarthEnterpriseMapsProvider constructor
*
- * @param {Object} options Object with the following properties:
- * @param {Resource|String} options.url The url of the Google Earth server hosting the imagery.
- * @param {Number} options.channel The channel (id) to be used when requesting data from the server.
+ * @property {Resource|String} url The url of the Google Earth server hosting the imagery.
+ * @property {Number} channel The channel (id) to be used when requesting data from the server.
* The channel number can be found by looking at the json file located at:
* earth.localdomain/default_map/query?request=Json&vars=geeServerDefs The /default_map path may
* differ depending on your Google Earth Enterprise server configuration. Look for the "id" that
@@ -52,13 +38,34 @@ import ImageryProvider from "./ImageryProvider.js";
* }
* ]
* }
- * @param {String} [options.path="/default_map"] The path of the Google Earth server hosting the imagery.
- * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the Google Earth
+ * @property {String} [path="/default_map"] The path of the Google Earth server hosting the imagery.
+ * @property {Number} [maximumLevel] The maximum level-of-detail supported by the Google Earth
* Enterprise server, or undefined if there is no limit.
- * @param {TileDiscardPolicy} [options.tileDiscardPolicy] The policy that determines if a tile
+ * @property {TileDiscardPolicy} [tileDiscardPolicy] The policy that determines if a tile
* is invalid and should be discarded. To ensure that no tiles are discarded, construct and pass
* a {@link NeverTileDiscardPolicy} for this parameter.
- * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
+ * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
+ */
+
+/**
+ * Provides tiled imagery using the Google Earth Imagery API.
+ *
+ * Notes: This imagery provider does not work with the public Google Earth servers. It works with the
+ * Google Earth Enterprise Server.
+ *
+ * By default the Google Earth Enterprise server does not set the
+ * {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} headers. You can either
+ * use a proxy server which adds these headers, or in the /opt/google/gehttpd/conf/gehttpd.conf
+ * and add the 'Header set Access-Control-Allow-Origin "*"' option to the '<Directory />' and
+ * '<Directory "/opt/google/gehttpd/htdocs">' directives.
+ *
+ * This provider is for use with 2D Maps API as part of Google Earth Enterprise. For 3D Earth API uses, it
+ * is necessary to use {@link GoogleEarthEnterpriseImageryProvider}
+ *
+ * @alias GoogleEarthEnterpriseMapsProvider
+ * @constructor
+ *
+ * @param {GoogleEarthEnterpriseMapsProvider.ConstructorOptions} options Object describing initialization options
*
* @exception {RuntimeError} Could not find layer with channel (id) of options.channel
.
* @exception {RuntimeError} Could not find a version in channel (id) options.channel
.
@@ -94,6 +101,92 @@ function GoogleEarthEnterpriseMapsProvider(options) {
}
//>>includeEnd('debug');
+ /**
+ * The default alpha blending value of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultNightAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultDayAlpha = undefined;
+
+ /**
+ * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
+ * makes the imagery darker while greater than 1.0 makes it brighter.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultBrightness = undefined;
+
+ /**
+ * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
+ * the contrast while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultContrast = undefined;
+
+ /**
+ * The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultHue = undefined;
+
+ /**
+ * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
+ * saturation while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultSaturation = undefined;
+
+ /**
+ * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default 1.9
+ */
+ this.defaultGamma = 1.9;
+
+ /**
+ * The default texture minification filter to apply to this provider.
+ *
+ * @type {TextureMinificationFilter}
+ * @default undefined
+ */
+ this.defaultMinificationFilter = undefined;
+
+ /**
+ * The default texture magnification filter to apply to this provider.
+ *
+ * @type {TextureMagnificationFilter}
+ * @default undefined
+ */
+ this.defaultMagnificationFilter = undefined;
+
var url = options.url;
var path = defaultValue(options.path, "/default_map");
@@ -116,16 +209,6 @@ function GoogleEarthEnterpriseMapsProvider(options) {
'" title="Google Imagery"/>'
);
- /**
- * The default {@link ImageryLayer#gamma} to use for imagery layers created for this provider.
- * By default, this is set to 1.9. Changing this value after creating an {@link ImageryLayer} for this provider will have
- * no effect. Instead, set the layer's {@link ImageryLayer#gamma} property.
- *
- * @type {Number}
- * @default 1.9
- */
- this.defaultGamma = 1.9;
-
this._tilingScheme = undefined;
this._version = undefined;
@@ -360,7 +443,7 @@ Object.defineProperties(GoogleEarthEnterpriseMapsProvider.prototype, {
* Gets the maximum level-of-detail that can be requested. This function should
* not be called before {@link GoogleEarthEnterpriseMapsProvider#ready} returns true.
* @memberof GoogleEarthEnterpriseMapsProvider.prototype
- * @type {Number}
+ * @type {Number|undefined}
* @readonly
*/
maximumLevel: {
@@ -598,7 +681,7 @@ GoogleEarthEnterpriseMapsProvider.prototype.getTileCredits = function (
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level.
* @param {Request} [request] The request object. Intended for internal use only.
- * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
+ * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if there are too many active requests to the server, and the request
* should be retried later. The resolved image may be either an
* Image or a Canvas DOM object.
diff --git a/Source/Scene/GridImageryProvider.js b/Source/Scene/GridImageryProvider.js
index 7a89ae5379c1..1e780c0e6e15 100644
--- a/Source/Scene/GridImageryProvider.js
+++ b/Source/Scene/GridImageryProvider.js
@@ -9,30 +9,123 @@ var defaultColor = new Color(1.0, 1.0, 1.0, 0.4);
var defaultGlowColor = new Color(0.0, 1.0, 0.0, 0.05);
var defaultBackgroundColor = new Color(0.0, 0.5, 0.0, 0.2);
+/**
+ * @typedef {Object} GridImageryProvider.ConstructorOptions
+ *
+ * Initialization options for the GridImageryProvider constructor
+ *
+ * @param {TilingScheme} [tilingScheme=new GeographicTilingScheme()] The tiling scheme for which to draw tiles.
+ * @param {Ellipsoid} [ellipsoid] The ellipsoid. If the tilingScheme is specified,
+ * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither
+ * parameter is specified, the WGS84 ellipsoid is used.
+ * @param {Number} [cells=8] The number of grids cells.
+ * @param {Color} [color=Color(1.0, 1.0, 1.0, 0.4)] The color to draw grid lines.
+ * @param {Color} [glowColor=Color(0.0, 1.0, 0.0, 0.05)] The color to draw glow for grid lines.
+ * @param {Number} [glowWidth=6] The width of lines used for rendering the line glow effect.
+ * @param {Color} [backgroundColor=Color(0.0, 0.5, 0.0, 0.2)] Background fill color.
+ * @param {Number} [tileWidth=256] The width of the tile for level-of-detail selection purposes.
+ * @param {Number} [tileHeight=256] The height of the tile for level-of-detail selection purposes.
+ * @param {Number} [canvasSize=256] The size of the canvas used for rendering.
+ */
+
/**
* An {@link ImageryProvider} that draws a wireframe grid on every tile with controllable background and glow.
* May be useful for custom rendering effects or debugging terrain.
*
* @alias GridImageryProvider
* @constructor
+ * @param {GridImageryProvider.ConstructorOptions} options Object describing initialization options
*
- * @param {Object} [options] Object with the following properties:
- * @param {TilingScheme} [options.tilingScheme=new GeographicTilingScheme()] The tiling scheme for which to draw tiles.
- * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified,
- * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither
- * parameter is specified, the WGS84 ellipsoid is used.
- * @param {Number} [options.cells=8] The number of grids cells.
- * @param {Color} [options.color=Color(1.0, 1.0, 1.0, 0.4)] The color to draw grid lines.
- * @param {Color} [options.glowColor=Color(0.0, 1.0, 0.0, 0.05)] The color to draw glow for grid lines.
- * @param {Number} [options.glowWidth=6] The width of lines used for rendering the line glow effect.
- * @param {Color} [options.backgroundColor=Color(0.0, 0.5, 0.0, 0.2)] Background fill color.
- * @param {Number} [options.tileWidth=256] The width of the tile for level-of-detail selection purposes.
- * @param {Number} [options.tileHeight=256] The height of the tile for level-of-detail selection purposes.
- * @param {Number} [options.canvasSize=256] The size of the canvas used for rendering.
*/
function GridImageryProvider(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
+ /**
+ * The default alpha blending value of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultNightAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultDayAlpha = undefined;
+
+ /**
+ * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
+ * makes the imagery darker while greater than 1.0 makes it brighter.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultBrightness = undefined;
+
+ /**
+ * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
+ * the contrast while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultContrast = undefined;
+
+ /**
+ * The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultHue = undefined;
+
+ /**
+ * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
+ * saturation while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultSaturation = undefined;
+
+ /**
+ * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultGamma = undefined;
+
+ /**
+ * The default texture minification filter to apply to this provider.
+ *
+ * @type {TextureMinificationFilter}
+ * @default undefined
+ */
+ this.defaultMinificationFilter = undefined;
+
+ /**
+ * The default texture magnification filter to apply to this provider.
+ *
+ * @type {TextureMagnificationFilter}
+ * @default undefined
+ */
+ this.defaultMagnificationFilter = undefined;
+
this._tilingScheme = defined(options.tilingScheme)
? options.tilingScheme
: new GeographicTilingScheme({ ellipsoid: options.ellipsoid });
@@ -102,7 +195,7 @@ Object.defineProperties(GridImageryProvider.prototype, {
* Gets the maximum level-of-detail that can be requested. This function should
* not be called before {@link GridImageryProvider#ready} returns true.
* @memberof GridImageryProvider.prototype
- * @type {Number}
+ * @type {Number|undefined}
* @readonly
*/
maximumLevel: {
@@ -315,7 +408,7 @@ GridImageryProvider.prototype.getTileCredits = function (x, y, level) {
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level.
* @param {Request} [request] The request object. Intended for internal use only.
- * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
+ * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if there are too many active requests to the server, and the request
* should be retried later. The resolved image may be either an
* Image or a Canvas DOM object.
diff --git a/Source/Scene/GroundPolylinePrimitive.js b/Source/Scene/GroundPolylinePrimitive.js
index 7d42fc6e55da..9364a560423d 100644
--- a/Source/Scene/GroundPolylinePrimitive.js
+++ b/Source/Scene/GroundPolylinePrimitive.js
@@ -212,7 +212,7 @@ function GroundPolylinePrimitive(options) {
depthTest: {
enabled: true,
},
- blending: BlendingState.ALPHA_BLEND,
+ blending: BlendingState.PRE_MULTIPLIED_ALPHA_BLEND,
depthMask: false,
});
}
@@ -334,7 +334,7 @@ Object.defineProperties(GroundPolylinePrimitive.prototype, {
* Initializes the minimum and maximum terrain heights. This only needs to be called if you are creating the
* GroundPolylinePrimitive synchronously.
*
- * @returns {Promise} A promise that will resolve once the terrain heights have been loaded.
+ * @returns {Promise} A promise that will resolve once the terrain heights have been loaded.
*/
GroundPolylinePrimitive.initializeTerrainHeights = function () {
return ApproximateTerrainHeights.initialize();
@@ -487,7 +487,7 @@ function getRenderState(mask3DTiles) {
cull: {
enabled: true, // prevent double-draw. Geometry is "inverted" (reversed winding order) so we're drawing backfaces.
},
- blending: BlendingState.ALPHA_BLEND,
+ blending: BlendingState.PRE_MULTIPLIED_ALPHA_BLEND,
depthMask: false,
stencilTest: {
enabled: mask3DTiles,
diff --git a/Source/Scene/GroundPrimitive.js b/Source/Scene/GroundPrimitive.js
index 943e508d9157..e07d256f54ab 100644
--- a/Source/Scene/GroundPrimitive.js
+++ b/Source/Scene/GroundPrimitive.js
@@ -505,7 +505,7 @@ function createBoundingVolume(groundPrimitive, frameState, geometry) {
}
function boundingVolumeIndex(commandIndex, length) {
- return Math.floor((commandIndex % length) / 3);
+ return Math.floor((commandIndex % length) / 2);
}
function updateAndQueueRenderCommand(
@@ -626,7 +626,7 @@ function updateAndQueueCommands(
var ignoreShowCommands = classificationPrimitive._commandsIgnoreShow;
var ignoreShowCommandsLength = ignoreShowCommands.length;
for (i = 0; i < ignoreShowCommandsLength; ++i) {
- boundingVolume = boundingVolumes[Math.floor(i / 2)];
+ boundingVolume = boundingVolumes[i];
command = ignoreShowCommands[i];
updateAndQueueRenderCommand(
groundPrimitive,
@@ -685,7 +685,7 @@ function updateAndQueueCommands(
* Initializes the minimum and maximum terrain heights. This only needs to be called if you are creating the
* GroundPrimitive synchronously.
*
- * @returns {Promise} A promise that will resolve once the terrain heights have been loaded.
+ * @returns {Promise} A promise that will resolve once the terrain heights have been loaded.
*
*/
GroundPrimitive.initializeTerrainHeights = function () {
diff --git a/Source/Scene/HeightReference.js b/Source/Scene/HeightReference.js
index 11788d5210b8..5fcd6f3ba874 100644
--- a/Source/Scene/HeightReference.js
+++ b/Source/Scene/HeightReference.js
@@ -1,7 +1,7 @@
/**
* Represents the position relative to the terrain.
*
- * @exports HeightReference
+ * @enum {Number}
*/
var HeightReference = {
/**
diff --git a/Source/Scene/HorizontalOrigin.js b/Source/Scene/HorizontalOrigin.js
index f98f12188e8d..ab46bf910222 100644
--- a/Source/Scene/HorizontalOrigin.js
+++ b/Source/Scene/HorizontalOrigin.js
@@ -8,7 +8,7 @@
*
*
*
- * @exports HorizontalOrigin
+ * @enum {Number}
*
* @see Billboard#horizontalOrigin
* @see Label#horizontalOrigin
diff --git a/Source/Scene/ImageryLayer.js b/Source/Scene/ImageryLayer.js
index b8938689eff2..4cd1cb84b750 100644
--- a/Source/Scene/ImageryLayer.js
+++ b/Source/Scene/ImageryLayer.js
@@ -54,6 +54,18 @@ import TileImagery from "./TileImagery.js";
* current frame state, this layer, and the x, y, and level coordinates of the
* imagery tile for which the alpha is required, and it is expected to return
* the alpha value to use for the tile.
+ * @param {Number|Function} [options.nightAlpha=1.0] The alpha blending value of this layer on the night side of the globe, from 0.0 to 1.0.
+ * This can either be a simple number or a function with the signature
+ * function(frameState, layer, x, y, level)
. The function is passed the
+ * current frame state, this layer, and the x, y, and level coordinates of the
+ * imagery tile for which the alpha is required, and it is expected to return
+ * the alpha value to use for the tile. This only takes effect when enableLighting
is true
.
+ * @param {Number|Function} [options.dayAlpha=1.0] The alpha blending value of this layer on the day side of the globe, from 0.0 to 1.0.
+ * This can either be a simple number or a function with the signature
+ * function(frameState, layer, x, y, level)
. The function is passed the
+ * current frame state, this layer, and the x, y, and level coordinates of the
+ * imagery tile for which the alpha is required, and it is expected to return
+ * the alpha value to use for the tile. This only takes effect when enableLighting
is true
.
* @param {Number|Function} [options.brightness=1.0] The brightness of this layer. 1.0 uses the unmodified imagery
* color. Less than 1.0 makes the imagery darker while greater than 1.0 makes it brighter.
* This can either be a simple number or a function with the signature
@@ -131,6 +143,30 @@ function ImageryLayer(imageryProvider, options) {
defaultValue(imageryProvider.defaultAlpha, 1.0)
);
+ /**
+ * The alpha blending value of this layer on the night side of the globe, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque. This only takes effect when {@link Globe#enableLighting} is true
.
+ *
+ * @type {Number}
+ * @default 1.0
+ */
+ this.nightAlpha = defaultValue(
+ options.nightAlpha,
+ defaultValue(imageryProvider.defaultNightAlpha, 1.0)
+ );
+
+ /**
+ * The alpha blending value of this layer on the day side of the globe, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque. This only takes effect when {@link Globe#enableLighting} is true
.
+ *
+ * @type {Number}
+ * @default 1.0
+ */
+ this.dayAlpha = defaultValue(
+ options.dayAlpha,
+ defaultValue(imageryProvider.defaultDayAlpha, 1.0)
+ );
+
/**
* The brightness of this layer. 1.0 uses the unmodified imagery color. Less than 1.0
* makes the imagery darker while greater than 1.0 makes it brighter.
diff --git a/Source/Scene/ImageryLayerCollection.js b/Source/Scene/ImageryLayerCollection.js
index 0030cd8751d0..4184c37c92f6 100644
--- a/Source/Scene/ImageryLayerCollection.js
+++ b/Source/Scene/ImageryLayerCollection.js
@@ -74,7 +74,7 @@ Object.defineProperties(ImageryLayerCollection.prototype, {
*
* @param {ImageryLayer} layer the layer to add.
* @param {Number} [index] the index to add the layer at. If omitted, the layer will
- * added on top of all existing layers.
+ * be added on top of all existing layers.
*
* @exception {DeveloperError} index, if supplied, must be greater than or equal to zero and less than or equal to the number of the layers.
*/
diff --git a/Source/Scene/ImageryLayerFeatureInfo.js b/Source/Scene/ImageryLayerFeatureInfo.js
index 90f89d3a485e..6536bcebd9ab 100644
--- a/Source/Scene/ImageryLayerFeatureInfo.js
+++ b/Source/Scene/ImageryLayerFeatureInfo.js
@@ -9,34 +9,34 @@ import defined from "../Core/defined.js";
function ImageryLayerFeatureInfo() {
/**
* Gets or sets the name of the feature.
- * @type {String}
+ * @type {String|undefined}
*/
this.name = undefined;
/**
* Gets or sets an HTML description of the feature. The HTML is not trusted and should
* be sanitized before display to the user.
- * @type {String}
+ * @type {String|undefined}
*/
this.description = undefined;
/**
* Gets or sets the position of the feature, or undefined if the position is not known.
*
- * @type {Cartographic}
+ * @type {Cartographic|undefined}
*/
this.position = undefined;
/**
* Gets or sets the raw data describing the feature. The raw data may be in any
* number of formats, such as GeoJSON, KML, etc.
- * @type {Object}
+ * @type {Object|undefined}
*/
this.data = undefined;
/**
* Gets or sets the image layer of the feature.
- * @type {Object}
+ * @type {Object|undefined}
*/
this.imageryLayer = undefined;
}
diff --git a/Source/Scene/ImageryProvider.js b/Source/Scene/ImageryProvider.js
index 884a28d71ce2..77c53f6975a9 100644
--- a/Source/Scene/ImageryProvider.js
+++ b/Source/Scene/ImageryProvider.js
@@ -19,6 +19,7 @@ import Resource from "../Core/Resource.js";
* @see GoogleEarthEnterpriseImageryProvider
* @see GoogleEarthEnterpriseMapsProvider
* @see GridImageryProvider
+ * @see IonImageryProvider
* @see MapboxImageryProvider
* @see MapboxStyleImageryProvider
* @see SingleTileImageryProvider
@@ -35,16 +36,34 @@ function ImageryProvider() {
* The default alpha blending value of this provider, with 0.0 representing fully transparent and
* 1.0 representing fully opaque.
*
- * @type {Number}
+ * @type {Number|undefined}
* @default undefined
*/
this.defaultAlpha = undefined;
+ /**
+ * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultNightAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultDayAlpha = undefined;
+
/**
* The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
* makes the imagery darker while greater than 1.0 makes it brighter.
*
- * @type {Number}
+ * @type {Number|undefined}
* @default undefined
*/
this.defaultBrightness = undefined;
@@ -53,7 +72,7 @@ function ImageryProvider() {
* The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
* the contrast while greater than 1.0 increases it.
*
- * @type {Number}
+ * @type {Number|undefined}
* @default undefined
*/
this.defaultContrast = undefined;
@@ -61,7 +80,7 @@ function ImageryProvider() {
/**
* The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
*
- * @type {Number}
+ * @type {Number|undefined}
* @default undefined
*/
this.defaultHue = undefined;
@@ -70,7 +89,7 @@ function ImageryProvider() {
* The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
* saturation while greater than 1.0 increases it.
*
- * @type {Number}
+ * @type {Number|undefined}
* @default undefined
*/
this.defaultSaturation = undefined;
@@ -78,7 +97,7 @@ function ImageryProvider() {
/**
* The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
*
- * @type {Number}
+ * @type {Number|undefined}
* @default undefined
*/
this.defaultGamma = undefined;
@@ -160,7 +179,7 @@ Object.defineProperties(ImageryProvider.prototype, {
* Gets the maximum level-of-detail that can be requested. This function should
* not be called before {@link ImageryProvider#ready} returns true.
* @memberof ImageryProvider.prototype
- * @type {Number}
+ * @type {Number|undefined}
* @readonly
*/
maximumLevel: {
@@ -257,7 +276,6 @@ Object.defineProperties(ImageryProvider.prototype, {
/**
* Gets the credits to be displayed when a given tile is displayed.
- * @function
*
* @param {Number} x The tile X coordinate.
* @param {Number} y The tile Y coordinate.
@@ -266,26 +284,28 @@ Object.defineProperties(ImageryProvider.prototype, {
*
* @exception {DeveloperError} getTileCredits
must not be called before the imagery provider is ready.
*/
-ImageryProvider.prototype.getTileCredits =
- DeveloperError.throwInstantiationError;
+ImageryProvider.prototype.getTileCredits = function (x, y, level) {
+ DeveloperError.throwInstantiationError();
+};
/**
* Requests the image for a given tile. This function should
* not be called before {@link ImageryProvider#ready} returns true.
- * @function
*
* @param {Number} x The tile X coordinate.
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level.
* @param {Request} [request] The request object. Intended for internal use only.
- * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
+ * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if there are too many active requests to the server, and the request
* should be retried later. The resolved image may be either an
* Image or a Canvas DOM object.
*
* @exception {DeveloperError} requestImage
must not be called before the imagery provider is ready.
*/
-ImageryProvider.prototype.requestImage = DeveloperError.throwInstantiationError;
+ImageryProvider.prototype.requestImage = function (x, y, level, request) {
+ DeveloperError.throwInstantiationError();
+};
/**
* Asynchronously determines what features, if any, are located at a given longitude and latitude within
@@ -306,7 +326,15 @@ ImageryProvider.prototype.requestImage = DeveloperError.throwInstantiationError;
*
* @exception {DeveloperError} pickFeatures
must not be called before the imagery provider is ready.
*/
-ImageryProvider.prototype.pickFeatures = DeveloperError.throwInstantiationError;
+ImageryProvider.prototype.pickFeatures = function (
+ x,
+ y,
+ level,
+ longitude,
+ latitude
+) {
+ DeveloperError.throwInstantiationError();
+};
var ktxRegex = /\.ktx$/i;
var crnRegex = /\.crn$/i;
@@ -318,7 +346,7 @@ var crnRegex = /\.crn$/i;
*
* @param {ImageryProvider} imageryProvider The imagery provider for the URL.
* @param {Resource|String} url The URL of the image.
- * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
+ * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if there are too many active requests to the server, and the request
* should be retried later. The resolved image may be either an
* Image or a Canvas DOM object.
diff --git a/Source/Scene/ImagerySplitDirection.js b/Source/Scene/ImagerySplitDirection.js
index 84b6e4be79ce..0778b4021d01 100644
--- a/Source/Scene/ImagerySplitDirection.js
+++ b/Source/Scene/ImagerySplitDirection.js
@@ -1,7 +1,7 @@
/**
* The direction to display an ImageryLayer relative to the {@link Scene#imagerySplitPosition}.
*
- * @exports ImagerySplitDirection
+ * @enum {Number}
*
* @see ImageryLayer#splitDirection
*/
diff --git a/Source/Scene/IonImageryProvider.js b/Source/Scene/IonImageryProvider.js
index 806449949d30..d13495957e94 100644
--- a/Source/Scene/IonImageryProvider.js
+++ b/Source/Scene/IonImageryProvider.js
@@ -36,16 +36,23 @@ var ImageryProviderMapping = {
WMTS: createFactory(WebMapTileServiceImageryProvider),
};
+/**
+ * @typedef {Object} IonImageryProvider.ConstructorOptions
+ *
+ * Initialization options for the TileMapServiceImageryProvider constructor
+ *
+ * @property {Number} assetId An ion imagery asset ID
+ * @property {String} [accessToken=Ion.defaultAccessToken] The access token to use.
+ * @property {String|Resource} [server=Ion.defaultServer] The resource to the Cesium ion API server.
+ */
+
/**
* Provides tiled imagery using the Cesium ion REST API.
*
* @alias IonImageryProvider
* @constructor
*
- * @param {Object} options Object with the following properties:
- * @param {Number} options.assetId An ion imagery asset ID;
- * @param {String} [options.accessToken=Ion.defaultAccessToken] The access token to use.
- * @param {String|Resource} [options.server=Ion.defaultServer] The resource to the Cesium ion API server.
+ * @param {IonImageryProvider.ConstructorOptions} options Object describing initialization options
*
* @example
* viewer.imageryLayers.addImageryProvider(new Cesium.IonImageryProvider({ assetId : 23489024 }));
@@ -62,16 +69,34 @@ function IonImageryProvider(options) {
* The default alpha blending value of this provider, with 0.0 representing fully transparent and
* 1.0 representing fully opaque.
*
- * @type {Number}
+ * @type {Number|undefined}
* @default undefined
*/
this.defaultAlpha = undefined;
+ /**
+ * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultNightAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultDayAlpha = undefined;
+
/**
* The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
* makes the imagery darker while greater than 1.0 makes it brighter.
*
- * @type {Number}
+ * @type {Number|undefined}
* @default undefined
*/
this.defaultBrightness = undefined;
@@ -80,7 +105,7 @@ function IonImageryProvider(options) {
* The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
* the contrast while greater than 1.0 increases it.
*
- * @type {Number}
+ * @type {Number|undefined}
* @default undefined
*/
this.defaultContrast = undefined;
@@ -88,7 +113,7 @@ function IonImageryProvider(options) {
/**
* The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
*
- * @type {Number}
+ * @type {Number|undefined}
* @default undefined
*/
this.defaultHue = undefined;
@@ -97,7 +122,7 @@ function IonImageryProvider(options) {
* The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
* saturation while greater than 1.0 increases it.
*
- * @type {Number}
+ * @type {Number|undefined}
* @default undefined
*/
this.defaultSaturation = undefined;
@@ -105,7 +130,7 @@ function IonImageryProvider(options) {
/**
* The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
*
- * @type {Number}
+ * @type {Number|undefined}
* @default undefined
*/
this.defaultGamma = undefined;
@@ -282,7 +307,7 @@ Object.defineProperties(IonImageryProvider.prototype, {
* Gets the maximum level-of-detail that can be requested. This function should
* not be called before {@link IonImageryProvider#ready} returns true.
* @memberof IonImageryProvider.prototype
- * @type {Number}
+ * @type {Number|undefined}
* @readonly
*/
maximumLevel: {
@@ -420,6 +445,19 @@ Object.defineProperties(IonImageryProvider.prototype, {
//>>includeEnd('debug');
return this._imageryProvider.hasAlphaChannel;
},
+
+ /**
+ * Gets the proxy used by this provider.
+ * @memberof IonImageryProvider.prototype
+ * @type {Proxy}
+ * @readonly
+ * @default undefined
+ */
+ proxy: {
+ get: function () {
+ return undefined;
+ },
+ },
},
});
@@ -460,7 +498,7 @@ IonImageryProvider.prototype.getTileCredits = function (x, y, level) {
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level.
* @param {Request} [request] The request object. Intended for internal use only.
- * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
+ * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if there are too many active requests to the server, and the request
* should be retried later. The resolved image may be either an
* Image or a Canvas DOM object.
diff --git a/Source/Scene/IonWorldImageryStyle.js b/Source/Scene/IonWorldImageryStyle.js
index cf7b325c15de..824de2cb4fdd 100644
--- a/Source/Scene/IonWorldImageryStyle.js
+++ b/Source/Scene/IonWorldImageryStyle.js
@@ -3,7 +3,7 @@
/**
* The types of imagery provided by {@link createWorldImagery}.
*
- * @exports IonWorldImageryStyle
+ * @enum {Number}
*/
var IonWorldImageryStyle = {
/**
diff --git a/Source/Scene/Label.js b/Source/Scene/Label.js
index e86977c254c9..8108aa5a5669 100644
--- a/Source/Scene/Label.js
+++ b/Source/Scene/Label.js
@@ -621,7 +621,7 @@ Object.defineProperties(Label.prototype, {
/**
* Gets or sets near and far translucency properties of a Label based on the Label's distance from the camera.
* A label's translucency will interpolate between the {@link NearFarScalar#nearValue} and
- * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds
+ * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds
* of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}.
* Outside of these ranges the label's translucency remains clamped to the nearest bound. If undefined,
* translucencyByDistance will be disabled.
@@ -678,7 +678,7 @@ Object.defineProperties(Label.prototype, {
/**
* Gets or sets near and far pixel offset scaling properties of a Label based on the Label's distance from the camera.
* A label's pixel offset will be scaled between the {@link NearFarScalar#nearValue} and
- * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds
+ * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds
* of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}.
* Outside of these ranges the label's pixel offset scaling remains clamped to the nearest bound. If undefined,
* pixelOffsetScaleByDistance will be disabled.
@@ -736,7 +736,7 @@ Object.defineProperties(Label.prototype, {
/**
* Gets or sets near and far scaling properties of a Label based on the label's distance from the camera.
* A label's scale will interpolate between the {@link NearFarScalar#nearValue} and
- * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds
+ * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds
* of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}.
* Outside of these ranges the label's scale remains clamped to the nearest bound. If undefined,
* scaleByDistance will be disabled.
diff --git a/Source/Scene/LabelStyle.js b/Source/Scene/LabelStyle.js
index 4412141dc9d7..10517de8aff3 100644
--- a/Source/Scene/LabelStyle.js
+++ b/Source/Scene/LabelStyle.js
@@ -1,7 +1,7 @@
/**
* Describes how to draw a label.
*
- * @exports LabelStyle
+ * @enum {Number}
*
* @see Label#style
*/
diff --git a/Source/Scene/MapMode2D.js b/Source/Scene/MapMode2D.js
index 3663f43a68db..7e1d8b538dce 100644
--- a/Source/Scene/MapMode2D.js
+++ b/Source/Scene/MapMode2D.js
@@ -1,7 +1,7 @@
/**
* Describes how the map will operate in 2D.
*
- * @exports MapMode2D
+ * @enum {Number}
*/
var MapMode2D = {
/**
diff --git a/Source/Scene/MapboxImageryProvider.js b/Source/Scene/MapboxImageryProvider.js
index e27c0e8eb83d..79caf55821b6 100644
--- a/Source/Scene/MapboxImageryProvider.js
+++ b/Source/Scene/MapboxImageryProvider.js
@@ -12,24 +12,30 @@ var defaultCredit = new Credit(
);
/**
- * Provides tiled imagery hosted by Mapbox.
+ * @typedef {Object} MapboxImageryProvider.ConstructorOptions
*
- * @alias MapboxImageryProvider
- * @constructor
+ * Initialization options for the MapboxImageryProvider constructor
*
- * @param {Object} [options] Object with the following properties:
- * @param {String} [options.url='https://api.mapbox.com/v4/'] The Mapbox server url.
- * @param {String} options.mapId The Mapbox Map ID.
- * @param {String} [options.accessToken] The public access token for the imagery.
- * @param {String} [options.format='png'] The format of the image request.
- * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
- * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying
+ * @property {String} [url='https://api.mapbox.com/v4/'] The Mapbox server url.
+ * @property {String} mapId The Mapbox Map ID.
+ * @property {String} [accessToken] The public access token for the imagery.
+ * @property {String} [format='png'] The format of the image request.
+ * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
+ * @property {Number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying
* this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely
* to result in rendering problems.
- * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
- * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image.
- * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas.
+ * @property {Number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
+ * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image.
+ * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas.
+ */
+
+/**
+ * Provides tiled imagery hosted by Mapbox.
*
+ * @alias MapboxImageryProvider
+ * @constructor
+ *
+ * @param {MapboxImageryProvider.ConstructorOptions} options Object describing initialization options
*
* @example
* // Mapbox tile provider
@@ -50,6 +56,92 @@ function MapboxImageryProvider(options) {
}
//>>includeEnd('debug');
+ /**
+ * The default alpha blending value of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultNightAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultDayAlpha = undefined;
+
+ /**
+ * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
+ * makes the imagery darker while greater than 1.0 makes it brighter.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultBrightness = undefined;
+
+ /**
+ * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
+ * the contrast while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultContrast = undefined;
+
+ /**
+ * The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultHue = undefined;
+
+ /**
+ * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
+ * saturation while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultSaturation = undefined;
+
+ /**
+ * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultGamma = undefined;
+
+ /**
+ * The default texture minification filter to apply to this provider.
+ *
+ * @type {TextureMinificationFilter}
+ * @default undefined
+ */
+ this.defaultMinificationFilter = undefined;
+
+ /**
+ * The default texture magnification filter to apply to this provider.
+ *
+ * @type {TextureMagnificationFilter}
+ * @default undefined
+ */
+ this.defaultMagnificationFilter = undefined;
+
var resource = Resource.createIfNeeded(
defaultValue(options.url, "https://{s}.tiles.mapbox.com/v4/")
);
@@ -179,7 +271,7 @@ Object.defineProperties(MapboxImageryProvider.prototype, {
* Gets the maximum level-of-detail that can be requested. This function should
* not be called before {@link MapboxImageryProvider#ready} returns true.
* @memberof MapboxImageryProvider.prototype
- * @type {Number}
+ * @type {Number|undefined}
* @readonly
*/
maximumLevel: {
@@ -314,7 +406,7 @@ MapboxImageryProvider.prototype.getTileCredits = function (x, y, level) {
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level.
* @param {Request} [request] The request object. Intended for internal use only.
- * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
+ * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if there are too many active requests to the server, and the request
* should be retried later. The resolved image may be either an
* Image or a Canvas DOM object.
diff --git a/Source/Scene/MapboxStyleImageryProvider.js b/Source/Scene/MapboxStyleImageryProvider.js
index a52b5972b4e3..6c51a414b32f 100644
--- a/Source/Scene/MapboxStyleImageryProvider.js
+++ b/Source/Scene/MapboxStyleImageryProvider.js
@@ -12,26 +12,32 @@ var defaultCredit = new Credit(
);
/**
- * Provides tiled imagery hosted by Mapbox.
+ * @typedef {Object} MapboxStyleImageryProvider.ConstructorOptions
*
- * @alias MapboxStyleImageryProvider
- * @constructor
+ * Initialization options for the MapboxStyleImageryProvider constructor
*
- * @param {Object} [options] Object with the following properties:
- * @param {Resource|String} [options.url='https://api.mapbox.com/styles/v1/'] The Mapbox server url.
- * @param {String} [options.username='mapbox'] The username of the map account.
- * @param {String} options.styleId The Mapbox Style ID.
- * @param {String} [options.accessToken] The public access token for the imagery.
- * @param {Number} [options.tilesize=512] The size of the image tiles.
- * @param {Boolean} [options.scaleFactor] Determines if tiles are rendered at a @2x scale factor.
- * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
- * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying
+ * @property {Resource|String} [url='https://api.mapbox.com/styles/v1/'] The Mapbox server url.
+ * @property {String} [username='mapbox'] The username of the map account.
+ * @property {String} styleId The Mapbox Style ID.
+ * @property {String} [accessToken] The public access token for the imagery.
+ * @property {Number} [tilesize=512] The size of the image tiles.
+ * @property {Boolean} [scaleFactor] Determines if tiles are rendered at a @2x scale factor.
+ * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
+ * @property {Number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying
* this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely
* to result in rendering problems.
- * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
- * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image.
- * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas.
+ * @property {Number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
+ * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image.
+ * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas.
+ */
+
+/**
+ * Provides tiled imagery hosted by Mapbox.
*
+ * @alias MapboxStyleImageryProvider
+ * @constructor
+ *
+ * @param {MapboxStyleImageryProvider.ConstructorOptions} options Object describing initialization options
*
* @example
* // Mapbox style provider
@@ -52,6 +58,92 @@ function MapboxStyleImageryProvider(options) {
}
//>>includeEnd('debug');
+ /**
+ * The default alpha blending value of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultNightAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultDayAlpha = undefined;
+
+ /**
+ * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
+ * makes the imagery darker while greater than 1.0 makes it brighter.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultBrightness = undefined;
+
+ /**
+ * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
+ * the contrast while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultContrast = undefined;
+
+ /**
+ * The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultHue = undefined;
+
+ /**
+ * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
+ * saturation while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultSaturation = undefined;
+
+ /**
+ * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultGamma = undefined;
+
+ /**
+ * The default texture minification filter to apply to this provider.
+ *
+ * @type {TextureMinificationFilter}
+ * @default undefined
+ */
+ this.defaultMinificationFilter = undefined;
+
+ /**
+ * The default texture magnification filter to apply to this provider.
+ *
+ * @type {TextureMagnificationFilter}
+ * @default undefined
+ */
+ this.defaultMagnificationFilter = undefined;
+
var resource = Resource.createIfNeeded(
defaultValue(options.url, "https://api.mapbox.com/styles/v1/")
);
@@ -191,7 +283,7 @@ Object.defineProperties(MapboxStyleImageryProvider.prototype, {
* Gets the maximum level-of-detail that can be requested. This function should
* not be called before {@link MapboxStyleImageryProvider#ready} returns true.
* @memberof MapboxStyleImageryProvider.prototype
- * @type {Number}
+ * @type {Number|undefined}
* @readonly
*/
maximumLevel: {
@@ -326,7 +418,7 @@ MapboxStyleImageryProvider.prototype.getTileCredits = function (x, y, level) {
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level.
* @param {Request} [request] The request object. Intended for internal use only.
- * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
+ * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if there are too many active requests to the server, and the request
* should be retried later. The resolved image may be either an
* Image or a Canvas DOM object.
diff --git a/Source/Scene/MaterialAppearance.js b/Source/Scene/MaterialAppearance.js
index e5a69b513abc..e0770a047378 100644
--- a/Source/Scene/MaterialAppearance.js
+++ b/Source/Scene/MaterialAppearance.js
@@ -22,11 +22,11 @@ import Material from "./Material.js";
* @param {Boolean} [options.faceForward=!options.closed] When true
, the fragment shader flips the surface normal as needed to ensure that the normal faces the viewer to avoid dark spots. This is useful when both sides of a geometry should be shaded like {@link WallGeometry}.
* @param {Boolean} [options.translucent=true] When true
, the geometry is expected to appear translucent so {@link MaterialAppearance#renderState} has alpha blending enabled.
* @param {Boolean} [options.closed=false] When true
, the geometry is expected to be closed so {@link MaterialAppearance#renderState} has backface culling enabled.
- * @param {MaterialAppearance.MaterialSupport} [options.materialSupport=MaterialAppearance.MaterialSupport.TEXTURED] The type of materials that will be supported.
+ * @param {MaterialAppearance.MaterialSupportType} [options.materialSupport=MaterialAppearance.MaterialSupport.TEXTURED] The type of materials that will be supported.
* @param {Material} [options.material=Material.ColorType] The material used to determine the fragment color.
* @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader.
* @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader.
- * @param {RenderState} [options.renderState] Optional render state to override the default render state.
+ * @param {Object} [options.renderState] Optional render state to override the default render state.
*
* @see {@link https://github.com/CesiumGS/cesium/wiki/Fabric|Fabric}
* @demo {@link https://sandcastle.cesium.com/index.html?src=Materials.html|Cesium Sandcastle Material Appearance Demo}
@@ -177,7 +177,7 @@ Object.defineProperties(MaterialAppearance.prototype, {
*
* @memberof MaterialAppearance.prototype
*
- * @type {MaterialAppearance.MaterialSupport}
+ * @type {MaterialAppearance.MaterialSupportType}
* @readonly
*
* @default {@link MaterialAppearance.MaterialSupport.TEXTURED}
@@ -276,18 +276,27 @@ MaterialAppearance.prototype.isTranslucent = Appearance.prototype.isTranslucent;
MaterialAppearance.prototype.getRenderState =
Appearance.prototype.getRenderState;
+/**
+ * @typedef MaterialAppearance.MaterialSupportType
+ * @type {Object}
+ * @property {VertexFormat} vertexFormat
+ * @property {String} vertexShaderSource
+ * @property {String} fragmentShaderSource
+ */
+
/**
* Determines the type of {@link Material} that is supported by a
* {@link MaterialAppearance} instance. This is a trade-off between
* flexibility (a wide array of materials) and memory/performance
* (required vertex format and GLSL shader complexity.
- * @exports MaterialAppearance.MaterialSupport
+ * @namespace
*/
MaterialAppearance.MaterialSupport = {
/**
* Only basic materials, which require just position
and
* normal
vertex attributes, are supported.
*
+ * @type {MaterialAppearance.MaterialSupportType}
* @constant
*/
BASIC: Object.freeze({
@@ -300,6 +309,7 @@ MaterialAppearance.MaterialSupport = {
* normal
, and st
vertex attributes,
* are supported. The vast majority of materials fall into this category.
*
+ * @type {MaterialAppearance.MaterialSupportType}
* @constant
*/
TEXTURED: Object.freeze({
@@ -312,6 +322,7 @@ MaterialAppearance.MaterialSupport = {
* This requires position
, normal
, st
,
* tangent
, and bitangent
vertex attributes.
*
+ * @type {MaterialAppearance.MaterialSupportType}
* @constant
*/
ALL: Object.freeze({
diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js
index 6720690cb6db..f337048d58c4 100644
--- a/Source/Scene/Model.js
+++ b/Source/Scene/Model.js
@@ -4388,7 +4388,7 @@ function applySkins(model) {
computedJointMatrices[m]
);
if (defined(bindShapeMatrix)) {
- // Optimization for when bind shape matrix is the identity.
+ // NOTE: bindShapeMatrix is glTF 1.0 only, removed in glTF 2.0.
computedJointMatrices[m] = Matrix4.multiplyTransformation(
computedJointMatrices[m],
bindShapeMatrix,
diff --git a/Source/Scene/ModelAnimationLoop.js b/Source/Scene/ModelAnimationLoop.js
index cda8146ea601..3cb0a59948e9 100644
--- a/Source/Scene/ModelAnimationLoop.js
+++ b/Source/Scene/ModelAnimationLoop.js
@@ -1,7 +1,7 @@
/**
* Determines if and how a glTF animation is looped.
*
- * @exports ModelAnimationLoop
+ * @enum {Number}
*
* @see ModelAnimationCollection#add
*/
diff --git a/Source/Scene/ModelOutlineLoader.js b/Source/Scene/ModelOutlineLoader.js
index eb50d33f5889..d8561055255c 100644
--- a/Source/Scene/ModelOutlineLoader.js
+++ b/Source/Scene/ModelOutlineLoader.js
@@ -8,6 +8,10 @@ import TextureMinificationFilter from "../Renderer/TextureMinificationFilter.js"
import TextureWrap from "../Renderer/TextureWrap.js";
import ForEach from "../ThirdParty/GltfPipeline/ForEach.js";
+// glTF does not allow an index value of 65535 because this is the primitive
+// restart value in some APIs.
+var MAX_GLTF_UINT16_INDEX = 65534;
+
/**
* Creates face outlines for glTF primitives with the `CESIUM_primitive_outline` extension.
* @private
@@ -273,7 +277,10 @@ function addOutline(
vertexCopies[unmatchableVertexIndex] = copy;
}
- if (copy >= 65536 && triangleIndices instanceof Uint16Array) {
+ if (
+ copy > MAX_GLTF_UINT16_INDEX &&
+ triangleIndices instanceof Uint16Array
+ ) {
// We outgrew a 16-bit index buffer, switch to 32-bit.
triangleIndices = new Uint32Array(triangleIndices);
triangleIndexAccessorGltf.componentType = 5125; // UNSIGNED_INT
@@ -295,6 +302,15 @@ function addOutline(
0,
triangleIndices.byteLength
);
+
+ // The index componentType is also squirreled away in ModelLoadResources.
+ // Hackily update it, or else we'll end up creating the wrong type
+ // of index buffer later.
+ loadResources.indexBuffersToCreate._array.forEach(function (toCreate) {
+ if (toCreate.id === triangleIndexAccessorGltf.bufferView) {
+ toCreate.componentType = triangleIndexAccessorGltf.componentType;
+ }
+ });
}
if (unmatchableVertexIndex === i0) {
diff --git a/Source/Scene/ModelUtility.js b/Source/Scene/ModelUtility.js
index 1f41ba6356ab..44103a7c1878 100644
--- a/Source/Scene/ModelUtility.js
+++ b/Source/Scene/ModelUtility.js
@@ -70,13 +70,13 @@ ModelUtility.splitIncompatibleMaterials = function (gltf) {
var jointAccessorId = primitive.attributes.JOINTS_0;
var componentType;
- var type;
+ var accessorType;
if (defined(jointAccessorId)) {
var jointAccessor = accessors[jointAccessorId];
componentType = jointAccessor.componentType;
- type = jointAccessor.type;
+ accessorType = jointAccessor.type;
}
- var isSkinned = defined(jointAccessorId);
+ var isSkinned = defined(jointAccessorId) && accessorType === "VEC4";
var hasVertexColors = defined(primitive.attributes.COLOR_0);
var hasMorphTargets = defined(primitive.targets);
var hasNormals = defined(primitive.attributes.NORMAL);
@@ -92,7 +92,6 @@ ModelUtility.splitIncompatibleMaterials = function (gltf) {
skinning: {
skinned: isSkinned,
componentType: componentType,
- type: type,
},
hasVertexColors: hasVertexColors,
hasMorphTargets: hasMorphTargets,
@@ -103,7 +102,6 @@ ModelUtility.splitIncompatibleMaterials = function (gltf) {
};
} else if (
primitiveInfo.skinning.skinned !== isSkinned ||
- primitiveInfo.skinning.type !== type ||
primitiveInfo.hasVertexColors !== hasVertexColors ||
primitiveInfo.hasMorphTargets !== hasMorphTargets ||
primitiveInfo.hasNormals !== hasNormals ||
@@ -124,7 +122,6 @@ ModelUtility.splitIncompatibleMaterials = function (gltf) {
skinning: {
skinned: isSkinned,
componentType: componentType,
- type: type,
},
hasVertexColors: hasVertexColors,
hasMorphTargets: hasMorphTargets,
diff --git a/Source/Scene/NeverTileDiscardPolicy.js b/Source/Scene/NeverTileDiscardPolicy.js
index 3bccb7882442..77b6035d8435 100644
--- a/Source/Scene/NeverTileDiscardPolicy.js
+++ b/Source/Scene/NeverTileDiscardPolicy.js
@@ -19,7 +19,7 @@ NeverTileDiscardPolicy.prototype.isReady = function () {
/**
* Given a tile image, decide whether to discard that image.
*
- * @param {Image} image An image to test.
+ * @param {HTMLImageElement} image An image to test.
* @returns {Boolean} True if the image should be discarded; otherwise, false.
*/
NeverTileDiscardPolicy.prototype.shouldDiscardImage = function (image) {
diff --git a/Source/Scene/OctahedralProjectedCubeMap.js b/Source/Scene/OctahedralProjectedCubeMap.js
index 1a3f753e7b32..1de61027cc73 100644
--- a/Source/Scene/OctahedralProjectedCubeMap.js
+++ b/Source/Scene/OctahedralProjectedCubeMap.js
@@ -93,7 +93,7 @@ Object.defineProperties(OctahedralProjectedCubeMap.prototype, {
/**
* Gets a promise that resolves when the texture atlas is ready to use.
* @memberof OctahedralProjectedCubeMap.prototype
- * @type {Promise}
+ * @type {Promise}
* @readonly
*/
readyPromise: {
diff --git a/Source/Scene/OpenStreetMapImageryProvider.js b/Source/Scene/OpenStreetMapImageryProvider.js
index 7f869ee5cae4..f5ca4bbdbf5a 100644
--- a/Source/Scene/OpenStreetMapImageryProvider.js
+++ b/Source/Scene/OpenStreetMapImageryProvider.js
@@ -11,6 +11,20 @@ var defaultCredit = new Credit(
"MapQuest, Open Street Map and contributors, CC-BY-SA"
);
+/**
+ * @typedef {Object} OpenStreetMapImageryProvider.ConstructorOptions
+ *
+ * Initialization options for the OpenStreetMapImageryProvider constructor
+ *
+ * @property {String} [url='https://a.tile.openstreetmap.org'] The OpenStreetMap server url.
+ * @property {String} [fileExtension='png'] The file extension for images on the server.
+ * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle of the layer.
+ * @property {Number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider.
+ * @property {Number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
+ * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
+ * @property {Credit|String} [credit='MapQuest, Open Street Map and contributors, CC-BY-SA'] A credit for the data source, which is displayed on the canvas.
+ */
+
/**
* An imagery provider that provides tiled imagery hosted by OpenStreetMap
* or another provider of Slippy tiles. The default url connects to OpenStreetMap's volunteer-run
@@ -19,17 +33,9 @@ var defaultCredit = new Credit(
*
* @alias OpenStreetMapImageryProvider
* @constructor
+ * @extends UrlTemplateImageryProvider
*
- * @param {Object} [options] Object with the following properties:
- * @param {String} [options.url='https://a.tile.openstreetmap.org'] The OpenStreetMap server url.
- * @param {String} [options.fileExtension='png'] The file extension for images on the server.
- * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle of the layer.
- * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider.
- * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
- * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
- * @param {Credit|String} [options.credit='MapQuest, Open Street Map and contributors, CC-BY-SA'] A credit for the data source, which is displayed on the canvas.
- * @returns {UrlTemplateImageryProvider} The imagery provider.
- *
+ * @param {OpenStreetMapImageryProvider.ConstructorOptions} options Object describing initialization options
* @exception {DeveloperError} The rectangle and minimumLevel indicate that there are more than four tiles at the minimum level. Imagery providers with more than four tiles at the minimum level are not supported.
*
* @see ArcGisMapServerImageryProvider
@@ -41,7 +47,6 @@ var defaultCredit = new Credit(
* @see WebMapTileServiceImageryProvider
* @see UrlTemplateImageryProvider
*
- *
* @example
* var osm = new Cesium.OpenStreetMapImageryProvider({
* url : 'https://a.tile.openstreetmap.org/'
diff --git a/Source/Scene/ParticleSystem.js b/Source/Scene/ParticleSystem.js
index d18aff1c3a19..5169caa227f6 100644
--- a/Source/Scene/ParticleSystem.js
+++ b/Source/Scene/ParticleSystem.js
@@ -23,7 +23,7 @@ var defaultImageSize = new Cartesian2(1.0, 1.0);
*
* @param {Object} [options] Object with the following properties:
* @param {Boolean} [options.show=true] Whether to display the particle system.
- * @param {ParticleSystem~updateCallback} [options.updateCallback] The callback function to be called each frame to update a particle.
+ * @param {ParticleSystem.updateCallback} [options.updateCallback] The callback function to be called each frame to update a particle.
* @param {ParticleEmitter} [options.emitter=new CircleEmitter(0.5)] The particle emitter for this system.
* @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the particle system from model to world coordinates.
* @param {Matrix4} [options.emitterModelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the particle system emitter within the particle systems local coordinate system.
@@ -67,7 +67,7 @@ function ParticleSystem(options) {
/**
* An array of force callbacks. The callback is passed a {@link Particle} and the difference from the last time
- * @type {ParticleSystem~updateCallback}
+ * @type {ParticleSystem.updateCallback}
* @default undefined
*/
this.updateCallback = options.updateCallback;
@@ -894,7 +894,7 @@ ParticleSystem.prototype.destroy = function () {
* A function used to modify attributes of the particle at each time step. This can include force modifications,
* color, sizing, etc.
*
- * @callback ParticleSystem~updateCallback
+ * @callback ParticleSystem.updateCallback
*
* @param {Particle} particle The particle being updated.
* @param {Number} dt The time in seconds since the last update.
diff --git a/Source/Scene/PerInstanceColorAppearance.js b/Source/Scene/PerInstanceColorAppearance.js
index bcc1d7eb9f45..79fc05bceea8 100644
--- a/Source/Scene/PerInstanceColorAppearance.js
+++ b/Source/Scene/PerInstanceColorAppearance.js
@@ -21,7 +21,7 @@ import Appearance from "./Appearance.js";
* @param {Boolean} [options.closed=false] When true
, the geometry is expected to be closed so {@link PerInstanceColorAppearance#renderState} has backface culling enabled.
* @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader.
* @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader.
- * @param {RenderState} [options.renderState] Optional render state to override the default render state.
+ * @param {Object} [options.renderState] Optional render state to override the default render state.
*
* @example
* // A solid white line segment
diff --git a/Source/Scene/PointCloud.js b/Source/Scene/PointCloud.js
index 0193c2d79444..cf49e1a873d0 100644
--- a/Source/Scene/PointCloud.js
+++ b/Source/Scene/PointCloud.js
@@ -3,6 +3,7 @@ import BoundingSphere from "../Core/BoundingSphere.js";
import Cartesian3 from "../Core/Cartesian3.js";
import Cartesian4 from "../Core/Cartesian4.js";
import Check from "../Core/Check.js";
+import clone from "../Core/clone.js";
import Color from "../Core/Color.js";
import combine from "../Core/combine.js";
import ComponentDatatype from "../Core/ComponentDatatype.js";
@@ -972,16 +973,27 @@ function createUniformMap(pointCloud, frameState) {
pointCloud._drawCommand.uniformMap = uniformMap;
}
-var defaultProperties = ["POSITION", "COLOR", "NORMAL", "POSITION_ABSOLUTE"];
+function getStyleablePropertyIds(source, propertyIds) {
+ // Get all the property IDs used by this style
+ var regex = /czm_3dtiles_property_(\d+)/g;
+ var matches = regex.exec(source);
+ while (matches !== null) {
+ var id = parseInt(matches[1]);
+ if (propertyIds.indexOf(id) === -1) {
+ propertyIds.push(id);
+ }
+ matches = regex.exec(source);
+ }
+}
-function getStyleableProperties(source, properties) {
- // Get all the properties used by this style
- var regex = /czm_tiles3d_style_(\w+)/g;
+function getBuiltinPropertyNames(source, propertyNames) {
+ // Get all the builtin property names used by this style
+ var regex = /czm_3dtiles_builtin_property_(\w+)/g;
var matches = regex.exec(source);
while (matches !== null) {
var name = matches[1];
- if (properties.indexOf(name) === -1) {
- properties.push(name);
+ if (propertyNames.indexOf(name) === -1) {
+ propertyNames.push(name);
}
matches = regex.exec(source);
}
@@ -997,24 +1009,24 @@ function getVertexAttribute(vertexArray, index) {
}
}
-function modifyStyleFunction(source) {
- // Replace occurrences of czm_tiles3d_style_DEFAULTPROPERTY
- var length = defaultProperties.length;
- for (var i = 0; i < length; ++i) {
- var property = defaultProperties[i];
- var styleName = "czm_tiles3d_style_" + property;
- var replaceName = property.toLowerCase();
- source = source.replace(
- new RegExp(styleName + "(\\W)", "g"),
- replaceName + "$1"
- );
- }
+var builtinPropertyNameMap = {
+ POSITION: "czm_3dtiles_builtin_property_POSITION",
+ POSITION_ABSOLUTE: "czm_3dtiles_builtin_property_POSITION_ABSOLUTE",
+ COLOR: "czm_3dtiles_builtin_property_COLOR",
+ NORMAL: "czm_3dtiles_builtin_property_NORMAL",
+};
+function modifyStyleFunction(source) {
// Edit the function header to accept the point position, color, and normal
- return source.replace(
- "()",
- "(vec3 position, vec3 position_absolute, vec4 color, vec3 normal)"
- );
+ var functionHeader =
+ "(" +
+ "vec3 czm_3dtiles_builtin_property_POSITION, " +
+ "vec3 czm_3dtiles_builtin_property_POSITION_ABSOLUTE, " +
+ "vec4 czm_3dtiles_builtin_property_COLOR, " +
+ "vec3 czm_3dtiles_builtin_property_NORMAL" +
+ ")";
+
+ return source.replace("()", functionHeader);
}
function createShaders(pointCloud, frameState, style) {
@@ -1044,23 +1056,34 @@ function createShaders(pointCloud, frameState, style) {
var pointSizeStyleFunction;
var styleTranslucent = isTranslucent;
+ var propertyNameMap = clone(builtinPropertyNameMap);
+ var propertyIdToAttributeMap = {};
+ var styleableShaderAttributes = pointCloud._styleableShaderAttributes;
+ for (name in styleableShaderAttributes) {
+ if (styleableShaderAttributes.hasOwnProperty(name)) {
+ attribute = styleableShaderAttributes[name];
+ propertyNameMap[name] = "czm_3dtiles_property_" + attribute.location;
+ propertyIdToAttributeMap[attribute.location] = attribute;
+ }
+ }
+
if (hasStyle) {
var shaderState = {
translucent: false,
};
colorStyleFunction = style.getColorShaderFunction(
"getColorFromStyle",
- "czm_tiles3d_style_",
+ propertyNameMap,
shaderState
);
showStyleFunction = style.getShowShaderFunction(
"getShowFromStyle",
- "czm_tiles3d_style_",
+ propertyNameMap,
shaderState
);
pointSizeStyleFunction = style.getPointSizeShaderFunction(
"getPointSizeFromStyle",
- "czm_tiles3d_style_",
+ propertyNameMap,
shaderState
);
if (defined(colorStyleFunction) && shaderState.translucent) {
@@ -1076,28 +1099,27 @@ function createShaders(pointCloud, frameState, style) {
var hasClippedContent = pointCloud.isClipped;
// Get the properties in use by the style
- var styleableProperties = [];
+ var styleablePropertyIds = [];
+ var builtinPropertyNames = [];
if (hasColorStyle) {
- getStyleableProperties(colorStyleFunction, styleableProperties);
+ getStyleablePropertyIds(colorStyleFunction, styleablePropertyIds);
+ getBuiltinPropertyNames(colorStyleFunction, builtinPropertyNames);
colorStyleFunction = modifyStyleFunction(colorStyleFunction);
}
if (hasShowStyle) {
- getStyleableProperties(showStyleFunction, styleableProperties);
+ getStyleablePropertyIds(showStyleFunction, styleablePropertyIds);
+ getBuiltinPropertyNames(showStyleFunction, builtinPropertyNames);
showStyleFunction = modifyStyleFunction(showStyleFunction);
}
if (hasPointSizeStyle) {
- getStyleableProperties(pointSizeStyleFunction, styleableProperties);
+ getStyleablePropertyIds(pointSizeStyleFunction, styleablePropertyIds);
+ getBuiltinPropertyNames(pointSizeStyleFunction, builtinPropertyNames);
pointSizeStyleFunction = modifyStyleFunction(pointSizeStyleFunction);
}
- var usesColorSemantic = styleableProperties.indexOf("COLOR") >= 0;
- var usesNormalSemantic = styleableProperties.indexOf("NORMAL") >= 0;
-
- // Split default properties from user properties
- var userProperties = styleableProperties.filter(function (property) {
- return defaultProperties.indexOf(property) === -1;
- });
+ var usesColorSemantic = builtinPropertyNames.indexOf("COLOR") >= 0;
+ var usesNormalSemantic = builtinPropertyNames.indexOf("NORMAL") >= 0;
if (usesNormalSemantic && !hasNormals) {
throw new RuntimeError(
@@ -1106,11 +1128,10 @@ function createShaders(pointCloud, frameState, style) {
}
// Disable vertex attributes that aren't used in the style, enable attributes that are
- var styleableShaderAttributes = pointCloud._styleableShaderAttributes;
for (name in styleableShaderAttributes) {
if (styleableShaderAttributes.hasOwnProperty(name)) {
attribute = styleableShaderAttributes[name];
- var enabled = userProperties.indexOf(name) >= 0;
+ var enabled = styleablePropertyIds.indexOf(attribute.location) >= 0;
var vertexAttribute = getVertexAttribute(vertexArray, attribute.location);
vertexAttribute.enabled = enabled;
}
@@ -1146,20 +1167,12 @@ function createShaders(pointCloud, frameState, style) {
var attributeDeclarations = "";
- var length = userProperties.length;
+ var length = styleablePropertyIds.length;
for (i = 0; i < length; ++i) {
- name = userProperties[i];
- attribute = styleableShaderAttributes[name];
- if (!defined(attribute)) {
- throw new RuntimeError(
- 'Style references a property "' +
- name +
- '" that does not exist or is not styleable.'
- );
- }
-
+ var propertyId = styleablePropertyIds[i];
+ attribute = propertyIdToAttributeMap[propertyId];
var componentCount = attribute.componentCount;
- var attributeName = "czm_tiles3d_style_" + name;
+ var attributeName = "czm_3dtiles_property_" + propertyId;
var attributeType;
if (componentCount === 1) {
attributeType = "float";
diff --git a/Source/Scene/PointCloud3DTileContent.js b/Source/Scene/PointCloud3DTileContent.js
index 56b88ac1ffeb..50ec733be009 100644
--- a/Source/Scene/PointCloud3DTileContent.js
+++ b/Source/Scene/PointCloud3DTileContent.js
@@ -40,10 +40,6 @@ function PointCloud3DTileContent(
this._batchTable = undefined; // Used when feature table contains BATCH_ID semantic
this._styleDirty = false;
this._features = undefined;
-
- /**
- * @inheritdoc Cesium3DTileContent#featurePropertiesDirty
- */
this.featurePropertiesDirty = false;
this._pointCloud = new PointCloud({
diff --git a/Source/Scene/PointPrimitive.js b/Source/Scene/PointPrimitive.js
index 767b7c1b8caf..d69b11290147 100644
--- a/Source/Scene/PointPrimitive.js
+++ b/Source/Scene/PointPrimitive.js
@@ -194,7 +194,7 @@ Object.defineProperties(PointPrimitive.prototype, {
/**
* Gets or sets near and far scaling properties of a point based on the point's distance from the camera.
* A point's scale will interpolate between the {@link NearFarScalar#nearValue} and
- * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds
+ * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds
* of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}.
* Outside of these ranges the point's scale remains clamped to the nearest bound. This scale
* multiplies the pixelSize and outlineWidth to affect the total size of the point. If undefined,
@@ -238,7 +238,7 @@ Object.defineProperties(PointPrimitive.prototype, {
/**
* Gets or sets near and far translucency properties of a point based on the point's distance from the camera.
* A point's translucency will interpolate between the {@link NearFarScalar#nearValue} and
- * {@link NearFarScalar#farValue} while the camera distance falls within the upper and lower bounds
+ * {@link NearFarScalar#farValue} while the camera distance falls within the lower and upper bounds
* of the specified {@link NearFarScalar#near} and {@link NearFarScalar#far}.
* Outside of these ranges the point's translucency remains clamped to the nearest bound. If undefined,
* translucencyByDistance will be disabled.
diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js
index e37a0323b6be..bbc4a6d1d82a 100644
--- a/Source/Scene/Polyline.js
+++ b/Source/Scene/Polyline.js
@@ -17,7 +17,7 @@ import Material from "./Material.js";
* @internalConstructor
* @class
*
- * @param {Object} [options] Object with the following properties:
+ * @param {Object} options Object with the following properties:
* @param {Boolean} [options.show=true] true
if this polyline will be shown; otherwise, false
.
* @param {Number} [options.width=1.0] The width of the polyline in pixels.
* @param {Boolean} [options.loop=false] Whether a line segment will be added between the last and first line positions to make this line a loop.
diff --git a/Source/Scene/PolylineColorAppearance.js b/Source/Scene/PolylineColorAppearance.js
index aaf4c4b8ed41..f5055d3b469c 100644
--- a/Source/Scene/PolylineColorAppearance.js
+++ b/Source/Scene/PolylineColorAppearance.js
@@ -28,7 +28,7 @@ if (!FeatureDetection.isInternetExplorer()) {
* @param {Boolean} [options.translucent=true] When true
, the geometry is expected to appear translucent so {@link PolylineColorAppearance#renderState} has alpha blending enabled.
* @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader.
* @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader.
- * @param {RenderState} [options.renderState] Optional render state to override the default render state.
+ * @param {Object} [options.renderState] Optional render state to override the default render state.
*
* @example
* // A solid white line segment
diff --git a/Source/Scene/PolylineMaterialAppearance.js b/Source/Scene/PolylineMaterialAppearance.js
index ca2afd643a56..da555d65deb7 100644
--- a/Source/Scene/PolylineMaterialAppearance.js
+++ b/Source/Scene/PolylineMaterialAppearance.js
@@ -28,7 +28,7 @@ if (!FeatureDetection.isInternetExplorer()) {
* @param {Material} [options.material=Material.ColorType] The material used to determine the fragment color.
* @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader.
* @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader.
- * @param {RenderState} [options.renderState] Optional render state to override the default render state.
+ * @param {Object} [options.renderState] Optional render state to override the default render state.
*
* @see {@link https://github.com/CesiumGS/cesium/wiki/Fabric|Fabric}
*
diff --git a/Source/Scene/PostProcessStageLibrary.js b/Source/Scene/PostProcessStageLibrary.js
index 3b779589bfd7..a455f76f25d6 100644
--- a/Source/Scene/PostProcessStageLibrary.js
+++ b/Source/Scene/PostProcessStageLibrary.js
@@ -30,7 +30,7 @@ import PostProcessStageSampleMode from "./PostProcessStageSampleMode.js";
/**
* Contains functions for creating common post-process stages.
*
- * @exports PostProcessStageLibrary
+ * @namespace PostProcessStageLibrary
*/
var PostProcessStageLibrary = {};
diff --git a/Source/Scene/PostProcessStageSampleMode.js b/Source/Scene/PostProcessStageSampleMode.js
index 2518c57e2aab..32caaf7bb475 100644
--- a/Source/Scene/PostProcessStageSampleMode.js
+++ b/Source/Scene/PostProcessStageSampleMode.js
@@ -1,7 +1,7 @@
/**
* Determines how input texture to a {@link PostProcessStage} is sampled.
*
- * @exports PostProcessStageSampleMode
+ * @enum {Number}
*/
var PostProcessStageSampleMode = {
/**
diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js
index 16ce0c782d51..465362ea8836 100644
--- a/Source/Scene/Primitive.js
+++ b/Source/Scene/Primitive.js
@@ -1132,17 +1132,10 @@ function depthClampVS(vertexShaderSource) {
vertexShaderSource,
"czm_non_depth_clamp_main"
);
- // The varying should be surround by #ifdef GL_EXT_frag_depth as an optimization.
- // It is not to workaround an issue with Edge:
- // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12120362/
modifiedVS +=
- "varying float v_WindowZ;\n" +
"void main() {\n" +
" czm_non_depth_clamp_main();\n" +
- " vec4 position = gl_Position;\n" +
- " v_WindowZ = (0.5 * (position.z / position.w) + 0.5) * position.w;\n" +
- " position.z = min(position.z, position.w);\n" +
- " gl_Position = position;\n" +
+ " gl_Position = czm_depthClamp(gl_Position);" +
"}\n";
return modifiedVS;
}
@@ -1153,14 +1146,13 @@ function depthClampFS(fragmentShaderSource) {
"czm_non_depth_clamp_main"
);
modifiedFS +=
- "varying float v_WindowZ;\n" +
"void main() {\n" +
" czm_non_depth_clamp_main();\n" +
"#if defined(GL_EXT_frag_depth)\n" +
" #if defined(LOG_DEPTH)\n" +
" czm_writeLogDepth();\n" +
" #else\n" +
- " gl_FragDepthEXT = min(v_WindowZ * gl_FragCoord.w, 1.0);\n" +
+ " czm_writeDepthClamp();\n" +
" #endif\n" +
"#endif\n" +
"}\n";
diff --git a/Source/Scene/QuadtreeTileLoadState.js b/Source/Scene/QuadtreeTileLoadState.js
index dfce7d7b0328..e09deeeabd8a 100644
--- a/Source/Scene/QuadtreeTileLoadState.js
+++ b/Source/Scene/QuadtreeTileLoadState.js
@@ -1,6 +1,6 @@
/**
* The state of a {@link QuadtreeTile} in the tile load pipeline.
- * @exports QuadtreeTileLoadState
+ * @enum {Number}
* @private
*/
var QuadtreeTileLoadState = {
diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js
index ef5396234f48..43b2db6e23fa 100644
--- a/Source/Scene/Scene.js
+++ b/Source/Scene/Scene.js
@@ -51,6 +51,7 @@ import DeviceOrientationCameraController from "./DeviceOrientationCameraControll
import Fog from "./Fog.js";
import FrameState from "./FrameState.js";
import GlobeDepth from "./GlobeDepth.js";
+import GlobeTranslucencyState from "./GlobeTranslucencyState.js";
import InvertClassification from "./InvertClassification.js";
import JobScheduler from "./JobScheduler.js";
import MapMode2D from "./MapMode2D.js";
@@ -125,7 +126,7 @@ var requestRenderAfterFrame = function (scene) {
* @constructor
*
* @param {Object} [options] Object with the following properties:
- * @param {Canvas} options.canvas The HTML canvas element to create the scene for.
+ * @param {HTMLCanvasElement} options.canvas The HTML canvas element to create the scene for.
* @param {Object} [options.contextOptions] Context and WebGL creation properties. See details above.
* @param {Element} [options.creditContainer] The HTML element in which the credits will be displayed.
* @param {Element} [options.creditViewport] The HTML element in which to display the credit popup. If not specified, the viewport will be a added as a sibling of the canvas.
@@ -206,9 +207,13 @@ function Scene(options) {
this._context = context;
this._computeEngine = new ComputeEngine(context);
this._globe = undefined;
+ this._globeTranslucencyState = new GlobeTranslucencyState();
this._primitives = new PrimitiveCollection();
this._groundPrimitives = new PrimitiveCollection();
+ this._globeHeight = undefined;
+ this._cameraUnderground = false;
+
this._logDepthBuffer = context.fragmentDepth;
this._logDepthBufferDirty = true;
@@ -785,7 +790,7 @@ Object.defineProperties(Scene.prototype, {
* Gets the canvas element to which this scene is bound.
* @memberof Scene.prototype
*
- * @type {Canvas}
+ * @type {HTMLCanvasElement}
* @readonly
*/
canvas: {
@@ -1647,6 +1652,15 @@ Object.defineProperties(Scene.prototype, {
return 0.9999;
},
},
+
+ /**
+ * @private
+ */
+ globeHeight: {
+ get: function () {
+ return this._globeHeight;
+ },
+ },
});
/**
@@ -1831,7 +1845,8 @@ function getOccluder(scene) {
scene._mode === SceneMode.SCENE3D &&
defined(globe) &&
globe.show &&
- !scene._cameraUnderground
+ !scene._cameraUnderground &&
+ !scene._globeTranslucencyState.translucent
) {
var ellipsoid = globe.ellipsoid;
var minimumTerrainHeight = scene.frameState.minimumTerrainHeight;
@@ -1898,6 +1913,7 @@ Scene.prototype.updateFrameState = function () {
);
frameState.light = this.light;
frameState.cameraUnderground = this._cameraUnderground;
+ frameState.globeTranslucencyState = this._globeTranslucencyState;
if (
defined(this._specularEnvironmentMapAtlas) &&
@@ -2220,6 +2236,7 @@ function executeCommand(command, scene, context, passState, debugFramebuffer) {
var passes = frameState.passes;
if (
!passes.pick &&
+ !passes.depth &&
scene._hdr &&
defined(command.derivedCommands) &&
defined(command.derivedCommands.hdr)
@@ -2369,6 +2386,7 @@ var scratchOrthographicOffCenterFrustum = new OrthographicOffCenterFrustum();
function executeCommands(scene, passState) {
var camera = scene.camera;
var context = scene.context;
+ var frameState = scene.frameState;
var us = context.uniformState;
us.updateCamera(camera);
@@ -2392,7 +2410,7 @@ function executeCommands(scene, passState) {
us.updateFrustum(frustum);
us.updatePass(Pass.ENVIRONMENT);
- var passes = scene._frameState.passes;
+ var passes = frameState.passes;
var picking = passes.pick;
var environmentState = scene._environmentState;
var view = scene._view;
@@ -2471,6 +2489,9 @@ function executeCommands(scene, passState) {
var clearGlobeDepth = environmentState.clearGlobeDepth;
var useDepthPlane = environmentState.useDepthPlane;
+ var globeTranslucencyState = scene._globeTranslucencyState;
+ var globeTranslucent = globeTranslucencyState.translucent;
+ var globeTranslucencyFramebuffer = scene._view.globeTranslucencyFramebuffer;
var separatePrimitiveFramebuffer = (environmentState.separatePrimitiveFramebuffer = false);
var clearDepth = scene._depthClearCommand;
var clearStencil = scene._stencilClearCommand;
@@ -2492,7 +2513,7 @@ function executeCommands(scene, passState) {
camera.position.z = height2D - frustumCommands.near + 1.0;
frustum.far = Math.max(1.0, frustumCommands.far - frustumCommands.near);
frustum.near = 1.0;
- us.update(scene.frameState);
+ us.update(frameState);
us.updateFrustum(frustum);
} else {
// Avoid tearing artifacts between adjacent frustums in the opaque passes
@@ -2540,8 +2561,19 @@ function executeCommands(scene, passState) {
us.updatePass(Pass.GLOBE);
var commands = frustumCommands.commands[Pass.GLOBE];
var length = frustumCommands.indices[Pass.GLOBE];
- for (j = 0; j < length; ++j) {
- executeCommand(commands[j], scene, context, passState);
+
+ if (globeTranslucent) {
+ globeTranslucencyState.executeGlobeCommands(
+ frustumCommands,
+ executeCommand,
+ globeTranslucencyFramebuffer,
+ scene,
+ passState
+ );
+ } else {
+ for (j = 0; j < length; ++j) {
+ executeCommand(commands[j], scene, context, passState);
+ }
}
if (defined(globeDepth) && environmentState.useGlobeDepthFramebuffer) {
@@ -2557,11 +2589,24 @@ function executeCommands(scene, passState) {
}
// Draw terrain classification
- us.updatePass(Pass.TERRAIN_CLASSIFICATION);
- commands = frustumCommands.commands[Pass.TERRAIN_CLASSIFICATION];
- length = frustumCommands.indices[Pass.TERRAIN_CLASSIFICATION];
- for (j = 0; j < length; ++j) {
- executeCommand(commands[j], scene, context, passState);
+ if (!environmentState.renderTranslucentDepthForPick) {
+ us.updatePass(Pass.TERRAIN_CLASSIFICATION);
+ commands = frustumCommands.commands[Pass.TERRAIN_CLASSIFICATION];
+ length = frustumCommands.indices[Pass.TERRAIN_CLASSIFICATION];
+
+ if (globeTranslucent) {
+ globeTranslucencyState.executeGlobeClassificationCommands(
+ frustumCommands,
+ executeCommand,
+ globeTranslucencyFramebuffer,
+ scene,
+ passState
+ );
+ } else {
+ for (j = 0; j < length; ++j) {
+ executeCommand(commands[j], scene, context, passState);
+ }
+ }
}
if (clearGlobeDepth) {
@@ -2576,7 +2621,11 @@ function executeCommands(scene, passState) {
passState.framebuffer = globeDepth.primitiveFramebuffer;
}
- if (!environmentState.useInvertClassification || picking) {
+ if (
+ !environmentState.useInvertClassification ||
+ picking ||
+ environmentState.renderTranslucentDepthForPick
+ ) {
// Common/fastest path. Draw 3D Tiles and classification normally.
// Draw 3D Tiles
@@ -2593,11 +2642,14 @@ function executeCommands(scene, passState) {
}
// Draw classifications. Modifies 3D Tiles color.
- us.updatePass(Pass.CESIUM_3D_TILE_CLASSIFICATION);
- commands = frustumCommands.commands[Pass.CESIUM_3D_TILE_CLASSIFICATION];
- length = frustumCommands.indices[Pass.CESIUM_3D_TILE_CLASSIFICATION];
- for (j = 0; j < length; ++j) {
- executeCommand(commands[j], scene, context, passState);
+ if (!environmentState.renderTranslucentDepthForPick) {
+ us.updatePass(Pass.CESIUM_3D_TILE_CLASSIFICATION);
+ commands =
+ frustumCommands.commands[Pass.CESIUM_3D_TILE_CLASSIFICATION];
+ length = frustumCommands.indices[Pass.CESIUM_3D_TILE_CLASSIFICATION];
+ for (j = 0; j < length; ++j) {
+ executeCommand(commands[j], scene, context, passState);
+ }
}
}
} else {
@@ -2666,7 +2718,7 @@ function executeCommands(scene, passState) {
// Fullscreen pass to copy classified fragments
scene._invertClassification.executeClassified(context, passState);
- if (scene.frameState.invertClassificationColor.alpha === 1.0) {
+ if (frameState.invertClassificationColor.alpha === 1.0) {
// Fullscreen pass to copy unclassified fragments when alpha == 1.0
scene._invertClassification.executeUnclassified(context, passState);
}
@@ -2706,7 +2758,7 @@ function executeCommands(scene, passState) {
if (
!picking &&
environmentState.useInvertClassification &&
- scene.frameState.invertClassificationColor.alpha < 1.0
+ frameState.invertClassificationColor.alpha < 1.0
) {
// Fullscreen pass to copy unclassified fragments when alpha < 1.0.
// Not executed when undefined.
@@ -2767,8 +2819,19 @@ function executeCommands(scene, passState) {
us.updatePass(Pass.GLOBE);
commands = frustumCommands.commands[Pass.GLOBE];
length = frustumCommands.indices[Pass.GLOBE];
- for (j = 0; j < length; ++j) {
- executeIdCommand(commands[j], scene, context, passState);
+
+ if (globeTranslucent) {
+ globeTranslucencyState.executeGlobeCommands(
+ frustumCommands,
+ executeIdCommand,
+ globeTranslucencyFramebuffer,
+ scene,
+ passState
+ );
+ } else {
+ for (j = 0; j < length; ++j) {
+ executeIdCommand(commands[j], scene, context, passState);
+ }
}
if (clearGlobeDepth) {
@@ -3239,12 +3302,13 @@ Scene.prototype.updateEnvironment = function () {
var offscreenPass = frameState.passes.offscreen;
var skyAtmosphere = this.skyAtmosphere;
var globe = this.globe;
+ var globeTranslucencyState = this._globeTranslucencyState;
if (
!renderPass ||
(this._mode !== SceneMode.SCENE2D &&
view.camera.frustum instanceof OrthographicFrustum) ||
- this._cameraUnderground
+ !globeTranslucencyState.environmentVisible
) {
environmentState.skyAtmosphereCommand = undefined;
environmentState.skyBoxCommand = undefined;
@@ -3262,7 +3326,10 @@ Scene.prototype.updateEnvironment = function () {
environmentState.isReadyForAtmosphere ||
globe._surface._tilesToRender.length > 0;
}
- environmentState.skyAtmosphereCommand = skyAtmosphere.update(frameState);
+ environmentState.skyAtmosphereCommand = skyAtmosphere.update(
+ frameState,
+ globe
+ );
if (defined(environmentState.skyAtmosphereCommand)) {
this.updateDerivedCommands(environmentState.skyAtmosphereCommand);
}
@@ -3289,11 +3356,12 @@ Scene.prototype.updateEnvironment = function () {
var clearGlobeDepth = (environmentState.clearGlobeDepth =
defined(globe) &&
+ globe.show &&
(!globe.depthTestAgainstTerrain || this.mode === SceneMode.SCENE2D));
var useDepthPlane = (environmentState.useDepthPlane =
clearGlobeDepth &&
this.mode === SceneMode.SCENE3D &&
- !this._cameraUnderground);
+ globeTranslucencyState.useDepthPlane);
if (useDepthPlane) {
// Update the depth plane that is rendered in 3D when the primitives are
// not depth tested against terrain so primitives on the backface
@@ -3306,7 +3374,10 @@ Scene.prototype.updateEnvironment = function () {
this._useWebVR && this.mode !== SceneMode.SCENE2D && !offscreenPass;
var occluder =
- frameState.mode === SceneMode.SCENE3D ? frameState.occluder : undefined;
+ frameState.mode === SceneMode.SCENE3D &&
+ !globeTranslucencyState.sunVisibleThroughGlobe
+ ? frameState.occluder
+ : undefined;
var cullingVolume = frameState.cullingVolume;
// get user culling volume minus the far plane.
@@ -3356,6 +3427,7 @@ function updateDebugFrustumPlanes(scene) {
scene._debugFrustumPlanes = new DebugCameraPrimitive({
camera: scene.camera,
updateOnChange: false,
+ frustumSplits: frameState.frustumSplits,
});
} else {
scene._debugFrustumPlanes =
@@ -3552,6 +3624,15 @@ function updateAndClearFramebuffers(scene, passState, clearColor) {
environmentState.useInvertClassification = false;
}
}
+
+ if (scene._globeTranslucencyState.translucent) {
+ view.globeTranslucencyFramebuffer.updateAndClear(
+ scene._hdr,
+ view.viewport,
+ context,
+ passState
+ );
+ }
}
/**
@@ -3632,6 +3713,16 @@ function callAfterRenderFunctions(scene) {
functions.length = 0;
}
+function getGlobeHeight(scene) {
+ var globe = scene._globe;
+ var camera = scene.camera;
+ var cartographic = camera.positionCartographic;
+ if (defined(globe) && globe.show && defined(cartographic)) {
+ return globe.getHeight(cartographic);
+ }
+ return undefined;
+}
+
function isCameraUnderground(scene) {
var camera = scene.camera;
var mode = scene._mode;
@@ -3639,6 +3730,10 @@ function isCameraUnderground(scene) {
var cameraController = scene._screenSpaceCameraController;
var cartographic = camera.positionCartographic;
+ if (!defined(cartographic)) {
+ return false;
+ }
+
if (!cameraController.onMap() && cartographic.height < 0.0) {
// The camera can go off the map while in Columbus View.
// Make a best guess as to whether it's underground by checking if its height is less than zero.
@@ -3654,17 +3749,8 @@ function isCameraUnderground(scene) {
return false;
}
- if (cameraController.adjustedHeightForTerrain()) {
- // The camera controller already adjusted the camera, no need to call globe.getHeight again
- return false;
- }
-
- var globeHeight = globe.getHeight(cartographic);
- if (defined(globeHeight) && cartographic.height < globeHeight) {
- return true;
- }
-
- return false;
+ var globeHeight = scene._globeHeight;
+ return defined(globeHeight) && cartographic.height < globeHeight;
}
/**
@@ -3680,6 +3766,10 @@ Scene.prototype.initializeFrame = function () {
this._tweens.update();
+ this._globeHeight = getGlobeHeight(this);
+ this._cameraUnderground = isCameraUnderground(this);
+ this._globeTranslucencyState.update(this);
+
this._screenSpaceCameraController.update();
if (defined(this._deviceOrientationCameraController)) {
this._deviceOrientationCameraController.update();
@@ -3687,8 +3777,6 @@ Scene.prototype.initializeFrame = function () {
this.camera.update(this._mode);
this.camera._updateCameraChanged();
-
- this._cameraUnderground = isCameraUnderground(this);
};
function updateDebugShowFramesPerSecond(scene, renderedThisFrame) {
@@ -3834,10 +3922,9 @@ function updateMostDetailedRayPicks(scene) {
}
/**
- * Update and render the scene.
+ * Update and render the scene. It is usually not necessary to call this function
+ * directly because {@link CesiumWidget} or {@link Viewer} do it automatically.
* @param {JulianDate} [time] The simulation time at which to render.
- *
- * @private
*/
Scene.prototype.render = function (time) {
/**
@@ -4049,7 +4136,7 @@ Scene.prototype.pickPosition = function (windowPosition, result) {
* @param {Number} [limit] If supplied, stop drilling after collecting this many picks.
* @param {Number} [width=3] Width of the pick rectangle.
* @param {Number} [height=3] Height of the pick rectangle.
- * @returns {Object[]} Array of objects, each containing 1 picked primitives.
+ * @returns {Array.<*>} Array of objects, each containing 1 picked primitives.
*
* @exception {DeveloperError} windowPosition is undefined.
*
diff --git a/Source/Scene/SceneMode.js b/Source/Scene/SceneMode.js
index 14858ffd8604..a9eabb4caae0 100644
--- a/Source/Scene/SceneMode.js
+++ b/Source/Scene/SceneMode.js
@@ -1,8 +1,7 @@
/**
* Indicates if the scene is viewed in 3D, 2D, or 2.5D Columbus view.
*
- * @exports SceneMode
- *
+ * @enum {Number}
* @see Scene#mode
*/
var SceneMode = {
diff --git a/Source/Scene/SceneTransforms.js b/Source/Scene/SceneTransforms.js
index 5db365f69572..d6eee52df206 100644
--- a/Source/Scene/SceneTransforms.js
+++ b/Source/Scene/SceneTransforms.js
@@ -15,7 +15,7 @@ import SceneMode from "./SceneMode.js";
/**
* Functions that do scene-dependent transforms between rendering-related coordinate systems.
*
- * @exports SceneTransforms
+ * @namespace SceneTransforms
*/
var SceneTransforms = {};
diff --git a/Source/Scene/SceneTransitioner.js b/Source/Scene/SceneTransitioner.js
index fbb892b6a683..d2789fd815c7 100644
--- a/Source/Scene/SceneTransitioner.js
+++ b/Source/Scene/SceneTransitioner.js
@@ -644,6 +644,7 @@ function morphFromColumbusViewTo2D(transitioner, duration) {
var pickPos = globe.pickWorldCoordinates(
ray,
scene,
+ true,
scratchCVTo2DPickPos
);
if (defined(pickPos)) {
@@ -773,6 +774,7 @@ function morphFrom3DTo2D(transitioner, duration, ellipsoid) {
var pickedPos = globe.pickWorldCoordinates(
ray,
scene,
+ true,
scratch3DTo2DPickPosition
);
if (defined(pickedPos)) {
diff --git a/Source/Scene/ScreenSpaceCameraController.js b/Source/Scene/ScreenSpaceCameraController.js
index 92e50e9eac8a..9866dde783a2 100644
--- a/Source/Scene/ScreenSpaceCameraController.js
+++ b/Source/Scene/ScreenSpaceCameraController.js
@@ -231,7 +231,7 @@ function ScreenSpaceCameraController(scene) {
this._minimumCollisionTerrainHeight = this.minimumCollisionTerrainHeight;
/**
* The minimum height the camera must be before switching from rotating a track ball to
- * free look when clicks originate on the sky on in space.
+ * free look when clicks originate on the sky or in space.
* @type {Number}
* @default 7500000.0
*/
@@ -255,6 +255,20 @@ function ScreenSpaceCameraController(scene) {
this._lastInertiaTranslateMovement = undefined;
this._lastInertiaTiltMovement = undefined;
+ // Zoom disables tilt, spin, and translate inertia
+ // Tilt disables spin and translate inertia
+ this._inertiaDisablers = {
+ _lastInertiaZoomMovement: [
+ "_lastInertiaSpinMovement",
+ "_lastInertiaTranslateMovement",
+ "_lastInertiaTiltMovement",
+ ],
+ _lastInertiaTiltMovement: [
+ "_lastInertiaSpinMovement",
+ "_lastInertiaTranslateMovement",
+ ],
+ };
+
this._tweens = new TweenCollection();
this._tween = undefined;
@@ -265,6 +279,8 @@ function ScreenSpaceCameraController(scene) {
this._rotateMousePosition = new Cartesian2(-1.0, -1.0);
this._rotateStartPosition = new Cartesian3();
this._strafeStartPosition = new Cartesian3();
+ this._strafeMousePosition = new Cartesian2();
+ this._strafeEndMousePosition = new Cartesian2();
this._zoomMouseStart = new Cartesian2(-1.0, -1.0);
this._zoomWorldPosition = new Cartesian3();
this._useZoomWorldPosition = false;
@@ -273,8 +289,10 @@ function ScreenSpaceCameraController(scene) {
this._rotating = false;
this._strafing = false;
this._zoomingOnVector = false;
+ this._zoomingUnderground = false;
this._rotatingZoom = false;
this._adjustedHeightForTerrain = false;
+ this._cameraUnderground = false;
var projection = scene.mapProjection;
this._maxCoord = projection.project(
@@ -289,6 +307,8 @@ function ScreenSpaceCameraController(scene) {
this._minimumRotateRate = 1.0 / 5000.0;
this._minimumZoomRate = 20.0;
this._maximumZoomRate = 5906376272000.0; // distance from the Sun to Pluto in meters.
+ this._minimumUndergroundPickDistance = 2000.0;
+ this._maximumUndergroundPickDistance = 10000.0;
}
function decay(time, coefficient) {
@@ -329,7 +349,7 @@ function maintainInertia(
startPosition: new Cartesian2(),
endPosition: new Cartesian2(),
motion: new Cartesian2(),
- active: false,
+ inertiaEnabled: true,
};
}
@@ -343,56 +363,35 @@ function maintainInertia(
if (ts && tr && threshold < inertiaMaxClickTimeThreshold) {
var d = decay(fromNow, decayCoef);
- if (!movementState.active) {
- var lastMovement = aggregator.getLastMovement(type, modifier);
- if (!defined(lastMovement) || sameMousePosition(lastMovement)) {
- return;
- }
-
- movementState.motion.x =
- (lastMovement.endPosition.x - lastMovement.startPosition.x) * 0.5;
- movementState.motion.y =
- (lastMovement.endPosition.y - lastMovement.startPosition.y) * 0.5;
-
- movementState.startPosition = Cartesian2.clone(
- lastMovement.startPosition,
- movementState.startPosition
- );
-
- movementState.endPosition = Cartesian2.multiplyByScalar(
- movementState.motion,
- d,
- movementState.endPosition
- );
- movementState.endPosition = Cartesian2.add(
- movementState.startPosition,
- movementState.endPosition,
- movementState.endPosition
- );
+ var lastMovement = aggregator.getLastMovement(type, modifier);
+ if (
+ !defined(lastMovement) ||
+ sameMousePosition(lastMovement) ||
+ !movementState.inertiaEnabled
+ ) {
+ return;
+ }
- movementState.active = true;
- } else {
- movementState.startPosition = Cartesian2.clone(
- movementState.endPosition,
- movementState.startPosition
- );
+ movementState.motion.x =
+ (lastMovement.endPosition.x - lastMovement.startPosition.x) * 0.5;
+ movementState.motion.y =
+ (lastMovement.endPosition.y - lastMovement.startPosition.y) * 0.5;
- movementState.endPosition = Cartesian2.multiplyByScalar(
- movementState.motion,
- d,
- movementState.endPosition
- );
- movementState.endPosition = Cartesian2.add(
- movementState.startPosition,
- movementState.endPosition,
- movementState.endPosition
- );
+ movementState.startPosition = Cartesian2.clone(
+ lastMovement.startPosition,
+ movementState.startPosition
+ );
- movementState.motion = Cartesian2.clone(
- Cartesian2.ZERO,
- movementState.motion
- );
- }
+ movementState.endPosition = Cartesian2.multiplyByScalar(
+ movementState.motion,
+ d,
+ movementState.endPosition
+ );
+ movementState.endPosition = Cartesian2.add(
+ movementState.startPosition,
+ movementState.endPosition,
+ movementState.endPosition
+ );
// If value from the decreasing exponential function is close to zero,
// the end coordinates may be NaN.
@@ -404,7 +403,6 @@ function maintainInertia(
movementState.endPosition
) < 0.5
) {
- movementState.active = false;
return;
}
@@ -412,8 +410,27 @@ function maintainInertia(
var startPosition = aggregator.getStartMousePosition(type, modifier);
action(object, startPosition, movementState);
}
- } else {
- movementState.active = false;
+ }
+}
+
+function activateInertia(controller, inertiaStateName) {
+ if (defined(inertiaStateName)) {
+ // Re-enable inertia if it was disabled
+ var movementState = controller[inertiaStateName];
+ if (defined(movementState)) {
+ movementState.inertiaEnabled = true;
+ }
+ // Disable inertia on other movements
+ var inertiasToDisable = controller._inertiaDisablers[inertiaStateName];
+ if (defined(inertiasToDisable)) {
+ var length = inertiasToDisable.length;
+ for (var i = 0; i < length; ++i) {
+ movementState = controller[inertiasToDisable[i]];
+ if (defined(movementState)) {
+ movementState.inertiaEnabled = false;
+ }
+ }
+ }
}
}
@@ -452,6 +469,7 @@ function reactToInput(
if (controller.enableInputs && enabled) {
if (movement) {
action(controller, startPosition, movement);
+ activateInertia(controller, inertiaStateName);
} else if (inertiaConstant < 1.0) {
maintainInertia(
aggregator,
@@ -531,18 +549,24 @@ function handleZoom(
rangeWindowRatio = Math.min(rangeWindowRatio, object.maximumMovementRatio);
var distance = zoomRate * rangeWindowRatio;
- if (distance > 0.0 && Math.abs(distanceMeasure - minHeight) < 1.0) {
- return;
- }
+ if (
+ object.enableCollisionDetection ||
+ object.minimumZoomDistance === 0.0 ||
+ !defined(object._globe) // look-at mode
+ ) {
+ if (distance > 0.0 && Math.abs(distanceMeasure - minHeight) < 1.0) {
+ return;
+ }
- if (distance < 0.0 && Math.abs(distanceMeasure - maxHeight) < 1.0) {
- return;
- }
+ if (distance < 0.0 && Math.abs(distanceMeasure - maxHeight) < 1.0) {
+ return;
+ }
- if (distanceMeasure - distance < minHeight) {
- distance = distanceMeasure - minHeight - 1.0;
- } else if (distanceMeasure - distance > maxHeight) {
- distance = distanceMeasure - maxHeight;
+ if (distanceMeasure - distance < minHeight) {
+ distance = distanceMeasure - minHeight - 1.0;
+ } else if (distanceMeasure - distance > maxHeight) {
+ distance = distanceMeasure - maxHeight;
+ }
}
var scene = object._scene;
@@ -601,6 +625,7 @@ function handleZoom(
zoomingOnVector = object._zoomingOnVector = false;
rotatingZoom = object._rotatingZoom = false;
+ object._zoomingUnderground = object._cameraUnderground;
}
if (!object._useZoomWorldPosition) {
@@ -660,8 +685,11 @@ function handleZoom(
scratchCameraPositionNormal
);
if (
- camera.positionCartographic.height < 3000.0 &&
- Math.abs(Cartesian3.dot(camera.direction, cameraPositionNormal)) < 0.6
+ object._cameraUnderground ||
+ object._zoomingUnderground ||
+ (camera.positionCartographic.height < 3000.0 &&
+ Math.abs(Cartesian3.dot(camera.direction, cameraPositionNormal)) <
+ 0.6)
) {
zoomOnVector = true;
} else {
@@ -900,7 +928,9 @@ function handleZoom(
camera.zoomIn(distance);
}
- camera.setView(scratchZoomViewOptions);
+ if (!object._cameraUnderground) {
+ camera.setView(scratchZoomViewOptions);
+ }
}
var translate2DStart = new Ray();
@@ -1070,6 +1100,8 @@ function pickGlobe(controller, mousePosition, result) {
return undefined;
}
+ var cullBackFaces = !controller._cameraUnderground;
+
var depthIntersection;
if (scene.pickPositionSupported) {
depthIntersection = scene.pickPositionWorldCoordinates(
@@ -1082,6 +1114,7 @@ function pickGlobe(controller, mousePosition, result) {
var rayIntersection = globe.pickWorldCoordinates(
ray,
scene,
+ cullBackFaces,
scratchRayIntersection
);
@@ -1099,11 +1132,108 @@ function pickGlobe(controller, mousePosition, result) {
return Cartesian3.clone(rayIntersection, result);
}
+var scratchDistanceCartographic = new Cartographic();
+
+function getDistanceFromSurface(controller) {
+ var ellipsoid = controller._ellipsoid;
+ var scene = controller._scene;
+ var camera = scene.camera;
+ var mode = scene.mode;
+
+ var height = 0.0;
+ if (mode === SceneMode.SCENE3D) {
+ var cartographic = ellipsoid.cartesianToCartographic(
+ camera.position,
+ scratchDistanceCartographic
+ );
+ if (defined(cartographic)) {
+ height = cartographic.height;
+ }
+ } else {
+ height = camera.position.z;
+ }
+ var globeHeight = defaultValue(controller._scene.globeHeight, 0.0);
+ var distanceFromSurface = Math.abs(globeHeight - height);
+ return distanceFromSurface;
+}
+
+var scratchSurfaceNormal = new Cartesian3();
+
+function getZoomDistanceUnderground(controller, ray) {
+ var origin = ray.origin;
+ var direction = ray.direction;
+ var distanceFromSurface = getDistanceFromSurface(controller);
+
+ // Weight zoom distance based on how strongly the pick ray is pointing inward.
+ // Geocentric normal is accurate enough for these purposes
+ var surfaceNormal = Cartesian3.normalize(origin, scratchSurfaceNormal);
+ var strength = Math.abs(Cartesian3.dot(surfaceNormal, direction));
+ strength = Math.max(strength, 0.5) * 2.0;
+ return distanceFromSurface * strength;
+}
+
+function getTiltCenterUnderground(controller, ray, pickedPosition, result) {
+ var distance = Cartesian3.distance(ray.origin, pickedPosition);
+ var distanceFromSurface = getDistanceFromSurface(controller);
+
+ var maximumDistance = CesiumMath.clamp(
+ distanceFromSurface * 5.0,
+ controller._minimumUndergroundPickDistance,
+ controller._maximumUndergroundPickDistance
+ );
+
+ if (distance > maximumDistance) {
+ // Simulate look-at behavior by tilting around a small invisible sphere
+ distance = Math.min(distance, distanceFromSurface / 5.0);
+ distance = Math.max(distance, 100.0);
+ }
+
+ return Ray.getPoint(ray, distance, result);
+}
+
+function getStrafeStartPositionUnderground(
+ controller,
+ ray,
+ pickedPosition,
+ result
+) {
+ var distance;
+ if (!defined(pickedPosition)) {
+ distance = getDistanceFromSurface(controller);
+ } else {
+ distance = Cartesian3.distance(ray.origin, pickedPosition);
+ if (distance > controller._maximumUndergroundPickDistance) {
+ // If the picked position is too far away set the strafe speed based on the
+ // camera's height from the globe surface
+ distance = getDistanceFromSurface(controller);
+ }
+ }
+
+ return Ray.getPoint(ray, distance, result);
+}
+
+var scratchInertialDelta = new Cartesian2();
+
+function continueStrafing(controller, movement) {
+ // Update the end position continually based on the inertial delta
+ var originalEndPosition = movement.endPosition;
+ var inertialDelta = Cartesian2.subtract(
+ movement.endPosition,
+ movement.startPosition,
+ scratchInertialDelta
+ );
+ var endPosition = controller._strafeEndMousePosition;
+ Cartesian2.add(endPosition, inertialDelta, endPosition);
+ movement.endPosition = endPosition;
+ strafe(controller, movement, controller._strafeStartPosition);
+ movement.endPosition = originalEndPosition;
+}
+
var translateCVStartRay = new Ray();
var translateCVEndRay = new Ray();
var translateCVStartPos = new Cartesian3();
var translateCVEndPos = new Cartesian3();
-var translatCVDifference = new Cartesian3();
+var translateCVDifference = new Cartesian3();
var translateCVOrigin = new Cartesian3();
var translateCVPlane = new Plane(Cartesian3.UNIT_X, 0.0);
var translateCVStartMouse = new Cartesian2();
@@ -1124,12 +1254,13 @@ function translateCV(controller, startPosition, movement) {
}
if (controller._strafing) {
- strafe(controller, startPosition, movement);
+ continueStrafing(controller, movement);
return;
}
var scene = controller._scene;
var camera = scene.camera;
+ var cameraUnderground = controller._cameraUnderground;
var startMouse = Cartesian2.clone(
movement.startPosition,
translateCVStartMouse
@@ -1148,14 +1279,24 @@ function translateCV(controller, startPosition, movement) {
}
}
- if (origin.x > camera.position.z && defined(globePos)) {
- Cartesian3.clone(globePos, controller._strafeStartPosition);
+ if (
+ cameraUnderground ||
+ (origin.x > camera.position.z && defined(globePos))
+ ) {
+ var pickPosition = globePos;
+ if (cameraUnderground) {
+ pickPosition = getStrafeStartPositionUnderground(
+ controller,
+ startRay,
+ globePos,
+ translateCVStartPos
+ );
+ }
+ Cartesian2.clone(startPosition, controller._strafeMousePosition);
+ Cartesian2.clone(startPosition, controller._strafeEndMousePosition);
+ Cartesian3.clone(pickPosition, controller._strafeStartPosition);
controller._strafing = true;
- strafe(controller, startPosition, movement);
- controller._strafeMousePosition = Cartesian2.clone(
- startPosition,
- controller._strafeMousePosition
- );
+ strafe(controller, movement, controller._strafeStartPosition);
return;
}
@@ -1185,7 +1326,7 @@ function translateCV(controller, startPosition, movement) {
var diff = Cartesian3.subtract(
startPlanePos,
endPlanePos,
- translatCVDifference
+ translateCVDifference
);
var temp = diff.x;
diff.x = diff.y;
@@ -1234,7 +1375,7 @@ function rotateCV(controller, startPosition, movement) {
if (
controller._tiltCVOffMap ||
!controller.onMap() ||
- camera.position.z > controller._minimumPickingTerrainHeight
+ Math.abs(camera.position.z) > controller._minimumPickingTerrainHeight
) {
controller._tiltCVOffMap = true;
rotateCVOnPlane(controller, startPosition, movement);
@@ -1309,6 +1450,7 @@ function rotateCVOnPlane(controller, startPosition, movement) {
function rotateCVOnTerrain(controller, startPosition, movement) {
var scene = controller._scene;
var camera = scene.camera;
+ var cameraUnderground = controller._cameraUnderground;
var center;
var ray;
@@ -1343,6 +1485,13 @@ function rotateCVOnTerrain(controller, startPosition, movement) {
Cartesian3.add(position, center, center);
}
+ if (cameraUnderground) {
+ if (!defined(ray)) {
+ ray = camera.getPickRay(startPosition, rotateCVWindowRay);
+ }
+ getTiltCenterUnderground(controller, ray, center, center);
+ }
+
Cartesian2.clone(startPosition, controller._tiltCenterMousePosition);
Cartesian3.clone(center, controller._tiltCenter);
}
@@ -1420,7 +1569,12 @@ function rotateCVOnTerrain(controller, startPosition, movement) {
camera._setTransform(verticalTransform);
if (dot < 0.0) {
- if (movement.startPosition.y > movement.endPosition.y) {
+ var movementDelta = movement.startPosition.y - movement.endPosition.y;
+ if (
+ (cameraUnderground && movementDelta < 0.0) ||
+ (!cameraUnderground && movementDelta > 0.0)
+ ) {
+ // Prevent camera from flipping past the up axis
constrainedAxis = undefined;
}
@@ -1518,23 +1672,48 @@ function zoomCV(controller, startPosition, movement) {
var camera = scene.camera;
var canvas = scene.canvas;
- var windowPosition = zoomCVWindowPos;
- windowPosition.x = canvas.clientWidth / 2;
- windowPosition.y = canvas.clientHeight / 2;
+ var cameraUnderground = controller._cameraUnderground;
+
+ var windowPosition;
+
+ if (cameraUnderground) {
+ windowPosition = startPosition;
+ } else {
+ windowPosition = zoomCVWindowPos;
+ windowPosition.x = canvas.clientWidth / 2;
+ windowPosition.y = canvas.clientHeight / 2;
+ }
+
var ray = camera.getPickRay(windowPosition, zoomCVWindowRay);
+ var position = ray.origin;
+ var direction = ray.direction;
+ var height = camera.position.z;
var intersection;
- if (camera.position.z < controller._minimumPickingTerrainHeight) {
+ if (height < controller._minimumPickingTerrainHeight) {
intersection = pickGlobe(controller, windowPosition, zoomCVIntersection);
}
var distance;
if (defined(intersection)) {
- distance = Cartesian3.distance(ray.origin, intersection);
- } else {
+ distance = Cartesian3.distance(position, intersection);
+ }
+
+ if (cameraUnderground) {
+ var distanceUnderground = getZoomDistanceUnderground(
+ controller,
+ ray,
+ height
+ );
+ if (defined(distance)) {
+ distance = Math.min(distance, distanceUnderground);
+ } else {
+ distance = distanceUnderground;
+ }
+ }
+
+ if (!defined(distance)) {
var normal = Cartesian3.UNIT_X;
- var position = ray.origin;
- var direction = ray.direction;
distance =
-Cartesian3.dot(normal, position) / Cartesian3.dot(normal, direction);
}
@@ -1609,10 +1788,6 @@ function updateCV(controller) {
if (
!controller._aggregator.anyButtonDown &&
- (!defined(controller._lastInertiaZoomMovement) ||
- !controller._lastInertiaZoomMovement.active) &&
- (!defined(controller._lastInertiaTranslateMovement) ||
- !controller._lastInertiaTranslateMovement.active) &&
!tweens.contains(controller._tween)
) {
var tween = camera.createCorrectPositionTween(
@@ -1633,21 +1808,11 @@ var scratchStrafeIntersection = new Cartesian3();
var scratchStrafeDirection = new Cartesian3();
var scratchMousePos = new Cartesian3();
-function strafe(controller, startPosition, movement) {
+function strafe(controller, movement, strafeStartPosition) {
var scene = controller._scene;
var camera = scene.camera;
- var mouseStartPosition = pickGlobe(
- controller,
- movement.startPosition,
- scratchMousePos
- );
- if (!defined(mouseStartPosition)) {
- return;
- }
-
- var mousePosition = movement.endPosition;
- var ray = camera.getPickRay(mousePosition, scratchStrafeRay);
+ var ray = camera.getPickRay(movement.endPosition, scratchStrafeRay);
var direction = Cartesian3.clone(camera.direction, scratchStrafeDirection);
if (scene.mode === SceneMode.COLUMBUS_VIEW) {
@@ -1655,7 +1820,7 @@ function strafe(controller, startPosition, movement) {
}
var plane = Plane.fromPointNormal(
- mouseStartPosition,
+ strafeStartPosition,
direction,
scratchStrafePlane
);
@@ -1668,7 +1833,7 @@ function strafe(controller, startPosition, movement) {
return;
}
- direction = Cartesian3.subtract(mouseStartPosition, intersection, direction);
+ direction = Cartesian3.subtract(strafeStartPosition, intersection, direction);
if (scene.mode === SceneMode.COLUMBUS_VIEW) {
Cartesian3.fromElements(direction.y, direction.z, direction.x, direction);
}
@@ -1681,10 +1846,13 @@ var scratchCartographic = new Cartographic();
var scratchRadii = new Cartesian3();
var scratchEllipsoid = new Ellipsoid();
var scratchLookUp = new Cartesian3();
+var scratchNormal = new Cartesian3();
function spin3D(controller, startPosition, movement) {
var scene = controller._scene;
var camera = scene.camera;
+ var cameraUnderground = controller._cameraUnderground;
+ var ellipsoid = controller._ellipsoid;
if (!Matrix4.equals(camera.transform, Matrix4.IDENTITY)) {
rotate3D(controller, startPosition, movement);
@@ -1693,34 +1861,8 @@ function spin3D(controller, startPosition, movement) {
var magnitude;
var radii;
- var ellipsoid;
- var up = controller._ellipsoid.geodeticSurfaceNormal(
- camera.position,
- scratchLookUp
- );
-
- var height = controller._ellipsoid.cartesianToCartographic(
- camera.positionWC,
- scratchCartographic
- ).height;
- var globe = controller._globe;
-
- var mousePos;
- var tangentPick = false;
- if (defined(globe) && height < controller._minimumPickingTerrainHeight) {
- mousePos = pickGlobe(controller, movement.startPosition, scratchMousePos);
- if (defined(mousePos)) {
- var ray = camera.getPickRay(movement.startPosition, pickGlobeScratchRay);
- var normal = controller._ellipsoid.geodeticSurfaceNormal(mousePos);
- tangentPick = Math.abs(Cartesian3.dot(ray.direction, normal)) < 0.05;
-
- if (tangentPick && !controller._looking) {
- controller._rotating = false;
- controller._strafing = true;
- }
- }
- }
+ var up = ellipsoid.geodeticSurfaceNormal(camera.position, scratchLookUp);
if (Cartesian2.equals(startPosition, controller._rotateMousePosition)) {
if (controller._looking) {
@@ -1728,9 +1870,15 @@ function spin3D(controller, startPosition, movement) {
} else if (controller._rotating) {
rotate3D(controller, startPosition, movement);
} else if (controller._strafing) {
- Cartesian3.clone(mousePos, controller._strafeStartPosition);
- strafe(controller, startPosition, movement);
+ continueStrafing(controller, movement);
} else {
+ if (
+ Cartesian3.magnitude(camera.position) <
+ Cartesian3.magnitude(controller._rotateStartPosition)
+ ) {
+ // Pan action is no longer valid if camera moves below the pan ellipsoid
+ return;
+ }
magnitude = Cartesian3.magnitude(controller._rotateStartPosition);
radii = scratchRadii;
radii.x = radii.y = radii.z = magnitude;
@@ -1743,15 +1891,44 @@ function spin3D(controller, startPosition, movement) {
controller._rotating = false;
controller._strafing = false;
+ var height = ellipsoid.cartesianToCartographic(
+ camera.positionWC,
+ scratchCartographic
+ ).height;
+ var globe = controller._globe;
+
if (defined(globe) && height < controller._minimumPickingTerrainHeight) {
+ var mousePos = pickGlobe(
+ controller,
+ movement.startPosition,
+ scratchMousePos
+ );
if (defined(mousePos)) {
- if (
- Cartesian3.magnitude(camera.position) < Cartesian3.magnitude(mousePos)
- ) {
- Cartesian3.clone(mousePos, controller._strafeStartPosition);
+ var strafing = false;
+ var ray = camera.getPickRay(movement.startPosition, pickGlobeScratchRay);
+
+ if (cameraUnderground) {
+ strafing = true;
+ getStrafeStartPositionUnderground(controller, ray, mousePos, mousePos);
+ } else {
+ var normal = ellipsoid.geodeticSurfaceNormal(mousePos, scratchNormal);
+ var tangentPick =
+ Math.abs(Cartesian3.dot(ray.direction, normal)) < 0.05;
+
+ if (tangentPick) {
+ strafing = true;
+ } else {
+ strafing =
+ Cartesian3.magnitude(camera.position) <
+ Cartesian3.magnitude(mousePos);
+ }
+ }
+ if (strafing) {
+ Cartesian2.clone(startPosition, controller._strafeEndMousePosition);
+ Cartesian3.clone(mousePos, controller._strafeStartPosition);
controller._strafing = true;
- strafe(controller, startPosition, movement);
+ strafe(controller, movement, controller._strafeStartPosition);
} else {
magnitude = Cartesian3.magnitude(mousePos);
radii = scratchRadii;
@@ -1974,9 +2151,18 @@ function zoom3D(controller, startPosition, movement) {
var camera = scene.camera;
var canvas = scene.canvas;
- var windowPosition = zoomCVWindowPos;
- windowPosition.x = canvas.clientWidth / 2;
- windowPosition.y = canvas.clientHeight / 2;
+ var cameraUnderground = controller._cameraUnderground;
+
+ var windowPosition;
+
+ if (cameraUnderground) {
+ windowPosition = startPosition;
+ } else {
+ windowPosition = zoomCVWindowPos;
+ windowPosition.x = canvas.clientWidth / 2;
+ windowPosition.y = canvas.clientHeight / 2;
+ }
+
var ray = camera.getPickRay(windowPosition, zoomCVWindowRay);
var intersection;
@@ -1991,7 +2177,22 @@ function zoom3D(controller, startPosition, movement) {
var distance;
if (defined(intersection)) {
distance = Cartesian3.distance(ray.origin, intersection);
- } else {
+ }
+
+ if (cameraUnderground) {
+ var distanceUnderground = getZoomDistanceUnderground(
+ controller,
+ ray,
+ height
+ );
+ if (defined(distance)) {
+ distance = Math.min(distance, distanceUnderground);
+ } else {
+ distance = distanceUnderground;
+ }
+ }
+
+ if (!defined(distance)) {
distance = height;
}
@@ -2149,6 +2350,7 @@ function tilt3DOnTerrain(controller, startPosition, movement) {
var ellipsoid = controller._ellipsoid;
var scene = controller._scene;
var camera = scene.camera;
+ var cameraUnderground = controller._cameraUnderground;
var center;
var ray;
@@ -2181,6 +2383,13 @@ function tilt3DOnTerrain(controller, startPosition, movement) {
center = Ray.getPoint(ray, intersection.start, tilt3DCenter);
}
+ if (cameraUnderground) {
+ if (!defined(ray)) {
+ ray = camera.getPickRay(startPosition, tilt3DRay);
+ }
+ getTiltCenterUnderground(controller, ray, center, center);
+ }
+
Cartesian2.clone(startPosition, controller._tiltCenterMousePosition);
Cartesian3.clone(center, controller._tiltCenter);
}
@@ -2242,7 +2451,12 @@ function tilt3DOnTerrain(controller, startPosition, movement) {
camera._setTransform(verticalTransform);
if (dot < 0.0) {
- if (movement.startPosition.y > movement.endPosition.y) {
+ var movementDelta = movement.startPosition.y - movement.endPosition.y;
+ if (
+ (cameraUnderground && movementDelta < 0.0) ||
+ (!cameraUnderground && movementDelta > 0.0)
+ ) {
+ // Prevent camera from flipping past the up axis
constrainedAxis = undefined;
}
@@ -2527,9 +2741,9 @@ function adjustHeightForTerrain(controller) {
var heightUpdated = false;
if (cartographic.height < controller._minimumCollisionTerrainHeight) {
- var height = globe.getHeight(cartographic);
- if (defined(height)) {
- height += controller.minimumZoomDistance;
+ var globeHeight = controller._scene.globeHeight;
+ if (defined(globeHeight)) {
+ var height = globeHeight + controller.minimumZoomDistance;
if (cartographic.height < height) {
cartographic.height = height;
if (mode === SceneMode.SCENE3D) {
@@ -2584,23 +2798,29 @@ var scratchPreviousDirection = new Cartesian3();
* @private
*/
ScreenSpaceCameraController.prototype.update = function () {
- var camera = this._scene.camera;
+ var scene = this._scene;
+ var camera = scene.camera;
+ var globe = scene.globe;
+ var mode = scene.mode;
+
if (!Matrix4.equals(camera.transform, Matrix4.IDENTITY)) {
this._globe = undefined;
this._ellipsoid = Ellipsoid.UNIT_SPHERE;
} else {
- this._globe = this._scene.globe;
+ this._globe = globe;
this._ellipsoid = defined(this._globe)
? this._globe.ellipsoid
- : this._scene.mapProjection.ellipsoid;
+ : scene.mapProjection.ellipsoid;
}
+ this._cameraUnderground = scene.cameraUnderground && defined(this._globe);
+
this._minimumCollisionTerrainHeight =
- this.minimumCollisionTerrainHeight * this._scene.terrainExaggeration;
+ this.minimumCollisionTerrainHeight * scene.terrainExaggeration;
this._minimumPickingTerrainHeight =
- this.minimumPickingTerrainHeight * this._scene.terrainExaggeration;
+ this.minimumPickingTerrainHeight * scene.terrainExaggeration;
this._minimumTrackBallHeight =
- this.minimumTrackBallHeight * this._scene.terrainExaggeration;
+ this.minimumTrackBallHeight * scene.terrainExaggeration;
var radius = this._ellipsoid.maximumRadius;
this._rotateFactor = 1.0 / radius;
@@ -2616,8 +2836,6 @@ ScreenSpaceCameraController.prototype.update = function () {
scratchPreviousDirection
);
- var scene = this._scene;
- var mode = scene.mode;
if (mode === SceneMode.SCENE2D) {
update2D(this);
} else if (mode === SceneMode.COLUMBUS_VIEW) {
@@ -2629,7 +2847,7 @@ ScreenSpaceCameraController.prototype.update = function () {
}
if (this.enableCollisionDetection && !this._adjustedHeightForTerrain) {
- // Adjust the camera height if the camera moved at all (user input or intertia) and an action didn't already adjust the camera height
+ // Adjust the camera height if the camera moved at all (user input or inertia) and an action didn't already adjust the camera height
var cameraChanged =
!Cartesian3.equals(previousPosition, camera.positionWC) ||
!Cartesian3.equals(previousDirection, camera.directionWC);
@@ -2641,13 +2859,6 @@ ScreenSpaceCameraController.prototype.update = function () {
this._aggregator.reset();
};
-/**
- * @private
- */
-ScreenSpaceCameraController.prototype.adjustedHeightForTerrain = function () {
- return this._adjustedHeightForTerrain;
-};
-
/**
* Returns true if this object was destroyed; otherwise, false.
*
diff --git a/Source/Scene/ShadowMode.js b/Source/Scene/ShadowMode.js
index c8a326643949..95e49b843912 100644
--- a/Source/Scene/ShadowMode.js
+++ b/Source/Scene/ShadowMode.js
@@ -2,7 +2,7 @@
* Specifies whether the object casts or receives shadows from light sources when
* shadows are enabled.
*
- * @exports ShadowMode
+ * @enum {Number}
*/
var ShadowMode = {
/**
@@ -36,13 +36,13 @@ var ShadowMode = {
* @constant
*/
RECEIVE_ONLY: 3,
-
- /**
- * @private
- */
- NUMBER_OF_SHADOW_MODES: 4,
};
+/**
+ * @private
+ */
+ShadowMode.NUMBER_OF_SHADOW_MODES = 4;
+
/**
* @private
*/
@@ -74,4 +74,5 @@ ShadowMode.fromCastReceive = function (castShadows, receiveShadows) {
}
return ShadowMode.DISABLED;
};
+
export default Object.freeze(ShadowMode);
diff --git a/Source/Scene/SingleTileImageryProvider.js b/Source/Scene/SingleTileImageryProvider.js
index 8ad4aa8fe339..f78fe92e4649 100644
--- a/Source/Scene/SingleTileImageryProvider.js
+++ b/Source/Scene/SingleTileImageryProvider.js
@@ -11,6 +11,17 @@ import TileProviderError from "../Core/TileProviderError.js";
import when from "../ThirdParty/when.js";
import ImageryProvider from "./ImageryProvider.js";
+/**
+ * @typedef {Object} SingleTileImageryProvider.ConstructorOptions
+ *
+ * Initialization options for the SingleTileImageryProvider constructor
+ *
+ * @property {Resource|String} url The url for the tile.
+ * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image.
+ * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas.
+ * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
+ */
+
/**
* Provides a single, top-level imagery tile. The single image is assumed to use a
* {@link GeographicTilingScheme}.
@@ -18,11 +29,7 @@ import ImageryProvider from "./ImageryProvider.js";
* @alias SingleTileImageryProvider
* @constructor
*
- * @param {Object} options Object with the following properties:
- * @param {Resource|String} options.url The url for the tile.
- * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image.
- * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas.
- * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
+ * @param {SingleTileImageryProvider.ConstructorOptions} options Object describing initialization options
*
* @see ArcGisMapServerImageryProvider
* @see BingMapsImageryProvider
@@ -41,6 +48,92 @@ function SingleTileImageryProvider(options) {
}
//>>includeEnd('debug');
+ /**
+ * The default alpha blending value of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultNightAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultDayAlpha = undefined;
+
+ /**
+ * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
+ * makes the imagery darker while greater than 1.0 makes it brighter.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultBrightness = undefined;
+
+ /**
+ * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
+ * the contrast while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultContrast = undefined;
+
+ /**
+ * The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultHue = undefined;
+
+ /**
+ * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
+ * saturation while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultSaturation = undefined;
+
+ /**
+ * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultGamma = undefined;
+
+ /**
+ * The default texture minification filter to apply to this provider.
+ *
+ * @type {TextureMinificationFilter}
+ * @default undefined
+ */
+ this.defaultMinificationFilter = undefined;
+
+ /**
+ * The default texture magnification filter to apply to this provider.
+ *
+ * @type {TextureMagnificationFilter}
+ * @default undefined
+ */
+ this.defaultMagnificationFilter = undefined;
+
var resource = Resource.createIfNeeded(options.url);
var rectangle = defaultValue(options.rectangle, Rectangle.MAX_VALUE);
@@ -174,7 +267,7 @@ Object.defineProperties(SingleTileImageryProvider.prototype, {
* Gets the maximum level-of-detail that can be requested. This function should
* not be called before {@link SingleTileImageryProvider#ready} returns true.
* @memberof SingleTileImageryProvider.prototype
- * @type {Number}
+ * @type {Number|undefined}
* @readonly
*/
maximumLevel: {
@@ -359,7 +452,7 @@ SingleTileImageryProvider.prototype.getTileCredits = function (x, y, level) {
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level.
* @param {Request} [request] The request object. Intended for internal use only.
- * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
+ * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if there are too many active requests to the server, and the request
* should be retried later. The resolved image may be either an
* Image or a Canvas DOM object.
diff --git a/Source/Scene/SkyAtmosphere.js b/Source/Scene/SkyAtmosphere.js
index d4b96ba67c7a..33c9904c4cd6 100644
--- a/Source/Scene/SkyAtmosphere.js
+++ b/Source/Scene/SkyAtmosphere.js
@@ -1,5 +1,4 @@
import Cartesian3 from "../Core/Cartesian3.js";
-import Cartesian4 from "../Core/Cartesian4.js";
import defaultValue from "../Core/defaultValue.js";
import defined from "../Core/defined.js";
import destroyObject from "../Core/destroyObject.js";
@@ -7,6 +6,7 @@ import Ellipsoid from "../Core/Ellipsoid.js";
import EllipsoidGeometry from "../Core/EllipsoidGeometry.js";
import GeometryPipeline from "../Core/GeometryPipeline.js";
import CesiumMath from "../Core/Math.js";
+import Matrix4 from "../Core/Matrix4.js";
import VertexFormat from "../Core/VertexFormat.js";
import BufferUsage from "../Renderer/BufferUsage.js";
import DrawCommand from "../Renderer/DrawCommand.js";
@@ -14,8 +14,10 @@ import RenderState from "../Renderer/RenderState.js";
import ShaderProgram from "../Renderer/ShaderProgram.js";
import ShaderSource from "../Renderer/ShaderSource.js";
import VertexArray from "../Renderer/VertexArray.js";
+import SkyAtmosphereCommon from "../Shaders/SkyAtmosphereCommon.js";
import SkyAtmosphereFS from "../Shaders/SkyAtmosphereFS.js";
import SkyAtmosphereVS from "../Shaders/SkyAtmosphereVS.js";
+import Axis from "./Axis.js";
import BlendingState from "./BlendingState.js";
import CullFace from "./CullFace.js";
import SceneMode from "./SceneMode.js";
@@ -51,15 +53,34 @@ function SkyAtmosphere(ellipsoid) {
*/
this.show = true;
+ /**
+ * Compute atmosphere per-fragment instead of per-vertex.
+ * This produces better looking atmosphere with a slight performance penalty.
+ *
+ * @type {Boolean}
+ * @default false
+ */
+ this.perFragmentAtmosphere = false;
+
this._ellipsoid = ellipsoid;
+
+ var outerEllipsoidScale = 1.025;
+ var scaleVector = Cartesian3.multiplyByScalar(
+ ellipsoid.radii,
+ outerEllipsoidScale,
+ new Cartesian3()
+ );
+ this._scaleMatrix = Matrix4.fromScale(scaleVector);
+ this._modelMatrix = new Matrix4();
+
this._command = new DrawCommand({
owner: this,
+ modelMatrix: this._modelMatrix,
});
this._spSkyFromSpace = undefined;
this._spSkyFromAtmosphere = undefined;
- this._spSkyFromSpaceColorCorrect = undefined;
- this._spSkyFromAtmosphereColorCorrect = undefined;
+ this._flags = undefined;
/**
* The hue shift to apply to the atmosphere. Defaults to 0.0 (no shift).
@@ -87,23 +108,23 @@ function SkyAtmosphere(ellipsoid) {
this._hueSaturationBrightness = new Cartesian3();
- // camera height, outer radius, inner radius, dynamic atmosphere color flag
- var cameraAndRadiiAndDynamicAtmosphereColor = new Cartesian4();
+ // outer radius, inner radius, dynamic atmosphere color flag
+ var radiiAndDynamicAtmosphereColor = new Cartesian3();
+
+ radiiAndDynamicAtmosphereColor.x =
+ ellipsoid.maximumRadius * outerEllipsoidScale;
+ radiiAndDynamicAtmosphereColor.y = ellipsoid.maximumRadius;
// Toggles whether the sun position is used. 0 treats the sun as always directly overhead.
- cameraAndRadiiAndDynamicAtmosphereColor.w = 0;
- cameraAndRadiiAndDynamicAtmosphereColor.y = Cartesian3.maximumComponent(
- Cartesian3.multiplyByScalar(ellipsoid.radii, 1.025, new Cartesian3())
- );
- cameraAndRadiiAndDynamicAtmosphereColor.z = ellipsoid.maximumRadius;
+ radiiAndDynamicAtmosphereColor.z = 0;
- this._cameraAndRadiiAndDynamicAtmosphereColor = cameraAndRadiiAndDynamicAtmosphereColor;
+ this._radiiAndDynamicAtmosphereColor = radiiAndDynamicAtmosphereColor;
var that = this;
this._command.uniformMap = {
- u_cameraAndRadiiAndDynamicAtmosphereColor: function () {
- return that._cameraAndRadiiAndDynamicAtmosphereColor;
+ u_radiiAndDynamicAtmosphereColor: function () {
+ return that._radiiAndDynamicAtmosphereColor;
},
u_hsbShift: function () {
that._hueSaturationBrightness.x = that.hueShift;
@@ -136,17 +157,16 @@ SkyAtmosphere.prototype.setDynamicAtmosphereColor = function (
enableLighting,
useSunDirection
) {
- this._cameraAndRadiiAndDynamicAtmosphereColor.w = enableLighting
- ? useSunDirection
- ? 2.0
- : 1.0
- : 0.0;
+ var lightEnum = enableLighting ? (useSunDirection ? 2.0 : 1.0) : 0.0;
+ this._radiiAndDynamicAtmosphereColor.z = lightEnum;
};
+var scratchModelMatrix = new Matrix4();
+
/**
* @private
*/
-SkyAtmosphere.prototype.update = function (frameState) {
+SkyAtmosphere.prototype.update = function (frameState, globe) {
if (!this.show) {
return undefined;
}
@@ -161,18 +181,38 @@ SkyAtmosphere.prototype.update = function (frameState) {
return undefined;
}
+ // Align the ellipsoid geometry so it always faces the same direction as the
+ // camera to reduce artifacts when rendering atmosphere per-vertex
+ var rotationMatrix = Matrix4.fromRotationTranslation(
+ frameState.context.uniformState.inverseViewRotation,
+ Cartesian3.ZERO,
+ scratchModelMatrix
+ );
+ var rotationOffsetMatrix = Matrix4.multiplyTransformation(
+ rotationMatrix,
+ Axis.Y_UP_TO_Z_UP,
+ scratchModelMatrix
+ );
+ var modelMatrix = Matrix4.multiply(
+ this._scaleMatrix,
+ rotationOffsetMatrix,
+ scratchModelMatrix
+ );
+ Matrix4.clone(modelMatrix, this._modelMatrix);
+
+ var context = frameState.context;
+
+ var colorCorrect = hasColorCorrection(this);
+ var translucent = frameState.globeTranslucencyState.translucent;
+ var perFragmentAtmosphere =
+ this.perFragmentAtmosphere || translucent || !defined(globe) || !globe.show;
+
var command = this._command;
if (!defined(command.vertexArray)) {
- var context = frameState.context;
-
var geometry = EllipsoidGeometry.createGeometry(
new EllipsoidGeometry({
- radii: Cartesian3.multiplyByScalar(
- this._ellipsoid.radii,
- 1.025,
- new Cartesian3()
- ),
+ radii: new Cartesian3(1.0, 1.0, 1.0),
slicePartitions: 256,
stackPartitions: 256,
vertexFormat: VertexFormat.POSITION_ONLY,
@@ -192,84 +232,75 @@ SkyAtmosphere.prototype.update = function (frameState) {
blending: BlendingState.ALPHA_BLEND,
depthMask: false,
});
+ }
+
+ var flags = colorCorrect | (perFragmentAtmosphere << 2) | (translucent << 3);
+
+ if (flags !== this._flags) {
+ this._flags = flags;
+
+ var defines = [];
+
+ if (colorCorrect) {
+ defines.push("COLOR_CORRECT");
+ }
+
+ if (perFragmentAtmosphere) {
+ defines.push("PER_FRAGMENT_ATMOSPHERE");
+ }
+
+ if (translucent) {
+ defines.push("GLOBE_TRANSLUCENT");
+ }
var vs = new ShaderSource({
- defines: ["SKY_FROM_SPACE"],
- sources: [SkyAtmosphereVS],
+ defines: defines.concat("SKY_FROM_SPACE"),
+ sources: [SkyAtmosphereCommon, SkyAtmosphereVS],
+ });
+
+ var fs = new ShaderSource({
+ defines: defines.concat("SKY_FROM_SPACE"),
+ sources: [SkyAtmosphereCommon, SkyAtmosphereFS],
});
this._spSkyFromSpace = ShaderProgram.fromCache({
context: context,
vertexShaderSource: vs,
- fragmentShaderSource: SkyAtmosphereFS,
+ fragmentShaderSource: fs,
});
vs = new ShaderSource({
- defines: ["SKY_FROM_ATMOSPHERE"],
- sources: [SkyAtmosphereVS],
+ defines: defines.concat("SKY_FROM_ATMOSPHERE"),
+ sources: [SkyAtmosphereCommon, SkyAtmosphereVS],
});
- this._spSkyFromAtmosphere = ShaderProgram.fromCache({
- context: context,
- vertexShaderSource: vs,
- fragmentShaderSource: SkyAtmosphereFS,
- });
- }
- // Compile the color correcting versions of the shader on demand
- var useColorCorrect = colorCorrect(this);
- if (
- useColorCorrect &&
- (!defined(this._spSkyFromSpaceColorCorrect) ||
- !defined(this._spSkyFromAtmosphereColorCorrect))
- ) {
- var contextColorCorrect = frameState.context;
-
- var vsColorCorrect = new ShaderSource({
- defines: ["SKY_FROM_SPACE"],
- sources: [SkyAtmosphereVS],
- });
- var fsColorCorrect = new ShaderSource({
- defines: ["COLOR_CORRECT"],
- sources: [SkyAtmosphereFS],
+ fs = new ShaderSource({
+ defines: defines.concat("SKY_FROM_ATMOSPHERE"),
+ sources: [SkyAtmosphereCommon, SkyAtmosphereFS],
});
- this._spSkyFromSpaceColorCorrect = ShaderProgram.fromCache({
- context: contextColorCorrect,
- vertexShaderSource: vsColorCorrect,
- fragmentShaderSource: fsColorCorrect,
- });
- vsColorCorrect = new ShaderSource({
- defines: ["SKY_FROM_ATMOSPHERE"],
- sources: [SkyAtmosphereVS],
- });
- this._spSkyFromAtmosphereColorCorrect = ShaderProgram.fromCache({
- context: contextColorCorrect,
- vertexShaderSource: vsColorCorrect,
- fragmentShaderSource: fsColorCorrect,
+ this._spSkyFromAtmosphere = ShaderProgram.fromCache({
+ context: context,
+ vertexShaderSource: vs,
+ fragmentShaderSource: fs,
});
}
var cameraPosition = frameState.camera.positionWC;
-
var cameraHeight = Cartesian3.magnitude(cameraPosition);
- this._cameraAndRadiiAndDynamicAtmosphereColor.x = cameraHeight;
- if (cameraHeight > this._cameraAndRadiiAndDynamicAtmosphereColor.y) {
+ if (cameraHeight > this._radiiAndDynamicAtmosphereColor.x) {
// Camera in space
- command.shaderProgram = useColorCorrect
- ? this._spSkyFromSpaceColorCorrect
- : this._spSkyFromSpace;
+ command.shaderProgram = this._spSkyFromSpace;
} else {
// Camera in atmosphere
- command.shaderProgram = useColorCorrect
- ? this._spSkyFromAtmosphereColorCorrect
- : this._spSkyFromAtmosphere;
+ command.shaderProgram = this._spSkyFromAtmosphere;
}
return command;
};
-function colorCorrect(skyAtmosphere) {
+function hasColorCorrection(skyAtmosphere) {
return !(
CesiumMath.equalsEpsilon(
skyAtmosphere.hueShift,
@@ -325,12 +356,6 @@ SkyAtmosphere.prototype.destroy = function () {
this._spSkyFromSpace = this._spSkyFromSpace && this._spSkyFromSpace.destroy();
this._spSkyFromAtmosphere =
this._spSkyFromAtmosphere && this._spSkyFromAtmosphere.destroy();
- this._spSkyFromSpaceColorCorrect =
- this._spSkyFromSpaceColorCorrect &&
- this._spSkyFromSpaceColorCorrect.destroy();
- this._spSkyFromAtmosphereColorCorrect =
- this._spSkyFromAtmosphereColorCorrect &&
- this._spSkyFromAtmosphereColorCorrect.destroy();
return destroyObject(this);
};
export default SkyAtmosphere;
diff --git a/Source/Scene/StencilFunction.js b/Source/Scene/StencilFunction.js
index 2a0fc199677a..f6affdf4a6b9 100644
--- a/Source/Scene/StencilFunction.js
+++ b/Source/Scene/StencilFunction.js
@@ -3,7 +3,7 @@ import WebGLConstants from "../Core/WebGLConstants.js";
/**
* Determines the function used to compare stencil values for the stencil test.
*
- * @exports StencilFunction
+ * @enum {Number}
*/
var StencilFunction = {
/**
diff --git a/Source/Scene/StencilOperation.js b/Source/Scene/StencilOperation.js
index b288b1d2edb2..aad78dcbd7be 100644
--- a/Source/Scene/StencilOperation.js
+++ b/Source/Scene/StencilOperation.js
@@ -3,7 +3,7 @@ import WebGLConstants from "../Core/WebGLConstants.js";
/**
* Determines the action taken based on the result of the stencil test.
*
- * @exports StencilOperation
+ * @enum {Number}
*/
var StencilOperation = {
/**
diff --git a/Source/Scene/StyleExpression.js b/Source/Scene/StyleExpression.js
index acbecdf78fc6..4e809a612587 100644
--- a/Source/Scene/StyleExpression.js
+++ b/Source/Scene/StyleExpression.js
@@ -55,7 +55,7 @@ StyleExpression.prototype.evaluateColor = function (feature, result) {
* Returns undefined if the shader function can't be generated from this expression.
*
* @param {String} functionName Name to give to the generated function.
- * @param {String} attributePrefix Prefix that is added to any variable names to access vertex attributes.
+ * @param {String} propertyNameMap Maps property variable names to shader attribute names.
* @param {Object} shaderState Stores information about the generated shader function, including whether it is translucent.
* @param {String} returnType The return type of the generated function.
*
@@ -65,7 +65,7 @@ StyleExpression.prototype.evaluateColor = function (feature, result) {
*/
StyleExpression.prototype.getShaderFunction = function (
functionName,
- attributePrefix,
+ propertyNameMap,
shaderState,
returnType
) {
diff --git a/Source/Scene/TextureAtlas.js b/Source/Scene/TextureAtlas.js
index f640000377bd..446be3b0505e 100644
--- a/Source/Scene/TextureAtlas.js
+++ b/Source/Scene/TextureAtlas.js
@@ -354,7 +354,7 @@ function addImage(textureAtlas, image, index) {
* the existing index is used.
*
* @param {String} id An identifier to detect whether the image already exists in the atlas.
- * @param {Image|Canvas|String|Resource|Promise|TextureAtlas~CreateImageCallback} image An image or canvas to add to the texture atlas,
+ * @param {HTMLImageElement|HTMLCanvasElement|String|Resource|Promise|TextureAtlas.CreateImageCallback} image An image or canvas to add to the texture atlas,
* or a URL to an Image, or a Promise for an image, or a function that creates an image.
* @returns {Promise.} A Promise for the image index.
*/
@@ -494,8 +494,8 @@ TextureAtlas.prototype.destroy = function () {
/**
* A function that creates an image.
- * @callback TextureAtlas~CreateImageCallback
+ * @callback TextureAtlas.CreateImageCallback
* @param {String} id The identifier of the image to load.
- * @returns {Image|Promise} The image, or a promise that will resolve to an image.
+ * @returns {HTMLImageElement|Promise} The image, or a promise that will resolve to an image.
*/
export default TextureAtlas;
diff --git a/Source/Scene/TileBoundingVolume.js b/Source/Scene/TileBoundingVolume.js
index 3a9093cd3c01..06d655078a81 100644
--- a/Source/Scene/TileBoundingVolume.js
+++ b/Source/Scene/TileBoundingVolume.js
@@ -4,6 +4,9 @@ import DeveloperError from "../Core/DeveloperError.js";
* Defines a bounding volume for a tile. This type describes an interface
* and is not intended to be instantiated directly.
*
+ * @alias TileBoundingVolume
+ * @constructor
+ *
* @see TileBoundingRegion
* @see TileBoundingSphere
* @see TileOrientedBoundingBox
@@ -15,8 +18,6 @@ function TileBoundingVolume() {}
/**
* The underlying bounding volume.
*
- * @memberof TileBoundingVolume.prototype
- *
* @type {Object}
* @readonly
*/
@@ -25,8 +26,6 @@ TileBoundingVolume.prototype.boundingVolume = undefined;
/**
* The underlying bounding sphere.
*
- * @memberof TileBoundingVolume.prototype
- *
* @type {BoundingSphere}
* @readonly
*/
diff --git a/Source/Scene/TileCoordinatesImageryProvider.js b/Source/Scene/TileCoordinatesImageryProvider.js
index ee56a9b317bd..7194766bcefd 100644
--- a/Source/Scene/TileCoordinatesImageryProvider.js
+++ b/Source/Scene/TileCoordinatesImageryProvider.js
@@ -5,6 +5,20 @@ import Event from "../Core/Event.js";
import GeographicTilingScheme from "../Core/GeographicTilingScheme.js";
import when from "../ThirdParty/when.js";
+/**
+ * @typedef {Object} TileCoordinatesImageryProvider.ConstructorOptions
+ *
+ * Initialization options for the TileCoordinatesImageryProvider constructor
+ *
+ * @property {TilingScheme} [tilingScheme=new GeographicTilingScheme()] The tiling scheme for which to draw tiles.
+ * @property {Ellipsoid} [ellipsoid] The ellipsoid. If the tilingScheme is specified,
+ * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither
+ * parameter is specified, the WGS84 ellipsoid is used.
+ * @property {Color} [color=Color.YELLOW] The color to draw the tile box and label.
+ * @property {Number} [tileWidth=256] The width of the tile for level-of-detail selection purposes.
+ * @property {Number} [tileHeight=256] The height of the tile for level-of-detail selection purposes.
+ */
+
/**
* An {@link ImageryProvider} that draws a box around every rendered tile in the tiling scheme, and draws
* a label inside it indicating the X, Y, Level coordinates of the tile. This is mostly useful for
@@ -13,14 +27,7 @@ import when from "../ThirdParty/when.js";
* @alias TileCoordinatesImageryProvider
* @constructor
*
- * @param {Object} [options] Object with the following properties:
- * @param {TilingScheme} [options.tilingScheme=new GeographicTilingScheme()] The tiling scheme for which to draw tiles.
- * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified,
- * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither
- * parameter is specified, the WGS84 ellipsoid is used.
- * @param {Color} [options.color=Color.YELLOW] The color to draw the tile box and label.
- * @param {Number} [options.tileWidth=256] The width of the tile for level-of-detail selection purposes.
- * @param {Number} [options.tileHeight=256] The height of the tile for level-of-detail selection purposes.
+ * @param {TileCoordinatesImageryProvider.ConstructorOptions} [options] Object describing initialization options
*/
function TileCoordinatesImageryProvider(options) {
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
@@ -33,6 +40,92 @@ function TileCoordinatesImageryProvider(options) {
this._tileWidth = defaultValue(options.tileWidth, 256);
this._tileHeight = defaultValue(options.tileHeight, 256);
this._readyPromise = when.resolve(true);
+
+ /**
+ * The default alpha blending value of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultNightAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultDayAlpha = undefined;
+
+ /**
+ * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
+ * makes the imagery darker while greater than 1.0 makes it brighter.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultBrightness = undefined;
+
+ /**
+ * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
+ * the contrast while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultContrast = undefined;
+
+ /**
+ * The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultHue = undefined;
+
+ /**
+ * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
+ * saturation while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultSaturation = undefined;
+
+ /**
+ * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultGamma = undefined;
+
+ /**
+ * The default texture minification filter to apply to this provider.
+ *
+ * @type {TextureMinificationFilter}
+ * @default undefined
+ */
+ this.defaultMinificationFilter = undefined;
+
+ /**
+ * The default texture magnification filter to apply to this provider.
+ *
+ * @type {TextureMagnificationFilter}
+ * @default undefined
+ */
+ this.defaultMagnificationFilter = undefined;
}
Object.defineProperties(TileCoordinatesImageryProvider.prototype, {
@@ -78,7 +171,7 @@ Object.defineProperties(TileCoordinatesImageryProvider.prototype, {
* Gets the maximum level-of-detail that can be requested. This function should
* not be called before {@link TileCoordinatesImageryProvider#ready} returns true.
* @memberof TileCoordinatesImageryProvider.prototype
- * @type {Number}
+ * @type {Number|undefined}
* @readonly
*/
maximumLevel: {
@@ -235,7 +328,7 @@ TileCoordinatesImageryProvider.prototype.getTileCredits = function (
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level.
* @param {Request} [request] The request object. Intended for internal use only.
- * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
+ * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if there are too many active requests to the server, and the request
* should be retried later. The resolved image may be either an
* Image or a Canvas DOM object.
diff --git a/Source/Scene/TileDiscardPolicy.js b/Source/Scene/TileDiscardPolicy.js
index c50a02a8611e..1977b881fcac 100644
--- a/Source/Scene/TileDiscardPolicy.js
+++ b/Source/Scene/TileDiscardPolicy.js
@@ -26,7 +26,7 @@ TileDiscardPolicy.prototype.isReady = DeveloperError.throwInstantiationError;
* Given a tile image, decide whether to discard that image.
* @function
*
- * @param {Image} image An image to test.
+ * @param {HTMLImageElement} image An image to test.
* @returns {Boolean} True if the image should be discarded; otherwise, false.
*/
TileDiscardPolicy.prototype.shouldDiscardImage =
diff --git a/Source/Scene/TileMapServiceImageryProvider.js b/Source/Scene/TileMapServiceImageryProvider.js
index 9f16e1e8392d..2f27b2c8d964 100644
--- a/Source/Scene/TileMapServiceImageryProvider.js
+++ b/Source/Scene/TileMapServiceImageryProvider.js
@@ -14,32 +14,39 @@ import when from "../ThirdParty/when.js";
import UrlTemplateImageryProvider from "./UrlTemplateImageryProvider.js";
/**
- * An imagery provider that provides tiled imagery as generated by
- * {@link http://www.maptiler.org/|MapTiler}, {@link http://www.klokan.cz/projects/gdal2tiles/|GDAL2Tiles}, etc.
+ * @typedef {Object} TileMapServiceImageryProvider.ConstructorOptions
*
- * @alias TileMapServiceImageryProvider
- * @constructor
+ * Initialization options for the TileMapServiceImageryProvider constructor
*
- * @param {Object} [options] Object with the following properties:
- * @param {Resource|String|Promise|Promise} [options.url='.'] Path to image tiles on server.
- * @param {String} [options.fileExtension='png'] The file extension for images on the server.
- * @param {Credit|String} [options.credit=''] A credit for the data source, which is displayed on the canvas.
- * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying
+ * @property {Resource|String|Promise|Promise} [url='.'] Path to image tiles on server.
+ * @property {String} [fileExtension='png'] The file extension for images on the server.
+ * @property {Credit|String} [credit=''] A credit for the data source, which is displayed on the canvas.
+ * @property {Number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying
* this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely
* to result in rendering problems.
- * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
- * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image.
- * @param {TilingScheme} [options.tilingScheme] The tiling scheme specifying how the ellipsoidal
+ * @property {Number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
+ * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image.
+ * @property {TilingScheme} [tilingScheme] The tiling scheme specifying how the ellipsoidal
* surface is broken into tiles. If this parameter is not provided, a {@link WebMercatorTilingScheme}
* is used.
- * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified,
+ * @property {Ellipsoid} [ellipsoid] The ellipsoid. If the tilingScheme is specified,
* this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither
* parameter is specified, the WGS84 ellipsoid is used.
- * @param {Number} [options.tileWidth=256] Pixel width of image tiles.
- * @param {Number} [options.tileHeight=256] Pixel height of image tiles.
- * @param {Boolean} [options.flipXY] Older versions of gdal2tiles.py flipped X and Y values in tilemapresource.xml.
+ * @property {Number} [tileWidth=256] Pixel width of image tiles.
+ * @property {Number} [tileHeight=256] Pixel height of image tiles.
+ * @property {Boolean} [flipXY] Older versions of gdal2tiles.py flipped X and Y values in tilemapresource.xml.
* Specifying this option will do the same, allowing for loading of these incorrect tilesets.
- * @returns {UrlTemplateImageryProvider} The imagery provider.
+ */
+
+/**
+ * An imagery provider that provides tiled imagery as generated by
+ * {@link http://www.maptiler.org/|MapTiler}, {@link http://www.klokan.cz/projects/gdal2tiles/|GDAL2Tiles}, etc.
+ *
+ * @alias TileMapServiceImageryProvider
+ * @constructor
+ * @extends UrlTemplateImageryProvider
+ *
+ * @param {TileMapServiceImageryProvider.ConstructorOptions} options Object describing initialization options
*
* @see ArcGisMapServerImageryProvider
* @see BingMapsImageryProvider
diff --git a/Source/Scene/TimeDynamicImagery.js b/Source/Scene/TimeDynamicImagery.js
index 7afa8d904349..ef579f198928 100644
--- a/Source/Scene/TimeDynamicImagery.js
+++ b/Source/Scene/TimeDynamicImagery.js
@@ -111,7 +111,7 @@ Object.defineProperties(TimeDynamicImagery.prototype, {
* @param {Number} level The tile level.
* @param {Request} [request] The request object. Intended for internal use only.
*
- * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
+ * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if the tile is not in the cache.
*/
TimeDynamicImagery.prototype.getFromCache = function (x, y, level, request) {
diff --git a/Source/Scene/Tonemapper.js b/Source/Scene/Tonemapper.js
index 4c34f7515f7f..2deefe17b20b 100644
--- a/Source/Scene/Tonemapper.js
+++ b/Source/Scene/Tonemapper.js
@@ -1,7 +1,7 @@
/**
* A tonemapping algorithm when rendering with high dynamic range.
*
- * @exports Tonemapper
+ * @enum {Number}
* @private
*/
var Tonemapper = {
diff --git a/Source/Scene/TweenCollection.js b/Source/Scene/TweenCollection.js
index ff1515276763..e27df7182912 100644
--- a/Source/Scene/TweenCollection.js
+++ b/Source/Scene/TweenCollection.js
@@ -45,7 +45,7 @@ function Tween(
* The callback to call if the tween is canceled either because {@link Tween#cancelTween}
* was called or because the tween was removed from the collection.
*
- * @type {TweenCollection~TweenCancelledCallback}
+ * @type {TweenCollection.TweenCancelledCallback}
*/
this.cancel = cancel;
@@ -125,7 +125,7 @@ Object.defineProperties(Tween.prototype, {
* The callback to call at each animation update (usually tied to the a rendered frame).
* @memberof Tween.prototype
*
- * @type {TweenCollection~TweenUpdateCallback}
+ * @type {TweenCollection.TweenUpdateCallback}
* @readonly
*/
update: {
@@ -138,7 +138,7 @@ Object.defineProperties(Tween.prototype, {
* The callback to call when the tween finishes animating.
* @memberof Tween.prototype
*
- * @type {TweenCollection~TweenCompleteCallback}
+ * @type {TweenCollection.TweenCompleteCallback}
* @readonly
*/
complete: {
@@ -204,9 +204,9 @@ Object.defineProperties(TweenCollection.prototype, {
* @param {Number} options.duration The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops.
* @param {Number} [options.delay=0.0] The delay, in seconds, before the tween starts animating.
* @param {EasingFunction} [options.easingFunction=EasingFunction.LINEAR_NONE] Determines the curve for animtion.
- * @param {TweenCollection~TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame).
- * @param {TweenCollection~TweenCompleteCallback} [options.complete] The callback to call when the tween finishes animating.
- * @param {TweenCollection~TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection.
+ * @param {TweenCollection.TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame).
+ * @param {TweenCollection.TweenCompleteCallback} [options.complete] The callback to call when the tween finishes animating.
+ * @param {TweenCollection.TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection.
* @returns {Tween} The tween.
*
* @exception {DeveloperError} options.duration must be positive.
@@ -284,9 +284,9 @@ TweenCollection.prototype.add = function (options) {
* @param {Number} [options.duration=3.0] The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops.
* @param {Number} [options.delay=0.0] The delay, in seconds, before the tween starts animating.
* @param {EasingFunction} [options.easingFunction=EasingFunction.LINEAR_NONE] Determines the curve for animtion.
- * @param {TweenCollection~TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame).
- * @param {TweenCollection~TweenCompleteCallback} [options.complete] The callback to call when the tween finishes animating.
- * @param {TweenCollection~TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection.
+ * @param {TweenCollection.TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame).
+ * @param {TweenCollection.TweenCompleteCallback} [options.complete] The callback to call when the tween finishes animating.
+ * @param {TweenCollection.TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection.
* @returns {Tween} The tween.
*
* @exception {DeveloperError} options.object must have the specified property.
@@ -350,9 +350,9 @@ TweenCollection.prototype.addProperty = function (options) {
* @param {Number} [options.duration=3.0] The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops.
* @param {Number} [options.delay=0.0] The delay, in seconds, before the tween starts animating.
* @param {EasingFunction} [options.easingFunction=EasingFunction.LINEAR_NONE] Determines the curve for animtion.
- * @param {TweenCollection~TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame).
- * @param {TweenCollection~TweenCompleteCallback} [options.complete] The callback to call when the tween finishes animating.
- * @param {TweenCollection~TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection.
+ * @param {TweenCollection.TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame).
+ * @param {TweenCollection.TweenCompleteCallback} [options.complete] The callback to call when the tween finishes animating.
+ * @param {TweenCollection.TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection.
* @returns {Tween} The tween.
*
* @exception {DeveloperError} material has no properties with alpha components.
@@ -423,8 +423,8 @@ TweenCollection.prototype.addAlpha = function (options) {
* @param {Number} [options.duration=3.0] The duration, in seconds, for the tween. The tween is automatically removed from the collection when it stops.
* @param {Number} [options.delay=0.0] The delay, in seconds, before the tween starts animating.
* @param {EasingFunction} [options.easingFunction=EasingFunction.LINEAR_NONE] Determines the curve for animtion.
- * @param {TweenCollection~TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame).
- * @param {TweenCollection~TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection.
+ * @param {TweenCollection.TweenUpdateCallback} [options.update] The callback to call at each animation update (usually tied to the a rendered frame).
+ * @param {TweenCollection.TweenCancelledCallback} [options.cancel] The callback to call if the tween is canceled either because {@link Tween#cancelTween} was called or because the tween was removed from the collection.
* @returns {Tween} The tween.
*
* @exception {DeveloperError} material.uniforms must have an offset property.
@@ -573,16 +573,16 @@ TweenCollection.prototype.update = function (time) {
/**
* A function that will execute when a tween completes.
- * @callback TweenCollection~TweenCompleteCallback
+ * @callback TweenCollection.TweenCompleteCallback
*/
/**
* A function that will execute when a tween updates.
- * @callback TweenCollection~TweenUpdateCallback
+ * @callback TweenCollection.TweenUpdateCallback
*/
/**
* A function that will execute when a tween is cancelled.
- * @callback TweenCollection~TweenCancelledCallback
+ * @callback TweenCollection.TweenCancelledCallback
*/
export default TweenCollection;
diff --git a/Source/Scene/UrlTemplateImageryProvider.js b/Source/Scene/UrlTemplateImageryProvider.js
index f8c49fc30c4e..3a8482c1f39a 100644
--- a/Source/Scene/UrlTemplateImageryProvider.js
+++ b/Source/Scene/UrlTemplateImageryProvider.js
@@ -50,13 +50,12 @@ var pickFeaturesTags = combine(tags, {
});
/**
- * Provides imagery by requesting tiles using a specified URL template.
+ * @typedef {Object} UrlTemplateImageryProvider.ConstructorOptions
*
- * @alias UrlTemplateImageryProvider
- * @constructor
+ * Initialization options for the UrlTemplateImageryProvider constructor
*
- * @param {Promise.|Object} [options] Object with the following properties:
- * @param {Resource|String} options.url The URL template to use to request tiles. It has the following keywords:
+ * @property {Promise.|Object} [options] Object with the following properties:
+ * @property {Resource|String} url The URL template to use to request tiles. It has the following keywords:
*
* {z}
: The level of the tile in the tiling scheme. Level zero is the root of the quadtree pyramid.
* {x}
: The tile X coordinate in the tiling scheme, where 0 is the Westernmost tile.
@@ -76,7 +75,7 @@ var pickFeaturesTags = combine(tags, {
* {width}
: The width of each tile in pixels.
* {height}
: The height of each tile in pixels.
*
- * @param {Resource|String} [options.pickFeaturesUrl] The URL template to use to pick features. If this property is not specified,
+ * @property {Resource|String} [pickFeaturesUrl] The URL template to use to pick features. If this property is not specified,
* {@link UrlTemplateImageryProvider#pickFeatures} will immediately returned undefined, indicating no
* features picked. The URL template supports all of the keywords supported by the url
* parameter, plus the following:
@@ -91,7 +90,7 @@ var pickFeaturesTags = combine(tags, {
* {latitudeProjected}
: The latitude of the picked position in the projected coordinates of the tiling scheme.
* {format}
: The format in which to get feature information, as specified in the {@link GetFeatureInfoFormat}.
*
- * @param {Object} [options.urlSchemeZeroPadding] Gets the URL scheme zero padding for each tile coordinate. The format is '000' where
+ * @property {Object} [urlSchemeZeroPadding] Gets the URL scheme zero padding for each tile coordinate. The format is '000' where
* each coordinate will be padded on the left with zeros to match the width of the passed string of zeros. e.g. Setting:
* urlSchemeZeroPadding : { '{x}' : '0000'}
* will cause an 'x' value of 12 to return the string '0012' for {x} in the generated URL.
@@ -104,40 +103,48 @@ var pickFeaturesTags = combine(tags, {
* {reverseY}
: The zero padding for the tile reverseY coordinate in the tiling scheme.
* {reverseZ}
: The zero padding for the reverseZ coordinate of the tile in the tiling scheme.
*
- * @param {String|String[]} [options.subdomains='abc'] The subdomains to use for the {s}
placeholder in the URL template.
+ * @property {String|String[]} [subdomains='abc'] The subdomains to use for the {s}
placeholder in the URL template.
* If this parameter is a single string, each character in the string is a subdomain. If it is
* an array, each element in the array is a subdomain.
- * @param {Credit|String} [options.credit=''] A credit for the data source, which is displayed on the canvas.
- * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying
+ * @property {Credit|String} [credit=''] A credit for the data source, which is displayed on the canvas.
+ * @property {Number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when specifying
* this that the number of tiles at the minimum level is small, such as four or less. A larger number is likely
* to result in rendering problems.
- * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
- * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image.
- * @param {TilingScheme} [options.tilingScheme=WebMercatorTilingScheme] The tiling scheme specifying how the ellipsoidal
+ * @property {Number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
+ * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle, in radians, covered by the image.
+ * @property {TilingScheme} [tilingScheme=WebMercatorTilingScheme] The tiling scheme specifying how the ellipsoidal
* surface is broken into tiles. If this parameter is not provided, a {@link WebMercatorTilingScheme}
* is used.
- * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified,
+ * @property {Ellipsoid} [ellipsoid] The ellipsoid. If the tilingScheme is specified,
* this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither
* parameter is specified, the WGS84 ellipsoid is used.
- * @param {Number} [options.tileWidth=256] Pixel width of image tiles.
- * @param {Number} [options.tileHeight=256] Pixel height of image tiles.
- * @param {Boolean} [options.hasAlphaChannel=true] true if the images provided by this imagery provider
+ * @property {Number} [tileWidth=256] Pixel width of image tiles.
+ * @property {Number} [tileHeight=256] Pixel height of image tiles.
+ * @property {Boolean} [hasAlphaChannel=true] true if the images provided by this imagery provider
* include an alpha channel; otherwise, false. If this property is false, an alpha channel, if
* present, will be ignored. If this property is true, any images without an alpha channel will
* be treated as if their alpha is 1.0 everywhere. When this property is false, memory usage
* and texture upload time are potentially reduced.
- * @param {GetFeatureInfoFormat[]} [options.getFeatureInfoFormats] The formats in which to get feature information at a
+ * @property {GetFeatureInfoFormat[]} [getFeatureInfoFormats] The formats in which to get feature information at a
* specific location when {@link UrlTemplateImageryProvider#pickFeatures} is invoked. If this
* parameter is not specified, feature picking is disabled.
- * @param {Boolean} [options.enablePickFeatures=true] If true, {@link UrlTemplateImageryProvider#pickFeatures} will
- * request the options.pickFeaturesUrl
and attempt to interpret the features included in the response. If false,
+ * @property {Boolean} [enablePickFeatures=true] If true, {@link UrlTemplateImageryProvider#pickFeatures} will
+ * request the pickFeaturesUrl
and attempt to interpret the features included in the response. If false,
* {@link UrlTemplateImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable
* features) without communicating with the server. Set this property to false if you know your data
* source does not support picking features or if you don't want this provider's features to be pickable. Note
* that this can be dynamically overridden by modifying the {@link UriTemplateImageryProvider#enablePickFeatures}
* property.
- * @param {Object} [options.customTags] Allow to replace custom keywords in the URL template. The object must have strings as keys and functions as values.
+ * @property {Object} [customTags] Allow to replace custom keywords in the URL template. The object must have strings as keys and functions as values.
+ */
+
+/**
+ * Provides imagery by requesting tiles using a specified URL template.
*
+ * @alias UrlTemplateImageryProvider
+ * @constructor
+ *
+ * @param {UrlTemplateImageryProvider.ConstructorOptions} options Object describing initialization options
*
* @example
* // Access Natural Earth II imagery, which uses a TMS tiling scheme and Geographic (EPSG:4326) project
@@ -209,6 +216,92 @@ function UrlTemplateImageryProvider(options) {
this._tags = undefined;
this._pickFeaturesTags = undefined;
+ /**
+ * The default alpha blending value of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultNightAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultDayAlpha = undefined;
+
+ /**
+ * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
+ * makes the imagery darker while greater than 1.0 makes it brighter.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultBrightness = undefined;
+
+ /**
+ * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
+ * the contrast while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultContrast = undefined;
+
+ /**
+ * The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultHue = undefined;
+
+ /**
+ * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
+ * saturation while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultSaturation = undefined;
+
+ /**
+ * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultGamma = undefined;
+
+ /**
+ * The default texture minification filter to apply to this provider.
+ *
+ * @type {TextureMinificationFilter}
+ * @default undefined
+ */
+ this.defaultMinificationFilter = undefined;
+
+ /**
+ * The default texture magnification filter to apply to this provider.
+ *
+ * @type {TextureMagnificationFilter}
+ * @default undefined
+ */
+ this.defaultMagnificationFilter = undefined;
+
/**
* Gets or sets a value indicating whether feature picking is enabled. If true, {@link UrlTemplateImageryProvider#pickFeatures} will
* request the options.pickFeaturesUrl
and attempt to interpret the features included in the response. If false,
@@ -281,7 +374,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, {
/**
* Gets the URL template to use to use to pick features. If this property is not specified,
- * {@link UrlTemplateImageryProvider#pickFeatures} will immediately returned undefined, indicating no
+ * {@link UrlTemplateImageryProvider#pickFeatures} will immediately return undefined, indicating no
* features picked. The URL template supports all of the keywords supported by the
* {@link UrlTemplateImageryProvider#url} property, plus the following:
*
@@ -364,7 +457,7 @@ Object.defineProperties(UrlTemplateImageryProvider.prototype, {
* Gets the maximum level-of-detail that can be requested, or undefined if there is no limit.
* This function should not be called before {@link UrlTemplateImageryProvider#ready} returns true.
* @memberof UrlTemplateImageryProvider.prototype
- * @type {Number}
+ * @type {Number|undefined}
* @readonly
* @default undefined
*/
@@ -660,7 +753,7 @@ UrlTemplateImageryProvider.prototype.getTileCredits = function (x, y, level) {
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level.
* @param {Request} [request] The request object. Intended for internal use only.
- * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
+ * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if there are too many active requests to the server, and the request
* should be retried later. The resolved image may be either an
* Image or a Canvas DOM object.
diff --git a/Source/Scene/Vector3DTileGeometry.js b/Source/Scene/Vector3DTileGeometry.js
index 89095aa3e9aa..63e8ca8b74b3 100644
--- a/Source/Scene/Vector3DTileGeometry.js
+++ b/Source/Scene/Vector3DTileGeometry.js
@@ -139,7 +139,7 @@ Object.defineProperties(Vector3DTileGeometry.prototype, {
/**
* Gets a promise that resolves when the primitive is ready to render.
* @memberof Vector3DTileGeometry.prototype
- * @type {Promise}
+ * @type {Promise}
* @readonly
*/
readyPromise: {
diff --git a/Source/Scene/Vector3DTilePoints.js b/Source/Scene/Vector3DTilePoints.js
index 9d2c9d5951dd..b6cd9346dc90 100644
--- a/Source/Scene/Vector3DTilePoints.js
+++ b/Source/Scene/Vector3DTilePoints.js
@@ -92,7 +92,7 @@ Object.defineProperties(Vector3DTilePoints.prototype, {
/**
* Gets a promise that resolves when the primitive is ready to render.
* @memberof Vector3DTilePoints.prototype
- * @type {Promise}
+ * @type {Promise}
* @readonly
*/
readyPromise: {
diff --git a/Source/Scene/Vector3DTilePolygons.js b/Source/Scene/Vector3DTilePolygons.js
index 50a1712ba549..afe4f440b18e 100644
--- a/Source/Scene/Vector3DTilePolygons.js
+++ b/Source/Scene/Vector3DTilePolygons.js
@@ -143,7 +143,7 @@ Object.defineProperties(Vector3DTilePolygons.prototype, {
/**
* Gets a promise that resolves when the primitive is ready to render.
* @memberof Vector3DTilePolygons.prototype
- * @type {Promise}
+ * @type {Promise}
* @readonly
*/
readyPromise: {
diff --git a/Source/Scene/Vector3DTilePolylines.js b/Source/Scene/Vector3DTilePolylines.js
index 13c363a1056b..d9672ddd222b 100644
--- a/Source/Scene/Vector3DTilePolylines.js
+++ b/Source/Scene/Vector3DTilePolylines.js
@@ -121,7 +121,7 @@ Object.defineProperties(Vector3DTilePolylines.prototype, {
/**
* Gets a promise that resolves when the primitive is ready to render.
* @memberof Vector3DTilePolylines.prototype
- * @type {Promise}
+ * @type {Promise}
* @readonly
*/
readyPromise: {
diff --git a/Source/Scene/Vector3DTilePrimitive.js b/Source/Scene/Vector3DTilePrimitive.js
index 142b351335d3..fdc3edce63bb 100644
--- a/Source/Scene/Vector3DTilePrimitive.js
+++ b/Source/Scene/Vector3DTilePrimitive.js
@@ -81,8 +81,6 @@ function Vector3DTilePrimitive(options) {
// Only used with WebGL 2 to ping-pong ibos after copy.
this._vaSwap = undefined;
- this._rsStencilPreloadPass = undefined;
- this._rsStencilPreloadPass3DTiles = undefined;
this._rsStencilDepthPass = undefined;
this._rsStencilDepthPass3DTiles = undefined;
this._rsColorPass = undefined;
@@ -369,7 +367,7 @@ function createShaders(primitive, context) {
});
}
-function getStencilPreloadRenderState(mask3DTiles) {
+function getStencilDepthRenderState(mask3DTiles) {
var stencilFunction = mask3DTiles
? StencilFunction.EQUAL
: StencilFunction.ALWAYS;
@@ -386,49 +384,13 @@ function getStencilPreloadRenderState(mask3DTiles) {
frontOperation: {
fail: StencilOperation.KEEP,
zFail: StencilOperation.DECREMENT_WRAP,
- zPass: StencilOperation.DECREMENT_WRAP,
+ zPass: StencilOperation.KEEP,
},
backFunction: stencilFunction,
backOperation: {
fail: StencilOperation.KEEP,
zFail: StencilOperation.INCREMENT_WRAP,
- zPass: StencilOperation.INCREMENT_WRAP,
- },
- reference: StencilConstants.CESIUM_3D_TILE_MASK,
- mask: StencilConstants.CESIUM_3D_TILE_MASK,
- },
- stencilMask: StencilConstants.CLASSIFICATION_MASK,
- depthTest: {
- enabled: false,
- },
- depthMask: false,
- };
-}
-
-function getStencilDepthRenderState(mask3DTiles) {
- var stencilFunction = mask3DTiles
- ? StencilFunction.EQUAL
- : StencilFunction.ALWAYS;
- return {
- colorMask: {
- red: false,
- green: false,
- blue: false,
- alpha: false,
- },
- stencilTest: {
- enabled: true,
- frontFunction: stencilFunction,
- frontOperation: {
- fail: StencilOperation.KEEP,
- zFail: StencilOperation.KEEP,
- zPass: StencilOperation.INCREMENT_WRAP,
- },
- backFunction: stencilFunction,
- backOperation: {
- fail: StencilOperation.KEEP,
- zFail: StencilOperation.KEEP,
- zPass: StencilOperation.DECREMENT_WRAP,
+ zPass: StencilOperation.KEEP,
},
reference: StencilConstants.CESIUM_3D_TILE_MASK,
mask: StencilConstants.CESIUM_3D_TILE_MASK,
@@ -447,15 +409,15 @@ var colorRenderState = {
enabled: true,
frontFunction: StencilFunction.NOT_EQUAL,
frontOperation: {
- fail: StencilOperation.KEEP,
- zFail: StencilOperation.KEEP,
- zPass: StencilOperation.DECREMENT_WRAP,
+ fail: StencilOperation.ZERO,
+ zFail: StencilOperation.ZERO,
+ zPass: StencilOperation.ZERO,
},
backFunction: StencilFunction.NOT_EQUAL,
backOperation: {
- fail: StencilOperation.KEEP,
- zFail: StencilOperation.KEEP,
- zPass: StencilOperation.DECREMENT_WRAP,
+ fail: StencilOperation.ZERO,
+ zFail: StencilOperation.ZERO,
+ zPass: StencilOperation.ZERO,
},
reference: 0,
mask: StencilConstants.CLASSIFICATION_MASK,
@@ -473,15 +435,15 @@ var pickRenderState = {
enabled: true,
frontFunction: StencilFunction.NOT_EQUAL,
frontOperation: {
- fail: StencilOperation.KEEP,
- zFail: StencilOperation.KEEP,
- zPass: StencilOperation.DECREMENT_WRAP,
+ fail: StencilOperation.ZERO,
+ zFail: StencilOperation.ZERO,
+ zPass: StencilOperation.ZERO,
},
backFunction: StencilFunction.NOT_EQUAL,
backOperation: {
- fail: StencilOperation.KEEP,
- zFail: StencilOperation.KEEP,
- zPass: StencilOperation.DECREMENT_WRAP,
+ fail: StencilOperation.ZERO,
+ zFail: StencilOperation.ZERO,
+ zPass: StencilOperation.ZERO,
},
reference: 0,
mask: StencilConstants.CLASSIFICATION_MASK,
@@ -494,16 +456,10 @@ var pickRenderState = {
};
function createRenderStates(primitive) {
- if (defined(primitive._rsStencilPreloadPass)) {
+ if (defined(primitive._rsStencilDepthPass)) {
return;
}
- primitive._rsStencilPreloadPass = RenderState.fromCache(
- getStencilPreloadRenderState(false)
- );
- primitive._rsStencilPreloadPass3DTiles = RenderState.fromCache(
- getStencilPreloadRenderState(true)
- );
primitive._rsStencilDepthPass = RenderState.fromCache(
getStencilDepthRenderState(false)
);
@@ -807,7 +763,7 @@ function createColorCommands(primitive, context) {
var commands = primitive._commands;
var batchedIndices = primitive._batchedIndices;
var length = batchedIndices.length;
- var commandsLength = length * 3;
+ var commandsLength = length * 2;
if (
defined(commands) &&
@@ -829,36 +785,9 @@ function createColorCommands(primitive, context) {
var offset = batchedIndices[j].offset;
var count = batchedIndices[j].count;
- var stencilPreloadCommand = commands[j * 3];
- if (!defined(stencilPreloadCommand)) {
- stencilPreloadCommand = commands[j * 3] = new DrawCommand({
- owner: primitive,
- });
- }
-
- stencilPreloadCommand.vertexArray = vertexArray;
- stencilPreloadCommand.modelMatrix = modelMatrix;
- stencilPreloadCommand.offset = offset;
- stencilPreloadCommand.count = count;
- stencilPreloadCommand.renderState = primitive._rsStencilPreloadPass;
- stencilPreloadCommand.shaderProgram = sp;
- stencilPreloadCommand.uniformMap = uniformMap;
- stencilPreloadCommand.boundingVolume = bv;
- stencilPreloadCommand.cull = false;
- stencilPreloadCommand.pass = Pass.TERRAIN_CLASSIFICATION;
-
- var stencilPreloadDerivedCommand = DrawCommand.shallowClone(
- stencilPreloadCommand,
- stencilPreloadCommand.derivedCommands.tileset
- );
- stencilPreloadDerivedCommand.renderState =
- primitive._rsStencilPreloadPass3DTiles;
- stencilPreloadDerivedCommand.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION;
- stencilPreloadCommand.derivedCommands.tileset = stencilPreloadDerivedCommand;
-
- var stencilDepthCommand = commands[j * 3 + 1];
+ var stencilDepthCommand = commands[j * 2];
if (!defined(stencilDepthCommand)) {
- stencilDepthCommand = commands[j * 3 + 1] = new DrawCommand({
+ stencilDepthCommand = commands[j * 2] = new DrawCommand({
owner: primitive,
});
}
@@ -883,9 +812,9 @@ function createColorCommands(primitive, context) {
stencilDepthDerivedCommand.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION;
stencilDepthCommand.derivedCommands.tileset = stencilDepthDerivedCommand;
- var colorCommand = commands[j * 3 + 2];
+ var colorCommand = commands[j * 2 + 1];
if (!defined(colorCommand)) {
- colorCommand = commands[j * 3 + 2] = new DrawCommand({
+ colorCommand = commands[j * 2 + 1] = new DrawCommand({
owner: primitive,
});
}
@@ -926,10 +855,10 @@ function createColorCommandsIgnoreShow(primitive, frameState) {
var spStencil = primitive._spStencil;
var commandsLength = commands.length;
- var length = (commandsIgnoreShow.length = (commandsLength / 3) * 2);
+ var length = (commandsIgnoreShow.length = commandsLength / 2);
var commandIndex = 0;
- for (var j = 0; j < length; j += 2) {
+ for (var j = 0; j < length; ++j) {
var commandIgnoreShow = (commandsIgnoreShow[j] = DrawCommand.shallowClone(
commands[commandIndex],
commandsIgnoreShow[j]
@@ -937,14 +866,7 @@ function createColorCommandsIgnoreShow(primitive, frameState) {
commandIgnoreShow.shaderProgram = spStencil;
commandIgnoreShow.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW;
- commandIgnoreShow = commandsIgnoreShow[j + 1] = DrawCommand.shallowClone(
- commands[commandIndex + 1],
- commandsIgnoreShow[j + 1]
- );
- commandIgnoreShow.shaderProgram = spStencil;
- commandIgnoreShow.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW;
-
- commandIndex += 3;
+ commandIndex += 2;
}
primitive._commandsDirty = false;
@@ -957,7 +879,7 @@ function createPickCommands(primitive) {
var length = primitive._indexOffsets.length;
var pickCommands = primitive._pickCommands;
- pickCommands.length = length * 3;
+ pickCommands.length = length * 2;
var vertexArray = primitive._va;
var spStencil = primitive._spStencil;
@@ -972,36 +894,9 @@ function createPickCommands(primitive) {
? primitive._boundingVolumes[j]
: primitive.boundingVolume;
- var stencilPreloadCommand = pickCommands[j * 3];
- if (!defined(stencilPreloadCommand)) {
- stencilPreloadCommand = pickCommands[j * 3] = new DrawCommand({
- owner: primitive,
- pickOnly: true,
- });
- }
-
- stencilPreloadCommand.vertexArray = vertexArray;
- stencilPreloadCommand.modelMatrix = modelMatrix;
- stencilPreloadCommand.offset = offset;
- stencilPreloadCommand.count = count;
- stencilPreloadCommand.renderState = primitive._rsStencilPreloadPass;
- stencilPreloadCommand.shaderProgram = spStencil;
- stencilPreloadCommand.uniformMap = uniformMap;
- stencilPreloadCommand.boundingVolume = bv;
- stencilPreloadCommand.pass = Pass.TERRAIN_CLASSIFICATION;
-
- var stencilPreloadDerivedCommand = DrawCommand.shallowClone(
- stencilPreloadCommand,
- stencilPreloadCommand.derivedCommands.tileset
- );
- stencilPreloadDerivedCommand.renderState =
- primitive._rsStencilPreloadPass3DTiles;
- stencilPreloadDerivedCommand.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION;
- stencilPreloadCommand.derivedCommands.tileset = stencilPreloadDerivedCommand;
-
- var stencilDepthCommand = pickCommands[j * 3 + 1];
+ var stencilDepthCommand = pickCommands[j * 2];
if (!defined(stencilDepthCommand)) {
- stencilDepthCommand = pickCommands[j * 3 + 1] = new DrawCommand({
+ stencilDepthCommand = pickCommands[j * 2] = new DrawCommand({
owner: primitive,
pickOnly: true,
});
@@ -1026,9 +921,9 @@ function createPickCommands(primitive) {
stencilDepthDerivedCommand.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION;
stencilDepthCommand.derivedCommands.tileset = stencilDepthDerivedCommand;
- var colorCommand = pickCommands[j * 3 + 2];
+ var colorCommand = pickCommands[j * 2 + 1];
if (!defined(colorCommand)) {
- colorCommand = pickCommands[j * 3 + 2] = new DrawCommand({
+ colorCommand = pickCommands[j * 2 + 1] = new DrawCommand({
owner: primitive,
pickOnly: true,
});
@@ -1284,8 +1179,8 @@ function queueCommands(primitive, frameState, commands, commandsIgnoreShow) {
function queueWireframeCommands(frameState, commands) {
var commandList = frameState.commandList;
var commandLength = commands.length;
- for (var i = 0; i < commandLength; i += 3) {
- var command = commands[i + 2];
+ for (var i = 0; i < commandLength; i += 2) {
+ var command = commands[i + 1];
command.pass = Pass.OPAQUE;
commandList.push(command);
}
@@ -1316,8 +1211,8 @@ function updateWireframe(primitive) {
var commands = primitive._commands;
var commandLength = commands.length;
- for (var i = 0; i < commandLength; i += 3) {
- var command = commands[i + 2];
+ for (var i = 0; i < commandLength; i += 2) {
+ var command = commands[i + 1];
command.renderState = rs;
command.primitiveType = type;
}
diff --git a/Source/Scene/VerticalOrigin.js b/Source/Scene/VerticalOrigin.js
index a86ab56be337..dfd99dc56e5c 100644
--- a/Source/Scene/VerticalOrigin.js
+++ b/Source/Scene/VerticalOrigin.js
@@ -8,7 +8,7 @@
*
*
*
- * @exports VerticalOrigin
+ * @enum {Number}
*
* @see Billboard#verticalOrigin
* @see Label#verticalOrigin
diff --git a/Source/Scene/View.js b/Source/Scene/View.js
index 51992969641e..b0c89cda68d2 100644
--- a/Source/Scene/View.js
+++ b/Source/Scene/View.js
@@ -12,6 +12,7 @@ import PassState from "../Renderer/PassState.js";
import Camera from "./Camera.js";
import FrustumCommands from "./FrustumCommands.js";
import GlobeDepth from "./GlobeDepth.js";
+import GlobeTranslucencyFramebuffer from "./GlobeTranslucencyFramebuffer.js";
import OIT from "./OIT.js";
import PickDepthFramebuffer from "./PickDepthFramebuffer.js";
import PickFramebuffer from "./PickFramebuffer.js";
@@ -70,6 +71,7 @@ function View(scene, camera, viewport) {
this.pickDepthFramebuffer = new PickDepthFramebuffer();
this.sceneFramebuffer = new SceneFramebuffer();
this.globeDepth = globeDepth;
+ this.globeTranslucencyFramebuffer = new GlobeTranslucencyFramebuffer();
this.oit = oit;
this.pickDepths = [];
this.debugGlobeDepths = [];
@@ -423,6 +425,9 @@ View.prototype.destroy = function () {
this.sceneFramebuffer && this.sceneFramebuffer.destroy();
this.globeDepth = this.globeDepth && this.globeDepth.destroy();
this.oit = this.oit && this.oit.destroy();
+ this.globeTranslucencyFramebuffer =
+ this.globeTranslucencyFramebuffer &&
+ this.globeTranslucencyFramebuffer.destroy();
var i;
var length;
diff --git a/Source/Scene/WebMapServiceImageryProvider.js b/Source/Scene/WebMapServiceImageryProvider.js
index 8cc2b28dff20..c529269da2a5 100644
--- a/Source/Scene/WebMapServiceImageryProvider.js
+++ b/Source/Scene/WebMapServiceImageryProvider.js
@@ -9,44 +9,51 @@ import TimeDynamicImagery from "./TimeDynamicImagery.js";
import UrlTemplateImageryProvider from "./UrlTemplateImageryProvider.js";
/**
- * Provides tiled imagery hosted by a Web Map Service (WMS) server.
+ * @typedef {Object} WebMapServiceImageryProvider.ConstructorOptions
*
- * @alias WebMapServiceImageryProvider
- * @constructor
+ * Initialization options for the WebMapServiceImageryProvider constructor
*
- * @param {Object} options Object with the following properties:
- * @param {Resource|String} options.url The URL of the WMS service. The URL supports the same keywords as the {@link UrlTemplateImageryProvider}.
- * @param {String} options.layers The layers to include, separated by commas.
- * @param {Object} [options.parameters=WebMapServiceImageryProvider.DefaultParameters] Additional parameters to pass to the WMS server in the GetMap URL.
- * @param {Object} [options.getFeatureInfoParameters=WebMapServiceImageryProvider.GetFeatureInfoDefaultParameters] Additional parameters to pass to the WMS server in the GetFeatureInfo URL.
- * @param {Boolean} [options.enablePickFeatures=true] If true, {@link WebMapServiceImageryProvider#pickFeatures} will invoke
+ * @property {Resource|String} url The URL of the WMS service. The URL supports the same keywords as the {@link UrlTemplateImageryProvider}.
+ * @property {String} layers The layers to include, separated by commas.
+ * @property {Object} [parameters=WebMapServiceImageryProvider.DefaultParameters] Additional parameters to pass to the WMS server in the GetMap URL.
+ * @property {Object} [getFeatureInfoParameters=WebMapServiceImageryProvider.GetFeatureInfoDefaultParameters] Additional parameters to pass to the WMS server in the GetFeatureInfo URL.
+ * @property {Boolean} [enablePickFeatures=true] If true, {@link WebMapServiceImageryProvider#pickFeatures} will invoke
* the GetFeatureInfo operation on the WMS server and return the features included in the response. If false,
* {@link WebMapServiceImageryProvider#pickFeatures} will immediately return undefined (indicating no pickable features)
* without communicating with the server. Set this property to false if you know your WMS server does not support
* GetFeatureInfo or if you don't want this provider's features to be pickable. Note that this can be dynamically
* overridden by modifying the WebMapServiceImageryProvider#enablePickFeatures property.
- * @param {GetFeatureInfoFormat[]} [options.getFeatureInfoFormats=WebMapServiceImageryProvider.DefaultGetFeatureInfoFormats] The formats
+ * @property {GetFeatureInfoFormat[]} [getFeatureInfoFormats=WebMapServiceImageryProvider.DefaultGetFeatureInfoFormats] The formats
* in which to try WMS GetFeatureInfo requests.
- * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle of the layer.
- * @param {TilingScheme} [options.tilingScheme=new GeographicTilingScheme()] The tiling scheme to use to divide the world into tiles.
- * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If the tilingScheme is specified,
+ * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle of the layer.
+ * @property {TilingScheme} [tilingScheme=new GeographicTilingScheme()] The tiling scheme to use to divide the world into tiles.
+ * @property {Ellipsoid} [ellipsoid] The ellipsoid. If the tilingScheme is specified,
* this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither
* parameter is specified, the WGS84 ellipsoid is used.
- * @param {Number} [options.tileWidth=256] The width of each tile in pixels.
- * @param {Number} [options.tileHeight=256] The height of each tile in pixels.
- * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when
+ * @property {Number} [tileWidth=256] The width of each tile in pixels.
+ * @property {Number} [tileHeight=256] The height of each tile in pixels.
+ * @property {Number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider. Take care when
* specifying this that the number of tiles at the minimum level is small, such as four or less. A larger number is
* likely to result in rendering problems.
- * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
+ * @property {Number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
* If not specified, there is no limit.
- * @param {String} [options.crs] CRS specification, for use with WMS specification >= 1.3.0.
- * @param {String} [options.srs] SRS specification, for use with WMS specification 1.1.0 or 1.1.1
- * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas.
- * @param {String|String[]} [options.subdomains='abc'] The subdomains to use for the {s}
placeholder in the URL template.
+ * @property {String} [crs] CRS specification, for use with WMS specification >= 1.3.0.
+ * @property {String} [srs] SRS specification, for use with WMS specification 1.1.0 or 1.1.1
+ * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas.
+ * @property {String|String[]} [subdomains='abc'] The subdomains to use for the {s}
placeholder in the URL template.
* If this parameter is a single string, each character in the string is a subdomain. If it is
* an array, each element in the array is a subdomain.
- * @param {Clock} [options.clock] A Clock instance that is used when determining the value for the time dimension. Required when options.times is specified.
- * @param {TimeIntervalCollection} [options.times] TimeIntervalCollection with its data property being an object containing time dynamic dimension and their values.
+ * @property {Clock} [clock] A Clock instance that is used when determining the value for the time dimension. Required when `times` is specified.
+ * @property {TimeIntervalCollection} [times] TimeIntervalCollection with its data property being an object containing time dynamic dimension and their values.
+ */
+
+/**
+ * Provides tiled imagery hosted by a Web Map Service (WMS) server.
+ *
+ * @alias WebMapServiceImageryProvider
+ * @constructor
+ *
+ * @param {WebMapServiceImageryProvider.ConstructorOptions} options Object describing initialization options
*
* @see ArcGisMapServerImageryProvider
* @see BingMapsImageryProvider
@@ -87,6 +94,92 @@ function WebMapServiceImageryProvider(options) {
);
}
+ /**
+ * The default alpha blending value of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultNightAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultDayAlpha = undefined;
+
+ /**
+ * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
+ * makes the imagery darker while greater than 1.0 makes it brighter.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultBrightness = undefined;
+
+ /**
+ * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
+ * the contrast while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultContrast = undefined;
+
+ /**
+ * The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultHue = undefined;
+
+ /**
+ * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
+ * saturation while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultSaturation = undefined;
+
+ /**
+ * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultGamma = undefined;
+
+ /**
+ * The default texture minification filter to apply to this provider.
+ *
+ * @type {TextureMinificationFilter}
+ * @default undefined
+ */
+ this.defaultMinificationFilter = undefined;
+
+ /**
+ * The default texture magnification filter to apply to this provider.
+ *
+ * @type {TextureMagnificationFilter}
+ * @default undefined
+ */
+ this.defaultMagnificationFilter = undefined;
+
var resource = Resource.createIfNeeded(options.url);
var pickFeatureResource = resource.clone();
@@ -293,7 +386,7 @@ Object.defineProperties(WebMapServiceImageryProvider.prototype, {
* Gets the maximum level-of-detail that can be requested. This function should
* not be called before {@link WebMapServiceImageryProvider#ready} returns true.
* @memberof WebMapServiceImageryProvider.prototype
- * @type {Number}
+ * @type {Number|undefined}
* @readonly
*/
maximumLevel: {
@@ -494,7 +587,7 @@ WebMapServiceImageryProvider.prototype.getTileCredits = function (x, y, level) {
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level.
* @param {Request} [request] The request object. Intended for internal use only.
- * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
+ * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if there are too many active requests to the server, and the request
* should be retried later. The resolved image may be either an
* Image or a Canvas DOM object.
diff --git a/Source/Scene/WebMapTileServiceImageryProvider.js b/Source/Scene/WebMapTileServiceImageryProvider.js
index 54e66417b684..2b3c14755ca6 100644
--- a/Source/Scene/WebMapTileServiceImageryProvider.js
+++ b/Source/Scene/WebMapTileServiceImageryProvider.js
@@ -17,6 +17,33 @@ var defaultParameters = Object.freeze({
request: "GetTile",
});
+/**
+ * @typedef {Object} WebMapTileServiceImageryProvider.ConstructorOptions
+ *
+ * Initialization options for the WebMapTileServiceImageryProvider constructor
+ *
+ * @property {Resource|String} url The base URL for the WMTS GetTile operation (for KVP-encoded requests) or the tile-URL template (for RESTful requests). The tile-URL template should contain the following variables: {style}, {TileMatrixSet}, {TileMatrix}, {TileRow}, {TileCol}. The first two are optional if actual values are hardcoded or not required by the server. The {s} keyword may be used to specify subdomains.
+ * @property {String} [format='image/jpeg'] The MIME type for images to retrieve from the server.
+ * @property {String} layer The layer name for WMTS requests.
+ * @property {String} style The style name for WMTS requests.
+ * @property {String} tileMatrixSetID The identifier of the TileMatrixSet to use for WMTS requests.
+ * @property {Array} [tileMatrixLabels] A list of identifiers in the TileMatrix to use for WMTS requests, one per TileMatrix level.
+ * @property {Clock} [clock] A Clock instance that is used when determining the value for the time dimension. Required when `times` is specified.
+ * @property {TimeIntervalCollection} [times] TimeIntervalCollection with its data
property being an object containing time dynamic dimension and their values.
+ * @property {Object} [dimensions] A object containing static dimensions and their values.
+ * @property {Number} [tileWidth=256] The tile width in pixels.
+ * @property {Number} [tileHeight=256] The tile height in pixels.
+ * @property {TilingScheme} [tilingScheme] The tiling scheme corresponding to the organization of the tiles in the TileMatrixSet.
+ * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle covered by the layer.
+ * @property {Number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider.
+ * @property {Number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
+ * @property {Ellipsoid} [ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
+ * @property {Credit|String} [credit] A credit for the data source, which is displayed on the canvas.
+ * @property {String|String[]} [subdomains='abc'] The subdomains to use for the {s}
placeholder in the URL template.
+ * If this parameter is a single string, each character in the string is a subdomain. If it is
+ * an array, each element in the array is a subdomain.
+ */
+
/**
* Provides tiled imagery served by {@link http://www.opengeospatial.org/standards/wmts|WMTS 1.0.0} compliant servers.
* This provider supports HTTP KVP-encoded and RESTful GetTile requests, but does not yet support the SOAP encoding.
@@ -24,27 +51,7 @@ var defaultParameters = Object.freeze({
* @alias WebMapTileServiceImageryProvider
* @constructor
*
- * @param {Object} options Object with the following properties:
- * @param {Resource|String} options.url The base URL for the WMTS GetTile operation (for KVP-encoded requests) or the tile-URL template (for RESTful requests). The tile-URL template should contain the following variables: {style}, {TileMatrixSet}, {TileMatrix}, {TileRow}, {TileCol}. The first two are optional if actual values are hardcoded or not required by the server. The {s} keyword may be used to specify subdomains.
- * @param {String} [options.format='image/jpeg'] The MIME type for images to retrieve from the server.
- * @param {String} options.layer The layer name for WMTS requests.
- * @param {String} options.style The style name for WMTS requests.
- * @param {String} options.tileMatrixSetID The identifier of the TileMatrixSet to use for WMTS requests.
- * @param {Array} [options.tileMatrixLabels] A list of identifiers in the TileMatrix to use for WMTS requests, one per TileMatrix level.
- * @param {Clock} [options.clock] A Clock instance that is used when determining the value for the time dimension. Required when options.times is specified.
- * @param {TimeIntervalCollection} [options.times] TimeIntervalCollection with its data
property being an object containing time dynamic dimension and their values.
- * @param {Object} [options.dimensions] A object containing static dimensions and their values.
- * @param {Number} [options.tileWidth=256] The tile width in pixels.
- * @param {Number} [options.tileHeight=256] The tile height in pixels.
- * @param {TilingScheme} [options.tilingScheme] The tiling scheme corresponding to the organization of the tiles in the TileMatrixSet.
- * @param {Rectangle} [options.rectangle=Rectangle.MAX_VALUE] The rectangle covered by the layer.
- * @param {Number} [options.minimumLevel=0] The minimum level-of-detail supported by the imagery provider.
- * @param {Number} [options.maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
- * @param {Ellipsoid} [options.ellipsoid] The ellipsoid. If not specified, the WGS84 ellipsoid is used.
- * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas.
- * @param {String|String[]} [options.subdomains='abc'] The subdomains to use for the {s}
placeholder in the URL template.
- * If this parameter is a single string, each character in the string is a subdomain. If it is
- * an array, each element in the array is a subdomain.
+ * @param {WebMapTileServiceImageryProvider.ConstructorOptions} options Object describing initialization options
*
* @demo {@link https://sandcastle.cesium.com/index.html?src=Web%20Map%20Tile%20Service%20with%20Time.html|Cesium Sandcastle Web Map Tile Service with Time Demo}
*
@@ -130,6 +137,92 @@ function WebMapTileServiceImageryProvider(options) {
}
//>>includeEnd('debug');
+ /**
+ * The default alpha blending value of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultNightAlpha = undefined;
+
+ /**
+ * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
+ * 1.0 representing fully opaque.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultDayAlpha = undefined;
+
+ /**
+ * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
+ * makes the imagery darker while greater than 1.0 makes it brighter.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultBrightness = undefined;
+
+ /**
+ * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
+ * the contrast while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultContrast = undefined;
+
+ /**
+ * The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultHue = undefined;
+
+ /**
+ * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
+ * saturation while greater than 1.0 increases it.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultSaturation = undefined;
+
+ /**
+ * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
+ *
+ * @type {Number|undefined}
+ * @default undefined
+ */
+ this.defaultGamma = undefined;
+
+ /**
+ * The default texture minification filter to apply to this provider.
+ *
+ * @type {TextureMinificationFilter}
+ * @default undefined
+ */
+ this.defaultMinificationFilter = undefined;
+
+ /**
+ * The default texture magnification filter to apply to this provider.
+ *
+ * @type {TextureMagnificationFilter}
+ * @default undefined
+ */
+ this.defaultMagnificationFilter = undefined;
+
var resource = Resource.createIfNeeded(options.url);
var style = options.style;
@@ -339,7 +432,7 @@ Object.defineProperties(WebMapTileServiceImageryProvider.prototype, {
* Gets the maximum level-of-detail that can be requested. This function should
* not be called before {@link WebMapTileServiceImageryProvider#ready} returns true.
* @memberof WebMapTileServiceImageryProvider.prototype
- * @type {Number}
+ * @type {Number|undefined}
* @readonly
*/
maximumLevel: {
@@ -552,7 +645,7 @@ WebMapTileServiceImageryProvider.prototype.getTileCredits = function (
* @param {Number} y The tile Y coordinate.
* @param {Number} level The tile level.
* @param {Request} [request] The request object. Intended for internal use only.
- * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
+ * @returns {Promise.|undefined} A promise for the image that will resolve when the image is available, or
* undefined if there are too many active requests to the server, and the request
* should be retried later. The resolved image may be either an
* Image or a Canvas DOM object.
diff --git a/Source/Scene/createBillboardPointCallback.js b/Source/Scene/createBillboardPointCallback.js
index 24453e9af971..65718192d807 100644
--- a/Source/Scene/createBillboardPointCallback.js
+++ b/Source/Scene/createBillboardPointCallback.js
@@ -1,12 +1,12 @@
/**
- * Creates a {@link createBillboardPointCallback~CanvasFunction} that will create a canvas with a point.
+ * Creates a {@link createBillboardPointCallback.CanvasFunction} that will create a canvas with a point.
*
* @param {Number} centerAlpha The alpha of the center of the point. The value must be in the range [0.0, 1.0].
* @param {String} cssColor The CSS color string.
* @param {String} cssOutlineColor The CSS color of the point outline.
* @param {Number} cssOutlineWidth The width of the outline in pixels.
* @param {Number} pixelSize The size of the point in pixels.
- * @return {createBillboardPointCallback~CanvasFunction} The function that will return a canvas with the point drawn on it.
+ * @return {createBillboardPointCallback.CanvasFunction} The function that will return a canvas with the point drawn on it.
*
* @private
*/
@@ -64,7 +64,7 @@ function createBillboardPointCallback(
/**
* A function that returns a canvas containing an image of a point.
- * @callback createBillboardPointCallback~CanvasFunction
+ * @callback createBillboardPointCallback.CanvasFunction
* @returns {HTMLCanvasElement} The result of the calculation.
*/
export default createBillboardPointCallback;
diff --git a/Source/Scene/createOsmBuildings.js b/Source/Scene/createOsmBuildings.js
index a692281fae11..d515ac6a4dd3 100644
--- a/Source/Scene/createOsmBuildings.js
+++ b/Source/Scene/createOsmBuildings.js
@@ -8,19 +8,19 @@ import Cesium3DTileStyle from "./Cesium3DTileStyle.js";
/**
* Creates a {@link Cesium3DTileset} instance for the
- * {@link https://cesium.com/content/#cesium-osm-buildings|Cesium OSM Buildings}
+ * {@link https://cesium.com/content/cesium-osm-buildings/|Cesium OSM Buildings}
* tileset.
*
- * @exports createOsmBuildings
+ * @function
*
* @param {Object} [options] Construction options. Any options allowed by the {@link Cesium3DTileset} constructor
* may be specified here. In addition to those, the following properties are supported:
* @param {Color} [options.defaultColor=Color.WHITE] The default color to use for buildings
- * that do not have a color. This parameter is ignored if `options.style` is specified.
+ * that do not have a color. This parameter is ignored if options.style
is specified.
* @param {Cesium3DTileStyle} [options.style] The style to use with the tileset. If not
* specified, a default style is used which gives each building or building part a
- * color inferred from its OpenStreetMap `tags`. If no color can be inferred,
- * `options.defaultColor` is used.
+ * color inferred from its OpenStreetMap tags
. If no color can be inferred,
+ * options.defaultColor
is used.
* @returns {Cesium3DTileset}
*
* @see Ion
diff --git a/Source/Scene/createTangentSpaceDebugPrimitive.js b/Source/Scene/createTangentSpaceDebugPrimitive.js
index fe809e7c1163..78f6436322f8 100644
--- a/Source/Scene/createTangentSpaceDebugPrimitive.js
+++ b/Source/Scene/createTangentSpaceDebugPrimitive.js
@@ -14,7 +14,7 @@ import Primitive from "./Primitive.js";
* is red; tangent is green; and bitangent is blue. If an attribute is not
* present, it is not drawn.
*
- * @exports createTangentSpaceDebugPrimitive
+ * @function
*
* @param {Object} options Object with the following properties:
* @param {Geometry} options.geometry The Geometry
instance with the attribute.
diff --git a/Source/Scene/createWorldImagery.js b/Source/Scene/createWorldImagery.js
index bb00d364a3be..460d4c7ffeaa 100644
--- a/Source/Scene/createWorldImagery.js
+++ b/Source/Scene/createWorldImagery.js
@@ -5,7 +5,7 @@ import IonWorldImageryStyle from "./IonWorldImageryStyle.js";
/**
* Creates an {@link IonImageryProvider} instance for ion's default global base imagery layer, currently Bing Maps.
*
- * @exports createWorldImagery
+ * @function
*
* @param {Object} [options] Object with the following properties:
* @param {IonWorldImageryStyle} [options.style=IonWorldImageryStyle] The style of base imagery, only AERIAL, AERIAL_WITH_LABELS, and ROAD are currently supported.
diff --git a/Source/Scene/processModelMaterialsCommon.js b/Source/Scene/processModelMaterialsCommon.js
index 03832771b990..5ce0bf0f226a 100644
--- a/Source/Scene/processModelMaterialsCommon.js
+++ b/Source/Scene/processModelMaterialsCommon.js
@@ -5,7 +5,6 @@ import webGLConstantToGlslType from "../Core/webGLConstantToGlslType.js";
import addToArray from "../ThirdParty/GltfPipeline/addToArray.js";
import ForEach from "../ThirdParty/GltfPipeline/ForEach.js";
import hasExtension from "../ThirdParty/GltfPipeline/hasExtension.js";
-import numberOfComponentsForType from "../ThirdParty/GltfPipeline/numberOfComponentsForType.js";
import ModelUtility from "./ModelUtility.js";
/**
@@ -389,44 +388,12 @@ function generateTechnique(
// Add attributes with semantics
var vertexShaderMain = "";
if (hasSkinning) {
- var i, j;
- var numberOfComponents = numberOfComponentsForType(skinningInfo.type);
- var matrix = false;
- if (skinningInfo.type.indexOf("MAT") === 0) {
- matrix = true;
- numberOfComponents = Math.sqrt(numberOfComponents);
- }
- if (!matrix) {
- for (i = 0; i < numberOfComponents; i++) {
- if (i === 0) {
- vertexShaderMain += " mat4 skinMat = ";
- } else {
- vertexShaderMain += " skinMat += ";
- }
- vertexShaderMain +=
- "a_weight[" + i + "] * u_jointMatrix[int(a_joint[" + i + "])];\n";
- }
- } else {
- for (i = 0; i < numberOfComponents; i++) {
- for (j = 0; j < numberOfComponents; j++) {
- if (i === 0 && j === 0) {
- vertexShaderMain += " mat4 skinMat = ";
- } else {
- vertexShaderMain += " skinMat += ";
- }
- vertexShaderMain +=
- "a_weight[" +
- i +
- "][" +
- j +
- "] * u_jointMatrix[int(a_joint[" +
- i +
- "][" +
- j +
- "])];\n";
- }
- }
- }
+ vertexShaderMain +=
+ " mat4 skinMatrix =\n" +
+ " a_weight.x * u_jointMatrix[int(a_joint.x)] +\n" +
+ " a_weight.y * u_jointMatrix[int(a_joint.y)] +\n" +
+ " a_weight.z * u_jointMatrix[int(a_joint.z)] +\n" +
+ " a_weight.w * u_jointMatrix[int(a_joint.w)];\n";
}
// Add position always
@@ -439,7 +406,7 @@ function generateTechnique(
vertexShader += "varying vec3 v_positionEC;\n";
if (hasSkinning) {
vertexShaderMain +=
- " vec4 pos = u_modelViewMatrix * skinMat * vec4(a_position,1.0);\n";
+ " vec4 pos = u_modelViewMatrix * skinMatrix * vec4(a_position,1.0);\n";
} else {
vertexShaderMain +=
" vec4 pos = u_modelViewMatrix * vec4(a_position,1.0);\n";
@@ -457,7 +424,7 @@ function generateTechnique(
vertexShader += "varying vec3 v_normal;\n";
if (hasSkinning) {
vertexShaderMain +=
- " v_normal = u_normalMatrix * mat3(skinMat) * a_normal;\n";
+ " v_normal = u_normalMatrix * mat3(skinMatrix) * a_normal;\n";
} else {
vertexShaderMain += " v_normal = u_normalMatrix * a_normal;\n";
}
@@ -481,16 +448,15 @@ function generateTechnique(
}
if (hasSkinning) {
- var attributeType = ModelUtility.getShaderVariable(skinningInfo.type);
techniqueAttributes.a_joint = {
- semantic: "JOINT",
+ semantic: "JOINTS_0",
};
techniqueAttributes.a_weight = {
- semantic: "WEIGHT",
+ semantic: "WEIGHTS_0",
};
- vertexShader += "attribute " + attributeType + " a_joint;\n";
- vertexShader += "attribute " + attributeType + " a_weight;\n";
+ vertexShader += "attribute vec4 a_joint;\n";
+ vertexShader += "attribute vec4 a_weight;\n";
}
if (hasVertexColors) {
@@ -676,8 +642,7 @@ function generateTechnique(
if (hasNormals) {
fragmentShader += " vec3 normal = normalize(v_normal);\n";
if (khrMaterialsCommon.doubleSided) {
- // !gl_FrontFacing doesn't work as expected on Mac/Intel so use the more verbose form instead. See https://github.com/CesiumGS/cesium/pull/8494.
- fragmentShader += " if (gl_FrontFacing == false)\n";
+ fragmentShader += " if (czm_backFacing())\n";
fragmentShader += " {\n";
fragmentShader += " normal = -normal;\n";
fragmentShader += " }\n";
diff --git a/Source/Scene/processPbrMaterials.js b/Source/Scene/processPbrMaterials.js
index b38298c42d59..163ee5731a55 100644
--- a/Source/Scene/processPbrMaterials.js
+++ b/Source/Scene/processPbrMaterials.js
@@ -5,7 +5,6 @@ import webGLConstantToGlslType from "../Core/webGLConstantToGlslType.js";
import addToArray from "../ThirdParty/GltfPipeline/addToArray.js";
import ForEach from "../ThirdParty/GltfPipeline/ForEach.js";
import hasExtension from "../ThirdParty/GltfPipeline/hasExtension.js";
-import numberOfComponentsForType from "../ThirdParty/GltfPipeline/numberOfComponentsForType.js";
import ModelUtility from "./ModelUtility.js";
/**
@@ -374,44 +373,12 @@ function generateTechnique(
// Add attributes with semantics
var vertexShaderMain = "";
if (hasSkinning) {
- var i, j;
- var numberOfComponents = numberOfComponentsForType(skinningInfo.type);
- var matrix = false;
- if (skinningInfo.type.indexOf("MAT") === 0) {
- matrix = true;
- numberOfComponents = Math.sqrt(numberOfComponents);
- }
- if (!matrix) {
- for (i = 0; i < numberOfComponents; i++) {
- if (i === 0) {
- vertexShaderMain += " mat4 skinMatrix = ";
- } else {
- vertexShaderMain += " skinMatrix += ";
- }
- vertexShaderMain +=
- "a_weight[" + i + "] * u_jointMatrix[int(a_joint[" + i + "])];\n";
- }
- } else {
- for (i = 0; i < numberOfComponents; i++) {
- for (j = 0; j < numberOfComponents; j++) {
- if (i === 0 && j === 0) {
- vertexShaderMain += " mat4 skinMatrix = ";
- } else {
- vertexShaderMain += " skinMatrix += ";
- }
- vertexShaderMain +=
- "a_weight[" +
- i +
- "][" +
- j +
- "] * u_jointMatrix[int(a_joint[" +
- i +
- "][" +
- j +
- "])];\n";
- }
- }
- }
+ vertexShaderMain +=
+ " mat4 skinMatrix =\n" +
+ " a_weight.x * u_jointMatrix[int(a_joint.x)] +\n" +
+ " a_weight.y * u_jointMatrix[int(a_joint.y)] +\n" +
+ " a_weight.z * u_jointMatrix[int(a_joint.z)] +\n" +
+ " a_weight.w * u_jointMatrix[int(a_joint.w)];\n";
}
// Add position always
@@ -619,7 +586,6 @@ function generateTechnique(
// Add skinning information if available
if (hasSkinning) {
- var attributeType = ModelUtility.getShaderVariable(skinningInfo.type);
techniqueAttributes.a_joint = {
semantic: "JOINTS_0",
};
@@ -627,8 +593,8 @@ function generateTechnique(
semantic: "WEIGHTS_0",
};
- vertexShader += "attribute " + attributeType + " a_joint;\n";
- vertexShader += "attribute " + attributeType + " a_weight;\n";
+ vertexShader += "attribute vec4 a_joint;\n";
+ vertexShader += "attribute vec4 a_weight;\n";
}
if (hasVertexColors) {
@@ -801,8 +767,7 @@ function generateTechnique(
fragmentShader += " vec3 n = ng;\n";
}
if (material.doubleSided) {
- // !gl_FrontFacing doesn't work as expected on Mac/Intel so use the more verbose form instead. See https://github.com/CesiumGS/cesium/pull/8494.
- fragmentShader += " if (gl_FrontFacing == false)\n";
+ fragmentShader += " if (czm_backFacing())\n";
fragmentShader += " {\n";
fragmentShader += " n = -n;\n";
fragmentShader += " }\n";
diff --git a/Source/Shaders/Builtin/Functions/backFacing.glsl b/Source/Shaders/Builtin/Functions/backFacing.glsl
new file mode 100644
index 000000000000..701244a81546
--- /dev/null
+++ b/Source/Shaders/Builtin/Functions/backFacing.glsl
@@ -0,0 +1,13 @@
+/**
+ * Determines if the fragment is back facing
+ *
+ * @name czm_backFacing
+ * @glslFunction
+ *
+ * @returns {bool} true
if the fragment is back facing; otherwise, false
.
+ */
+bool czm_backFacing()
+{
+ // !gl_FrontFacing doesn't work as expected on Mac/Intel so use the more verbose form instead. See https://github.com/CesiumGS/cesium/pull/8494.
+ return gl_FrontFacing == false;
+}
diff --git a/Source/Shaders/Builtin/Functions/depthClamp.glsl b/Source/Shaders/Builtin/Functions/depthClamp.glsl
new file mode 100644
index 000000000000..f83356a1b56d
--- /dev/null
+++ b/Source/Shaders/Builtin/Functions/depthClamp.glsl
@@ -0,0 +1,27 @@
+// emulated noperspective
+#ifndef LOG_DEPTH
+varying float v_WindowZ;
+#endif
+
+/**
+ * Clamps a vertex to the near and far planes.
+ *
+ * @name czm_depthClamp
+ * @glslFunction
+ *
+ * @param {vec4} coords The vertex in clip coordinates.
+ * @returns {vec4} The vertex clipped to the near and far planes.
+ *
+ * @example
+ * gl_Position = czm_depthClamp(czm_modelViewProjection * vec4(position, 1.0));
+ *
+ * @see czm_writeDepthClamp
+ */
+vec4 czm_depthClamp(vec4 coords)
+{
+#ifndef LOG_DEPTH
+ v_WindowZ = (0.5 * (coords.z / coords.w) + 0.5) * coords.w;
+ coords.z = clamp(coords.z, -coords.w, +coords.w);
+#endif
+ return coords;
+}
diff --git a/Source/Shaders/Builtin/Functions/depthClampFarPlane.glsl b/Source/Shaders/Builtin/Functions/depthClampFarPlane.glsl
deleted file mode 100644
index bec295024033..000000000000
--- a/Source/Shaders/Builtin/Functions/depthClampFarPlane.glsl
+++ /dev/null
@@ -1,27 +0,0 @@
-// emulated noperspective
-#ifndef LOG_DEPTH
-varying float v_WindowZ;
-#endif
-
-/**
- * Clamps a vertex to the far plane.
- *
- * @name czm_depthClampFarPlane
- * @glslFunction
- *
- * @param {vec4} coords The vertex in clip coordinates.
- * @returns {vec4} The vertex clipped to the far plane.
- *
- * @example
- * gl_Position = czm_depthClampFarPlane(czm_modelViewProjection * vec4(position, 1.0));
- *
- * @see czm_writeDepthClampedToFarPlane
- */
-vec4 czm_depthClampFarPlane(vec4 coords)
-{
-#ifndef LOG_DEPTH
- v_WindowZ = (0.5 * (coords.z / coords.w) + 0.5) * coords.w;
- coords.z = min(coords.z, coords.w);
-#endif
- return coords;
-}
diff --git a/Source/Shaders/Builtin/Functions/writeDepthClampedToFarPlane.glsl b/Source/Shaders/Builtin/Functions/writeDepthClamp.glsl
similarity index 62%
rename from Source/Shaders/Builtin/Functions/writeDepthClampedToFarPlane.glsl
rename to Source/Shaders/Builtin/Functions/writeDepthClamp.glsl
index bf8cf3209b45..9006fe0a1c99 100644
--- a/Source/Shaders/Builtin/Functions/writeDepthClampedToFarPlane.glsl
+++ b/Source/Shaders/Builtin/Functions/writeDepthClamp.glsl
@@ -8,18 +8,18 @@ varying float v_WindowZ;
* The shader must enable the GL_EXT_frag_depth extension.
*
*
- * @name czm_writeDepthClampedToFarPlane
+ * @name czm_writeDepthClamp
* @glslFunction
*
* @example
* gl_FragColor = color;
- * czm_writeDepthClampedToFarPlane();
+ * czm_writeDepthClamp();
*
- * @see czm_depthClampFarPlane
+ * @see czm_depthClamp
*/
-void czm_writeDepthClampedToFarPlane()
+void czm_writeDepthClamp()
{
#if defined(GL_EXT_frag_depth) && !defined(LOG_DEPTH)
- gl_FragDepthEXT = min(v_WindowZ * gl_FragCoord.w, 1.0);
+ gl_FragDepthEXT = clamp(v_WindowZ * gl_FragCoord.w, 0.0, 1.0);
#endif
}
diff --git a/Source/Shaders/DepthPlaneFS.glsl b/Source/Shaders/DepthPlaneFS.glsl
index 10c3ca2a0722..c6a9602ca1eb 100644
--- a/Source/Shaders/DepthPlaneFS.glsl
+++ b/Source/Shaders/DepthPlaneFS.glsl
@@ -2,8 +2,23 @@ varying vec4 positionEC;
void main()
{
- vec3 direction = normalize(positionEC.xyz);
- czm_ray ray = czm_ray(vec3(0.0), direction);
+ vec3 position;
+ vec3 direction;
+ if (czm_orthographicIn3D == 1.0)
+ {
+ vec2 uv = (gl_FragCoord.xy - czm_viewport.xy) / czm_viewport.zw;
+ vec2 minPlane = vec2(czm_frustumPlanes.z, czm_frustumPlanes.y); // left, bottom
+ vec2 maxPlane = vec2(czm_frustumPlanes.w, czm_frustumPlanes.x); // right, top
+ position = vec3(mix(minPlane, maxPlane, uv), 0.0);
+ direction = vec3(0.0, 0.0, -1.0);
+ }
+ else
+ {
+ position = vec3(0.0);
+ direction = normalize(positionEC.xyz);
+ }
+
+ czm_ray ray = czm_ray(position, direction);
vec3 ellipsoid_center = czm_view[3].xyz;
diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl
index 2485ade22955..10a5c29fc3f4 100644
--- a/Source/Shaders/GlobeFS.glsl
+++ b/Source/Shaders/GlobeFS.glsl
@@ -9,6 +9,11 @@ uniform bool u_dayTextureUseWebMercatorT[TEXTURE_UNITS];
uniform float u_dayTextureAlpha[TEXTURE_UNITS];
#endif
+#ifdef APPLY_DAY_NIGHT_ALPHA
+uniform float u_dayTextureNightAlpha[TEXTURE_UNITS];
+uniform float u_dayTextureDayAlpha[TEXTURE_UNITS];
+#endif
+
#ifdef APPLY_SPLIT
uniform float u_dayTextureSplit[TEXTURE_UNITS];
#endif
@@ -84,6 +89,17 @@ uniform vec3 u_hsbShift; // Hue, saturation, brightness
uniform vec4 u_fillHighlightColor;
#endif
+#ifdef TRANSLUCENT
+uniform vec4 u_frontFaceAlphaByDistance;
+uniform vec4 u_backFaceAlphaByDistance;
+uniform vec4 u_translucencyRectangle;
+#endif
+
+#ifdef UNDERGROUND_COLOR
+uniform vec4 u_undergroundColor;
+uniform vec4 u_undergroundColorAlphaByDistance;
+#endif
+
varying vec3 v_positionMC;
varying vec3 v_positionEC;
varying vec3 v_textureCoordinates;
@@ -96,8 +112,11 @@ varying float v_slope;
varying float v_aspect;
#endif
-#if defined(FOG) || defined(GROUND_ATMOSPHERE)
+#if defined(FOG) || defined(GROUND_ATMOSPHERE) || defined(UNDERGROUND_COLOR) || defined(TRANSLUCENT)
varying float v_distance;
+#endif
+
+#if defined(FOG) || defined(GROUND_ATMOSPHERE)
varying vec3 v_fogRayleighColor;
varying vec3 v_fogMieColor;
#endif
@@ -107,6 +126,36 @@ varying vec3 v_rayleighColor;
varying vec3 v_mieColor;
#endif
+#if defined(UNDERGROUND_COLOR) || defined(TRANSLUCENT)
+float interpolateByDistance(vec4 nearFarScalar, float distance)
+{
+ float startDistance = nearFarScalar.x;
+ float startValue = nearFarScalar.y;
+ float endDistance = nearFarScalar.z;
+ float endValue = nearFarScalar.w;
+ float t = clamp((distance - startDistance) / (endDistance - startDistance), 0.0, 1.0);
+ return mix(startValue, endValue, t);
+}
+#endif
+
+#if defined(UNDERGROUND_COLOR) || defined(TRANSLUCENT) || defined(APPLY_MATERIAL)
+vec4 alphaBlend(vec4 sourceColor, vec4 destinationColor)
+{
+ return sourceColor * vec4(sourceColor.aaa, 1.0) + destinationColor * (1.0 - sourceColor.a);
+}
+#endif
+
+#ifdef TRANSLUCENT
+bool inTranslucencyRectangle()
+{
+ return
+ v_textureCoordinates.x > u_translucencyRectangle.x &&
+ v_textureCoordinates.x < u_translucencyRectangle.z &&
+ v_textureCoordinates.y > u_translucencyRectangle.y &&
+ v_textureCoordinates.y < u_translucencyRectangle.w;
+}
+#endif
+
vec4 sampleAndBlend(
vec4 previousColor,
sampler2D textureToSample,
@@ -114,13 +163,16 @@ vec4 sampleAndBlend(
vec4 textureCoordinateRectangle,
vec4 textureCoordinateTranslationAndScale,
float textureAlpha,
+ float textureNightAlpha,
+ float textureDayAlpha,
float textureBrightness,
float textureContrast,
float textureHue,
float textureSaturation,
float textureOneOverGamma,
float split,
- vec4 colorToAlpha)
+ vec4 colorToAlpha,
+ float nightBlend)
{
// This crazy step stuff sets the alpha to 0.0 if this following condition is true:
// tileTextureCoordinates.s < textureCoordinateRectangle.s ||
@@ -135,6 +187,10 @@ vec4 sampleAndBlend(
alphaMultiplier = step(vec2(0.0), textureCoordinateRectangle.pq - tileTextureCoordinates);
textureAlpha = textureAlpha * alphaMultiplier.x * alphaMultiplier.y;
+#if defined(APPLY_DAY_NIGHT_ALPHA) && defined(ENABLE_DAYNIGHT_SHADING)
+ textureAlpha *= mix(textureDayAlpha, textureNightAlpha, nightBlend);
+#endif
+
vec2 translation = textureCoordinateTranslationAndScale.xy;
vec2 scale = textureCoordinateTranslationAndScale.zw;
vec2 textureCoordinates = tileTextureCoordinates * scale + translation;
@@ -225,9 +281,15 @@ vec3 colorCorrect(vec3 rgb) {
return rgb;
}
-vec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates);
+vec4 computeDayColor(vec4 initialColor, vec3 textureCoordinates, float nightBlend);
vec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat3 enuToEye, vec4 imageryColor, float specularMapValue, float fade);
+#ifdef GROUND_ATMOSPHERE
+vec3 computeGroundAtmosphereColor(vec3 fogColor, vec4 finalColor, vec3 atmosphereLightDirection, float cameraDist);
+#endif
+
+const float fExposure = 2.0;
+
void main()
{
#ifdef TILE_LIMIT_RECTANGLE
@@ -242,11 +304,22 @@ void main()
float clipDistance = clip(gl_FragCoord, u_clippingPlanes, u_clippingPlanesMatrix);
#endif
+#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) || defined(HDR)
+ vec3 normalMC = czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)); // normalized surface normal in model coordinates
+ vec3 normalEC = czm_normal3D * normalMC; // normalized surface normal in eye coordiantes
+#endif
+
+#if defined(APPLY_DAY_NIGHT_ALPHA) && defined(ENABLE_DAYNIGHT_SHADING)
+ float nightBlend = 1.0 - clamp(czm_getLambertDiffuse(czm_lightDirectionEC, normalEC) * 5.0, 0.0, 1.0);
+#else
+ float nightBlend = 0.0;
+#endif
+
// The clamp below works around an apparent bug in Chrome Canary v23.0.1241.0
// where the fragment shader sees textures coordinates < 0.0 and > 1.0 for the
// fragments on the edges of tiles even though the vertex shader is outputting
// coordinates strictly in the 0-1 range.
- vec4 color = computeDayColor(u_initialColor, clamp(v_textureCoordinates, 0.0, 1.0));
+ vec4 color = computeDayColor(u_initialColor, clamp(v_textureCoordinates, 0.0, 1.0), nightBlend);
#ifdef SHOW_TILE_BOUNDARIES
if (v_textureCoordinates.x < (1.0/256.0) || v_textureCoordinates.x > (255.0/256.0) ||
@@ -256,11 +329,6 @@ void main()
}
#endif
-#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) || defined(HDR)
- vec3 normalMC = czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)); // normalized surface normal in model coordinates
- vec3 normalEC = czm_normal3D * normalMC; // normalized surface normal in eye coordiantes
-#endif
-
#if defined(ENABLE_DAYNIGHT_SHADING) || defined(GROUND_ATMOSPHERE)
float cameraDist;
if (czm_sceneMode == czm_sceneMode2D)
@@ -317,7 +385,8 @@ void main()
materialInput.height = v_height;
materialInput.aspect = v_aspect;
czm_material material = czm_getMaterial(materialInput);
- color.xyz = mix(color.xyz, material.diffuse, material.alpha);
+ vec4 materialColor = vec4(material.diffuse, material.alpha);
+ color = alphaBlend(materialColor, color);
#endif
#ifdef ENABLE_VERTEX_LIGHTING
@@ -349,7 +418,6 @@ void main()
#if defined(FOG) || defined(GROUND_ATMOSPHERE)
vec3 fogColor = colorCorrect(v_fogMieColor) + finalColor.rgb * colorCorrect(v_fogRayleighColor);
#ifndef HDR
- const float fExposure = 2.0;
fogColor = vec3(1.0) - exp(-fExposure * fogColor);
#endif
#endif
@@ -375,12 +443,38 @@ void main()
#endif
#ifdef GROUND_ATMOSPHERE
- if (czm_sceneMode != czm_sceneMode3D)
+ if (!czm_backFacing())
{
- gl_FragColor = finalColor;
- return;
+ vec3 groundAtmosphereColor = computeGroundAtmosphereColor(fogColor, finalColor, atmosphereLightDirection, cameraDist);
+ finalColor = vec4(mix(finalColor.rgb, groundAtmosphereColor, fade), finalColor.a);
}
+#endif
+#ifdef UNDERGROUND_COLOR
+ if (czm_backFacing())
+ {
+ float distanceFromEllipsoid = max(czm_eyeHeight, 0.0);
+ float distance = max(v_distance - distanceFromEllipsoid, 0.0);
+ float blendAmount = interpolateByDistance(u_undergroundColorAlphaByDistance, distance);
+ vec4 undergroundColor = vec4(u_undergroundColor.rgb, u_undergroundColor.a * blendAmount);
+ finalColor = alphaBlend(undergroundColor, finalColor);
+ }
+#endif
+
+#ifdef TRANSLUCENT
+ if (inTranslucencyRectangle())
+ {
+ vec4 alphaByDistance = gl_FrontFacing ? u_frontFaceAlphaByDistance : u_backFaceAlphaByDistance;
+ finalColor.a *= interpolateByDistance(alphaByDistance, v_distance);
+ }
+#endif
+
+ gl_FragColor = finalColor;
+}
+
+#ifdef GROUND_ATMOSPHERE
+vec3 computeGroundAtmosphereColor(vec3 fogColor, vec4 finalColor, vec3 atmosphereLightDirection, float cameraDist)
+{
#if defined(PER_FRAGMENT_GROUND_ATMOSPHERE) && defined(DYNAMIC_ATMOSPHERE_LIGHTING) && (defined(ENABLE_DAYNIGHT_SHADING) || defined(ENABLE_VERTEX_LIGHTING))
float mpp = czm_metersPerPixel(vec4(0.0, 0.0, -czm_currentFrustum.x, 1.0), 1.0);
vec2 xy = gl_FragCoord.xy / czm_viewport.zw * 2.0 - vec2(1.0);
@@ -402,8 +496,8 @@ void main()
groundAtmosphereColor = vec3(1.0) - exp(-fExposure * groundAtmosphereColor);
#endif
- fadeInDist = u_nightFadeDistance.x;
- fadeOutDist = u_nightFadeDistance.y;
+ float fadeInDist = u_nightFadeDistance.x;
+ float fadeOutDist = u_nightFadeDistance.y;
float sunlitAtmosphereIntensity = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.0, 1.0);
@@ -422,11 +516,9 @@ void main()
groundAtmosphereColor = czm_saturation(groundAtmosphereColor, 1.6);
#endif
- finalColor = vec4(mix(finalColor.rgb, groundAtmosphereColor, fade), finalColor.a);
-#endif
-
- gl_FragColor = finalColor;
+ return groundAtmosphereColor;
}
+#endif
#ifdef SHOW_REFLECTIVE_OCEAN
diff --git a/Source/Shaders/GlobeVS.glsl b/Source/Shaders/GlobeVS.glsl
index c0d6aa757d5d..e233638f8008 100644
--- a/Source/Shaders/GlobeVS.glsl
+++ b/Source/Shaders/GlobeVS.glsl
@@ -28,8 +28,11 @@ varying float v_aspect;
varying float v_height;
#endif
-#if defined(FOG) || defined(GROUND_ATMOSPHERE)
+#if defined(FOG) || defined(GROUND_ATMOSPHERE) || defined(UNDERGROUND_COLOR) || defined(TRANSLUCENT)
varying float v_distance;
+#endif
+
+#if defined(FOG) || defined(GROUND_ATMOSPHERE)
varying vec3 v_fogMieColor;
varying vec3 v_fogRayleighColor;
#endif
@@ -172,6 +175,9 @@ void main()
AtmosphereColor atmosFogColor = computeGroundAtmosphereFromSpace(position3DWC, false, vec3(0.0));
v_fogMieColor = atmosFogColor.mie;
v_fogRayleighColor = atmosFogColor.rayleigh;
+#endif
+
+#if defined(FOG) || defined(GROUND_ATMOSPHERE) || defined(UNDERGROUND_COLOR) || defined(TRANSLUCENT)
v_distance = length((czm_modelView3D * vec4(position3DWC, 1.0)).xyz);
#endif
diff --git a/Source/Shaders/PolylineShadowVolumeFS.glsl b/Source/Shaders/PolylineShadowVolumeFS.glsl
index d8b65a80fd0e..b571272aa339 100644
--- a/Source/Shaders/PolylineShadowVolumeFS.glsl
+++ b/Source/Shaders/PolylineShadowVolumeFS.glsl
@@ -83,5 +83,8 @@ void main(void)
gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);
#endif // PER_INSTANCE_COLOR
- czm_writeDepthClampedToFarPlane();
+ // Premultiply alpha. Required for classification primitives on translucent globe.
+ gl_FragColor.rgb *= gl_FragColor.a;
+
+ czm_writeDepthClamp();
}
diff --git a/Source/Shaders/PolylineShadowVolumeVS.glsl b/Source/Shaders/PolylineShadowVolumeVS.glsl
index 9d17be9312d2..61c9f04ed625 100644
--- a/Source/Shaders/PolylineShadowVolumeVS.glsl
+++ b/Source/Shaders/PolylineShadowVolumeVS.glsl
@@ -157,7 +157,7 @@ void main()
#endif
positionEC.xyz += width * normalEC;
- gl_Position = czm_depthClampFarPlane(czm_projection * positionEC);
+ gl_Position = czm_depthClamp(czm_projection * positionEC);
#ifdef ANGLE_VARYING
// Approximate relative screen space direction of the line.
diff --git a/Source/Shaders/ShadowVolumeAppearanceFS.glsl b/Source/Shaders/ShadowVolumeAppearanceFS.glsl
index 1231a8b0cbae..51496c9ccf8c 100644
--- a/Source/Shaders/ShadowVolumeAppearanceFS.glsl
+++ b/Source/Shaders/ShadowVolumeAppearanceFS.glsl
@@ -73,7 +73,7 @@ void main(void)
#ifdef CULL_FRAGMENTS
if (0.0 <= uv.x && uv.x <= 1.0 && 0.0 <= uv.y && uv.y <= 1.0) {
gl_FragColor.a = 1.0; // 0.0 alpha leads to discard from ShaderSource.createPickFragmentShaderSource
- czm_writeDepthClampedToFarPlane();
+ czm_writeDepthClamp();
}
#else // CULL_FRAGMENTS
gl_FragColor.a = 1.0;
@@ -110,6 +110,9 @@ void main(void)
gl_FragColor = czm_phong(normalize(-eyeCoordinate.xyz), material, czm_lightDirectionEC);
#endif // FLAT
+ // Premultiply alpha. Required for classification primitives on translucent globe.
+ gl_FragColor.rgb *= gl_FragColor.a;
+
#else // PER_INSTANCE_COLOR
// Material support.
@@ -146,7 +149,10 @@ void main(void)
gl_FragColor = czm_phong(normalize(-eyeCoordinate.xyz), material, czm_lightDirectionEC);
#endif // FLAT
+ // Premultiply alpha. Required for classification primitives on translucent globe.
+ gl_FragColor.rgb *= gl_FragColor.a;
+
#endif // PER_INSTANCE_COLOR
- czm_writeDepthClampedToFarPlane();
+ czm_writeDepthClamp();
#endif // PICK
}
diff --git a/Source/Shaders/ShadowVolumeAppearanceVS.glsl b/Source/Shaders/ShadowVolumeAppearanceVS.glsl
index 0f2b1c456a3b..8938a0447469 100644
--- a/Source/Shaders/ShadowVolumeAppearanceVS.glsl
+++ b/Source/Shaders/ShadowVolumeAppearanceVS.glsl
@@ -97,5 +97,5 @@ void main()
v_color = czm_batchTable_color(batchId);
#endif
- gl_Position = czm_depthClampFarPlane(czm_modelViewProjectionRelativeToEye * position);
+ gl_Position = czm_depthClamp(czm_modelViewProjectionRelativeToEye * position);
}
diff --git a/Source/Shaders/ShadowVolumeFS.glsl b/Source/Shaders/ShadowVolumeFS.glsl
index b1af3c3ff493..267d55b6fa87 100644
--- a/Source/Shaders/ShadowVolumeFS.glsl
+++ b/Source/Shaders/ShadowVolumeFS.glsl
@@ -13,5 +13,5 @@ void main(void)
#else
gl_FragColor = vec4(1.0);
#endif
- czm_writeDepthClampedToFarPlane();
+ czm_writeDepthClamp();
}
diff --git a/Source/Shaders/SkyAtmosphereCommon.glsl b/Source/Shaders/SkyAtmosphereCommon.glsl
new file mode 100644
index 000000000000..53e4ec271140
--- /dev/null
+++ b/Source/Shaders/SkyAtmosphereCommon.glsl
@@ -0,0 +1,287 @@
+/**
+ * @license
+ * Copyright (c) 2000-2005, Sean O'Neil (s_p_oneil@hotmail.com)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the project nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Modifications made by Cesium GS, Inc.
+ */
+
+ // Code: http://sponeil.net/
+ // GPU Gems 2 Article: https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter16.html
+
+const float Kr = 0.0025;
+const float Kr4PI = Kr * 4.0 * czm_pi;
+const float Km = 0.0015;
+const float Km4PI = Km * 4.0 * czm_pi;
+const float ESun = 15.0;
+const float KmESun = Km * ESun;
+const float KrESun = Kr * ESun;
+const vec3 InvWavelength = vec3(
+ 5.60204474633241, // Red = 1.0 / Math.pow(0.650, 4.0)
+ 9.473284437923038, // Green = 1.0 / Math.pow(0.570, 4.0)
+ 19.643802610477206); // Blue = 1.0 / Math.pow(0.475, 4.0)
+const float rayleighScaleDepth = 0.25;
+
+const int nSamples = 2;
+const float fSamples = 2.0;
+
+const float g = -0.95;
+const float g2 = g * g;
+
+#ifdef COLOR_CORRECT
+uniform vec3 u_hsbShift; // Hue, saturation, brightness
+#endif
+
+uniform vec3 u_radiiAndDynamicAtmosphereColor; // outer radius, inner radius, dynamic atmosphere color flag
+
+float scale(float cosAngle)
+{
+ float x = 1.0 - cosAngle;
+ return rayleighScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
+}
+
+vec3 getLightDirection(vec3 positionWC)
+{
+ float lightEnum = u_radiiAndDynamicAtmosphereColor.z;
+ vec3 lightDirection =
+ positionWC * float(lightEnum == 0.0) +
+ czm_lightDirectionWC * float(lightEnum == 1.0) +
+ czm_sunDirectionWC * float(lightEnum == 2.0);
+ return normalize(lightDirection);
+}
+
+void calculateRayScatteringFromSpace(in vec3 positionWC, in vec3 ray, in float innerRadius, in float outerRadius, inout float far, out vec3 start, out float startOffset)
+{
+ // Calculate the closest intersection of the ray with the outer atmosphere (which is the near point of the ray passing through the atmosphere)
+ float cameraHeight = length(positionWC);
+ float B = 2.0 * dot(positionWC, ray);
+ float C = cameraHeight * cameraHeight - outerRadius * outerRadius;
+ float det = max(0.0, B * B - 4.0 * C);
+ float near = 0.5 * (-B - sqrt(det));
+
+ // Calculate the ray's starting position, then calculate its scattering offset
+ start = positionWC + ray * near;
+ far -= near;
+ float startAngle = dot(ray, start) / outerRadius;
+ float startDepth = exp(-1.0 / rayleighScaleDepth);
+ startOffset = startDepth * scale(startAngle);
+}
+
+void calculateRayScatteringFromGround(in vec3 positionWC, in vec3 ray, in float atmosphereScale, in float innerRadius, out vec3 start, out float startOffset)
+{
+ // Calculate the ray's starting position, then calculate its scattering offset
+ float cameraHeight = length(positionWC);
+ start = positionWC;
+ float height = length(start);
+ float depth = exp((atmosphereScale / rayleighScaleDepth ) * (innerRadius - cameraHeight));
+ float startAngle = dot(ray, start) / height;
+ startOffset = depth*scale(startAngle);
+}
+
+czm_raySegment rayEllipsoidIntersection(czm_ray ray, vec3 inverseRadii)
+{
+ vec3 o = inverseRadii * (czm_inverseView * vec4(ray.origin, 1.0)).xyz;
+ vec3 d = inverseRadii * (czm_inverseView * vec4(ray.direction, 0.0)).xyz;
+
+ float a = dot(d, d);
+ float b = dot(d, o);
+ float c = dot(o, o) - 1.0;
+ float discriminant = b * b - a * c;
+ if (discriminant < 0.0)
+ {
+ return czm_emptyRaySegment;
+ }
+ discriminant = sqrt(discriminant);
+ float t1 = (-b - discriminant) / a;
+ float t2 = (-b + discriminant) / a;
+
+ if (t1 < 0.0 && t2 < 0.0)
+ {
+ return czm_emptyRaySegment;
+ }
+
+ if (t1 < 0.0 && t2 >= 0.0)
+ {
+ t1 = 0.0;
+ }
+
+ return czm_raySegment(t1, t2);
+}
+
+vec3 getAdjustedPosition(vec3 positionWC, float innerRadius)
+{
+ // Adjust the camera position so that atmosphere color looks the same wherever the eye height is the same
+ float cameraHeight = czm_eyeHeight + innerRadius;
+ return normalize(positionWC) * cameraHeight;
+}
+
+vec3 getTranslucentPosition(vec3 positionWC, vec3 outerPositionWC, float innerRadius, out bool intersectsEllipsoid)
+{
+ vec3 directionWC = normalize(outerPositionWC - positionWC);
+ vec3 directionEC = czm_viewRotation * directionWC;
+ czm_ray viewRay = czm_ray(vec3(0.0), directionEC);
+ czm_raySegment raySegment = rayEllipsoidIntersection(viewRay, czm_ellipsoidInverseRadii);
+ intersectsEllipsoid = raySegment.start >= 0.0;
+
+ if (intersectsEllipsoid)
+ {
+ return positionWC + raySegment.stop * directionWC;
+ }
+
+ return getAdjustedPosition(positionWC, innerRadius);
+}
+
+void calculateMieColorAndRayleighColor(vec3 outerPositionWC, out vec3 mieColor, out vec3 rayleighColor)
+{
+ // Unpack attributes
+ float outerRadius = u_radiiAndDynamicAtmosphereColor.x;
+ float innerRadius = u_radiiAndDynamicAtmosphereColor.y;
+
+#ifdef GLOBE_TRANSLUCENT
+ bool intersectsEllipsoid = false;
+ vec3 startPositionWC = getTranslucentPosition(czm_viewerPositionWC, outerPositionWC, innerRadius, intersectsEllipsoid);
+#else
+ vec3 startPositionWC = getAdjustedPosition(czm_viewerPositionWC, innerRadius);
+#endif
+
+ vec3 lightDirection = getLightDirection(startPositionWC);
+
+ // Get the ray from the start position to the outer position and its length (which is the far point of the ray passing through the atmosphere)
+ vec3 ray = outerPositionWC - startPositionWC;
+ float far = length(ray);
+ ray /= far;
+
+ float atmosphereScale = 1.0 / (outerRadius - innerRadius);
+
+ vec3 start;
+ float startOffset;
+
+#ifdef SKY_FROM_SPACE
+#ifdef GLOBE_TRANSLUCENT
+ if (intersectsEllipsoid)
+ {
+ calculateRayScatteringFromGround(startPositionWC, ray, atmosphereScale, innerRadius, start, startOffset);
+ }
+ else
+ {
+ calculateRayScatteringFromSpace(startPositionWC, ray, innerRadius, outerRadius, far, start, startOffset);
+ }
+#else
+ calculateRayScatteringFromSpace(startPositionWC, ray, innerRadius, outerRadius, far, start, startOffset);
+#endif
+#else
+ calculateRayScatteringFromGround(startPositionWC, ray, atmosphereScale, innerRadius, start, startOffset);
+#endif
+
+ // Initialize the scattering loop variables
+ float sampleLength = far / fSamples;
+ float scaledLength = sampleLength * atmosphereScale;
+ vec3 sampleRay = ray * sampleLength;
+ vec3 samplePoint = start + sampleRay * 0.5;
+
+ // Now loop through the sample rays
+ vec3 frontColor = vec3(0.0, 0.0, 0.0);
+
+ for (int i = 0; i czm_epsilon7 ? hsb.z + u_hsbShift.z : 0.0; // brightness
+ // Convert shifted hsb back to rgb
+ rgb = czm_HSBToRGB(hsb);
+#endif
+
+ float outerRadius = u_radiiAndDynamicAtmosphereColor.x;
+ float innerRadius = u_radiiAndDynamicAtmosphereColor.y;
+ float lightEnum = u_radiiAndDynamicAtmosphereColor.z;
+
+ float cameraHeight = czm_eyeHeight + innerRadius;
+
+ // Alter alpha based on how close the viewer is to the ground (1.0 = on ground, 0.0 = at edge of atmosphere)
+ float atmosphereAlpha = clamp((outerRadius - cameraHeight) / (outerRadius - innerRadius), 0.0, 1.0);
+
+ // Alter alpha based on time of day (0.0 = night , 1.0 = day)
+ float nightAlpha = (lightEnum != 0.0) ? clamp(dot(normalize(positionWC), lightDirection), 0.0, 1.0) : 1.0;
+ atmosphereAlpha *= pow(nightAlpha, 0.5);
+
+ vec4 finalColor = vec4(rgb, mix(clamp(rgbExposure.b, 0.0, 1.0), 1.0, atmosphereAlpha) * smoothstep(0.0, 1.0, czm_morphTime));
+
+ if (mieColor.b > 1.0)
+ {
+ // Fade atmosphere below the ellipsoid. As the camera zooms further away from the ellipsoid draw
+ // a larger atmosphere ring to cover empty space of lower LOD globe tiles.
+ float strength = mieColor.b;
+ float minDistance = outerRadius;
+ float maxDistance = outerRadius * 3.0;
+ float maxStrengthLerp = 1.0 - clamp((maxDistance - cameraHeight) / (maxDistance - minDistance), 0.0, 1.0);
+ float maxStrength = mix(100.0, 10000.0, maxStrengthLerp);
+ strength = min(strength, maxStrength);
+ float alpha = 1.0 - (strength / maxStrength);
+ finalColor.a = alpha;
+ }
+
+ return finalColor;
+}
diff --git a/Source/Shaders/SkyAtmosphereFS.glsl b/Source/Shaders/SkyAtmosphereFS.glsl
index 9c5625299b81..b80e54cd43c0 100644
--- a/Source/Shaders/SkyAtmosphereFS.glsl
+++ b/Source/Shaders/SkyAtmosphereFS.glsl
@@ -1,90 +1,23 @@
-/**
- * @license
- * Copyright (c) 2000-2005, Sean O'Neil (s_p_oneil@hotmail.com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the project nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Modifications made by Analytical Graphics, Inc.
- */
+varying vec3 v_outerPositionWC;
- // Code: http://sponeil.net/
- // GPU Gems 2 Article: https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter16.html
-
-#ifdef COLOR_CORRECT
-uniform vec3 u_hsbShift; // Hue, saturation, brightness
-#endif
-
-uniform vec4 u_cameraAndRadiiAndDynamicAtmosphereColor; // Camera height, outer radius, inner radius, dynamic atmosphere color flag
-
-const float g = -0.95;
-const float g2 = g * g;
-
-varying vec3 v_rayleighColor;
+#ifndef PER_FRAGMENT_ATMOSPHERE
varying vec3 v_mieColor;
-varying vec3 v_toCamera;
-varying vec3 v_positionEC;
+varying vec3 v_rayleighColor;
+#endif
void main (void)
{
- float lightEnum = u_cameraAndRadiiAndDynamicAtmosphereColor.w;
- vec3 lightDirection =
- czm_viewerPositionWC * float(lightEnum == 0.0) +
- czm_lightDirectionWC * float(lightEnum == 1.0) +
- czm_sunDirectionWC * float(lightEnum == 2.0);
- lightDirection = normalize(lightDirection);
-
- // Extra normalize added for Android
- float cosAngle = dot(lightDirection, normalize(v_toCamera)) / length(v_toCamera);
- float rayleighPhase = 0.75 * (1.0 + cosAngle * cosAngle);
- float miePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + cosAngle * cosAngle) / pow(1.0 + g2 - 2.0 * g * cosAngle, 1.5);
-
- vec3 rgb = rayleighPhase * v_rayleighColor + miePhase * v_mieColor;
-
-#ifndef HDR
- const float exposure = 2.0;
- rgb = vec3(1.0) - exp(-exposure * rgb);
+ vec3 toCamera = czm_viewerPositionWC - v_outerPositionWC;
+ vec3 lightDirection = getLightDirection(czm_viewerPositionWC);
+ vec3 mieColor;
+ vec3 rayleighColor;
+
+#ifdef PER_FRAGMENT_ATMOSPHERE
+ calculateMieColorAndRayleighColor(v_outerPositionWC, mieColor, rayleighColor);
+#else
+ mieColor = v_mieColor;
+ rayleighColor = v_rayleighColor;
#endif
-#ifdef COLOR_CORRECT
- // Convert rgb color to hsb
- vec3 hsb = czm_RGBToHSB(rgb);
- // Perform hsb shift
- hsb.x += u_hsbShift.x; // hue
- hsb.y = clamp(hsb.y + u_hsbShift.y, 0.0, 1.0); // saturation
- hsb.z = hsb.z > czm_epsilon7 ? hsb.z + u_hsbShift.z : 0.0; // brightness
- // Convert shifted hsb back to rgb
- rgb = czm_HSBToRGB(hsb);
-#endif
-
- // Alter alpha based on how close the viewer is to the ground (1.0 = on ground, 0.0 = at edge of atmosphere)
- float atmosphereAlpha = clamp((u_cameraAndRadiiAndDynamicAtmosphereColor.y - u_cameraAndRadiiAndDynamicAtmosphereColor.x) / (u_cameraAndRadiiAndDynamicAtmosphereColor.y - u_cameraAndRadiiAndDynamicAtmosphereColor.z), 0.0, 1.0);
-
- // Alter alpha based on time of day (0.0 = night , 1.0 = day)
- float nightAlpha = (lightEnum != 0.0) ? clamp(dot(normalize(czm_viewerPositionWC), lightDirection), 0.0, 1.0) : 1.0;
- atmosphereAlpha *= pow(nightAlpha, 0.5);
-
- gl_FragColor = vec4(rgb, mix(rgb.b, 1.0, atmosphereAlpha) * smoothstep(0.0, 1.0, czm_morphTime));
+ gl_FragColor = calculateFinalColor(czm_viewerPositionWC, toCamera, lightDirection, mieColor, rayleighColor);
}
diff --git a/Source/Shaders/SkyAtmosphereVS.glsl b/Source/Shaders/SkyAtmosphereVS.glsl
index bfb0bad8922f..3c66fd31b37d 100644
--- a/Source/Shaders/SkyAtmosphereVS.glsl
+++ b/Source/Shaders/SkyAtmosphereVS.glsl
@@ -1,135 +1,19 @@
-/**
- * @license
- * Copyright (c) 2000-2005, Sean O'Neil (s_p_oneil@hotmail.com)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * * Neither the name of the project nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Modifications made by Analytical Graphics, Inc.
- */
-
- // Code: http://sponeil.net/
- // GPU Gems 2 Article: https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter16.html
-
attribute vec4 position;
-uniform vec4 u_cameraAndRadiiAndDynamicAtmosphereColor; // Camera height, outer radius, inner radius, dynamic atmosphere color flag
-
-const float Kr = 0.0025;
-const float Kr4PI = Kr * 4.0 * czm_pi;
-const float Km = 0.0015;
-const float Km4PI = Km * 4.0 * czm_pi;
-const float ESun = 15.0;
-const float KmESun = Km * ESun;
-const float KrESun = Kr * ESun;
-const vec3 InvWavelength = vec3(
- 5.60204474633241, // Red = 1.0 / Math.pow(0.650, 4.0)
- 9.473284437923038, // Green = 1.0 / Math.pow(0.570, 4.0)
- 19.643802610477206); // Blue = 1.0 / Math.pow(0.475, 4.0)
-const float rayleighScaleDepth = 0.25;
+varying vec3 v_outerPositionWC;
-const int nSamples = 2;
-const float fSamples = 2.0;
-
-varying vec3 v_rayleighColor;
+#ifndef PER_FRAGMENT_ATMOSPHERE
varying vec3 v_mieColor;
-varying vec3 v_toCamera;
-
-float scale(float cosAngle)
-{
- float x = 1.0 - cosAngle;
- return rayleighScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
-}
+varying vec3 v_rayleighColor;
+#endif
void main(void)
{
- // Unpack attributes
- float cameraHeight = u_cameraAndRadiiAndDynamicAtmosphereColor.x;
- float outerRadius = u_cameraAndRadiiAndDynamicAtmosphereColor.y;
- float innerRadius = u_cameraAndRadiiAndDynamicAtmosphereColor.z;
-
- // Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the atmosphere)
- vec3 positionV3 = position.xyz;
- vec3 ray = positionV3 - czm_viewerPositionWC;
- float far = length(ray);
- ray /= far;
- float atmosphereScale = 1.0 / (outerRadius - innerRadius);
+ vec4 positionWC = czm_model * position;
-#ifdef SKY_FROM_SPACE
- // Calculate the closest intersection of the ray with the outer atmosphere (which is the near point of the ray passing through the atmosphere)
- float B = 2.0 * dot(czm_viewerPositionWC, ray);
- float C = cameraHeight * cameraHeight - outerRadius * outerRadius;
- float det = max(0.0, B*B - 4.0 * C);
- float near = 0.5 * (-B - sqrt(det));
-
- // Calculate the ray's starting position, then calculate its scattering offset
- vec3 start = czm_viewerPositionWC + ray * near;
- far -= near;
- float startAngle = dot(ray, start) / outerRadius;
- float startDepth = exp(-1.0 / rayleighScaleDepth );
- float startOffset = startDepth*scale(startAngle);
-#else // SKY_FROM_ATMOSPHERE
- // Calculate the ray's starting position, then calculate its scattering offset
- vec3 start = czm_viewerPositionWC;
- float height = length(start);
- float depth = exp((atmosphereScale / rayleighScaleDepth ) * (innerRadius - cameraHeight));
- float startAngle = dot(ray, start) / height;
- float startOffset = depth*scale(startAngle);
+#ifndef PER_FRAGMENT_ATMOSPHERE
+ calculateMieColorAndRayleighColor(positionWC.xyz, v_mieColor, v_rayleighColor);
#endif
-
- float lightEnum = u_cameraAndRadiiAndDynamicAtmosphereColor.w;
- vec3 lightDirection =
- czm_viewerPositionWC * float(lightEnum == 0.0) +
- czm_lightDirectionWC * float(lightEnum == 1.0) +
- czm_sunDirectionWC * float(lightEnum == 2.0);
- lightDirection = normalize(lightDirection);
-
- // Initialize the scattering loop variables
- float sampleLength = far / fSamples;
- float scaledLength = sampleLength * atmosphereScale;
- vec3 sampleRay = ray * sampleLength;
- vec3 samplePoint = start + sampleRay * 0.5;
-
- // Now loop through the sample rays
- vec3 frontColor = vec3(0.0, 0.0, 0.0);
-
- for(int i=0; i >includeStart('debug', pragmas.debug);
diff --git a/Source/Widgets/CesiumWidget/CesiumWidget.js b/Source/Widgets/CesiumWidget/CesiumWidget.js
index bc1add14f2f8..22dd5ff3ad3f 100644
--- a/Source/Widgets/CesiumWidget/CesiumWidget.js
+++ b/Source/Widgets/CesiumWidget/CesiumWidget.js
@@ -126,15 +126,15 @@ function configureCameraFrustum(widget) {
* @param {Element|String} container The DOM element or ID that will contain the widget.
* @param {Object} [options] Object with the following properties:
* @param {Clock} [options.clock=new Clock()] The clock to use to control current time.
- * @param {ImageryProvider} [options.imageryProvider=createWorldImagery()] The imagery provider to serve as the base layer. If set to false
, no imagery provider will be added.
+ * @param {ImageryProvider | false} [options.imageryProvider=createWorldImagery()] The imagery provider to serve as the base layer. If set to false
, no imagery provider will be added.
* @param {TerrainProvider} [options.terrainProvider=new EllipsoidTerrainProvider] The terrain provider.
- * @param {SkyBox} [options.skyBox] The skybox used to render the stars. When undefined
, the default stars are used. If set to false
, no skyBox, Sun, or Moon will be added.
- * @param {SkyAtmosphere} [options.skyAtmosphere] Blue sky, and the glow around the Earth's limb. Set to false
to turn it off.
+ * @param {SkyBox| false} [options.skyBox] The skybox used to render the stars. When undefined
, the default stars are used. If set to false
, no skyBox, Sun, or Moon will be added.
+ * @param {SkyAtmosphere | false} [options.skyAtmosphere] Blue sky, and the glow around the Earth's limb. Set to false
to turn it off.
* @param {SceneMode} [options.sceneMode=SceneMode.SCENE3D] The initial scene mode.
* @param {Boolean} [options.scene3DOnly=false] When true
, each geometry instance will only be rendered in 3D to save GPU memory.
* @param {Boolean} [options.orderIndependentTranslucency=true] If true and the configuration supports it, use order independent translucency.
* @param {MapProjection} [options.mapProjection=new GeographicProjection()] The map projection to use in 2D and Columbus View modes.
- * @param {Globe} [options.globe=new Globe(mapProjection.ellipsoid)] The globe to use in the scene. If set to false
, no globe will be added.
+ * @param {Globe | false} [options.globe=new Globe(mapProjection.ellipsoid)] The globe to use in the scene. If set to false
, no globe will be added.
* @param {Boolean} [options.useDefaultRenderLoop=true] True if this widget should control the render loop, false otherwise.
* @param {Boolean} [options.useBrowserRecommendedResolution=true] If true, render at the browser's recommended resolution and ignore window.devicePixelRatio
.
* @param {Number} [options.targetFrameRate] The target frame rate when using the default render loop.
@@ -393,6 +393,7 @@ Object.defineProperties(CesiumWidget.prototype, {
* @memberof CesiumWidget.prototype
*
* @type {Element}
+ * @readonly
*/
container: {
get: function () {
@@ -404,7 +405,8 @@ Object.defineProperties(CesiumWidget.prototype, {
* Gets the canvas.
* @memberof CesiumWidget.prototype
*
- * @type {Canvas}
+ * @type {HTMLCanvasElement}
+ * @readonly
*/
canvas: {
get: function () {
@@ -417,6 +419,7 @@ Object.defineProperties(CesiumWidget.prototype, {
* @memberof CesiumWidget.prototype
*
* @type {Element}
+ * @readonly
*/
creditContainer: {
get: function () {
@@ -429,6 +432,7 @@ Object.defineProperties(CesiumWidget.prototype, {
* @memberof CesiumWidget.prototype
*
* @type {Element}
+ * @readonly
*/
creditViewport: {
get: function () {
@@ -441,6 +445,7 @@ Object.defineProperties(CesiumWidget.prototype, {
* @memberof CesiumWidget.prototype
*
* @type {Scene}
+ * @readonly
*/
scene: {
get: function () {
@@ -494,6 +499,7 @@ Object.defineProperties(CesiumWidget.prototype, {
* @memberof CesiumWidget.prototype
*
* @type {Clock}
+ * @readonly
*/
clock: {
get: function () {
@@ -506,6 +512,7 @@ Object.defineProperties(CesiumWidget.prototype, {
* @memberof CesiumWidget.prototype
*
* @type {ScreenSpaceEventHandler}
+ * @readonly
*/
screenSpaceEventHandler: {
get: function () {
diff --git a/Source/Widgets/Geocoder/Geocoder.js b/Source/Widgets/Geocoder/Geocoder.js
index 390a3b879ea1..943d52b1e6dd 100644
--- a/Source/Widgets/Geocoder/Geocoder.js
+++ b/Source/Widgets/Geocoder/Geocoder.js
@@ -24,7 +24,7 @@ var stopSearchPath =
* @param {GeocoderService[]} [options.geocoderServices] The geocoder services to be used
* @param {Boolean} [options.autoComplete = true] True if the geocoder should query as the user types to autocomplete
* @param {Number} [options.flightDuration=1.5] The duration of the camera flight to an entered location, in seconds.
- * @param {Geocoder~DestinationFoundFunction} [options.destinationFound=GeocoderViewModel.flyToDestination] A callback function that is called after a successful geocode. If not supplied, the default behavior is to fly the camera to the result destination.
+ * @param {Geocoder.DestinationFoundFunction} [options.destinationFound=GeocoderViewModel.flyToDestination] A callback function that is called after a successful geocode. If not supplied, the default behavior is to fly the camera to the result destination.
*/
function Geocoder(options) {
//>>includeStart('debug', pragmas.debug);
@@ -224,7 +224,7 @@ Geocoder.prototype.destroy = function () {
/**
* A function that handles the result of a successful geocode.
- * @callback Geocoder~DestinationFoundFunction
+ * @callback Geocoder.DestinationFoundFunction
* @param {GeocoderViewModel} viewModel The view model.
* @param {Cartesian3|Rectangle} destination The destination result of the geocode.
*/
diff --git a/Source/Widgets/Geocoder/GeocoderViewModel.js b/Source/Widgets/Geocoder/GeocoderViewModel.js
index b704825c6786..b384fcb853de 100644
--- a/Source/Widgets/Geocoder/GeocoderViewModel.js
+++ b/Source/Widgets/Geocoder/GeocoderViewModel.js
@@ -29,7 +29,7 @@ var DEFAULT_HEIGHT = 1000;
* If more than one are supplied, suggestions will be gathered for the geocoders that support it,
* and if no suggestion is selected the result from the first geocoder service wil be used.
* @param {Number} [options.flightDuration] The duration of the camera flight to an entered location, in seconds.
- * @param {Geocoder~DestinationFoundFunction} [options.destinationFound=GeocoderViewModel.flyToDestination] A callback function that is called after a successful geocode. If not supplied, the default behavior is to fly the camera to the result destination.
+ * @param {Geocoder.DestinationFoundFunction} [options.destinationFound=GeocoderViewModel.flyToDestination] A callback function that is called after a successful geocode. If not supplied, the default behavior is to fly the camera to the result destination.
*/
function GeocoderViewModel(options) {
//>>includeStart('debug', pragmas.debug);
@@ -157,7 +157,7 @@ function GeocoderViewModel(options) {
/**
* Gets and sets the command called when a geocode destination is found
- * @type {Geocoder~DestinationFoundFunction}
+ * @type {Geocoder.DestinationFoundFunction}
*/
this.destinationFound = defaultValue(
options.destinationFound,
@@ -547,7 +547,7 @@ function updateSearchSuggestions(viewModel) {
/**
* A function to fly to the destination found by a successful geocode.
- * @type {Geocoder~DestinationFoundFunction}
+ * @type {Geocoder.DestinationFoundFunction}
*/
GeocoderViewModel.flyToDestination = flyToDestination;
diff --git a/Source/Widgets/SelectionIndicator/SelectionIndicatorViewModel.js b/Source/Widgets/SelectionIndicator/SelectionIndicatorViewModel.js
index 08cee4b730f6..83ee0ce9a240 100644
--- a/Source/Widgets/SelectionIndicator/SelectionIndicatorViewModel.js
+++ b/Source/Widgets/SelectionIndicator/SelectionIndicatorViewModel.js
@@ -87,7 +87,7 @@ function SelectionIndicatorViewModel(
* Gets or sets the function for converting the world position of the object to the screen space position.
*
* @member
- * @type {SelectionIndicatorViewModel~ComputeScreenSpacePosition}
+ * @type {SelectionIndicatorViewModel.ComputeScreenSpacePosition}
* @default SceneTransforms.wgs84ToWindowCoordinates
*
* @example
@@ -205,7 +205,7 @@ Object.defineProperties(SelectionIndicatorViewModel.prototype, {
/**
* A function that converts the world position of an object to a screen space position.
- * @callback SelectionIndicatorViewModel~ComputeScreenSpacePosition
+ * @callback SelectionIndicatorViewModel.ComputeScreenSpacePosition
* @param {Cartesian3} position The position in WGS84 (world) coordinates.
* @param {Cartesian2} result An object to return the input position transformed to window coordinates.
* @returns {Cartesian2} The modified result parameter.
diff --git a/Source/Widgets/SvgPathBindingHandler.js b/Source/Widgets/SvgPathBindingHandler.js
index e57e6429efc5..cba2bd5f3cb7 100644
--- a/Source/Widgets/SvgPathBindingHandler.js
+++ b/Source/Widgets/SvgPathBindingHandler.js
@@ -16,7 +16,7 @@ var svgClassName = "cesium-svgPath-svg";
* css: Optional. A string containing additional CSS classes to apply to the SVG. 'cesium-svgPath-svg' is always applied.
*
*
- * @exports SvgPathBindingHandler
+ * @namespace SvgPathBindingHandler
*
* @example
* // Create an SVG as a child of a div
@@ -29,6 +29,9 @@ var svgClassName = "cesium-svgPath-svg";
*
*/
var SvgPathBindingHandler = {
+ /**
+ * @function
+ */
register: function (knockout) {
knockout.bindingHandlers.cesiumSvgPath = {
init: function (element, valueAccessor) {
diff --git a/Source/Widgets/Viewer/Viewer.js b/Source/Widgets/Viewer/Viewer.js
index c54f7d9cdfb0..c03cc73ef83f 100644
--- a/Source/Widgets/Viewer/Viewer.js
+++ b/Source/Widgets/Viewer/Viewer.js
@@ -209,6 +209,58 @@ function enableVRUI(viewer, enabled) {
}
}
+/**
+ * @typedef {Object} Viewer.ConstructorOptions
+ *
+ * Initialization options for the Viewer constructor
+ *
+ * @property {Boolean} [animation=true] If set to false, the Animation widget will not be created.
+ * @property {Boolean} [baseLayerPicker=true] If set to false, the BaseLayerPicker widget will not be created.
+ * @property {Boolean} [fullscreenButton=true] If set to false, the FullscreenButton widget will not be created.
+ * @property {Boolean} [vrButton=false] If set to true, the VRButton widget will be created.
+ * @property {Boolean|GeocoderService[]} [geocoder=true] If set to false, the Geocoder widget will not be created.
+ * @property {Boolean} [homeButton=true] If set to false, the HomeButton widget will not be created.
+ * @property {Boolean} [infoBox=true] If set to false, the InfoBox widget will not be created.
+ * @property {Boolean} [sceneModePicker=true] If set to false, the SceneModePicker widget will not be created.
+ * @property {Boolean} [selectionIndicator=true] If set to false, the SelectionIndicator widget will not be created.
+ * @property {Boolean} [timeline=true] If set to false, the Timeline widget will not be created.
+ * @property {Boolean} [navigationHelpButton=true] If set to false, the navigation help button will not be created.
+ * @property {Boolean} [navigationInstructionsInitiallyVisible=true] True if the navigation instructions should initially be visible, or false if the should not be shown until the user explicitly clicks the button.
+ * @property {Boolean} [scene3DOnly=false] When true
, each geometry instance will only be rendered in 3D to save GPU memory.
+ * @property {Boolean} [shouldAnimate=false] true
if the clock should attempt to advance simulation time by default, false
otherwise. This option takes precedence over setting {@link Viewer#clockViewModel}.
+ * @property {ClockViewModel} [clockViewModel=new ClockViewModel(clock)] The clock view model to use to control current time.
+ * @property {ProviderViewModel} [selectedImageryProviderViewModel] The view model for the current base imagery layer, if not supplied the first available base layer is used. This value is only valid if `baseLayerPicker` is set to true.
+ * @property {ProviderViewModel[]} [imageryProviderViewModels=createDefaultImageryProviderViewModels()] The array of ProviderViewModels to be selectable from the BaseLayerPicker. This value is only valid if `baseLayerPicker` is set to true.
+ * @property {ProviderViewModel} [selectedTerrainProviderViewModel] The view model for the current base terrain layer, if not supplied the first available base layer is used. This value is only valid if `baseLayerPicker` is set to true.
+ * @property {ProviderViewModel[]} [terrainProviderViewModels=createDefaultTerrainProviderViewModels()] The array of ProviderViewModels to be selectable from the BaseLayerPicker. This value is only valid if `baseLayerPicker` is set to true.
+ * @property {ImageryProvider} [imageryProvider=createWorldImagery()] The imagery provider to use. This value is only valid if `baseLayerPicker` is set to false.
+ * @property {TerrainProvider} [terrainProvider=new EllipsoidTerrainProvider()] The terrain provider to use
+ * @property {SkyBox|false} [skyBox] The skybox used to render the stars. When undefined
, the default stars are used. If set to false
, no skyBox, Sun, or Moon will be added.
+ * @property {SkyAtmosphere|false} [skyAtmosphere] Blue sky, and the glow around the Earth's limb. Set to false
to turn it off.
+ * @property {Element|String} [fullscreenElement=document.body] The element or id to be placed into fullscreen mode when the full screen button is pressed.
+ * @property {Boolean} [useDefaultRenderLoop=true] True if this widget should control the render loop, false otherwise.
+ * @property {Number} [targetFrameRate] The target frame rate when using the default render loop.
+ * @property {Boolean} [showRenderLoopErrors=true] If true, this widget will automatically display an HTML panel to the user containing the error, if a render loop error occurs.
+ * @property {Boolean} [useBrowserRecommendedResolution=true] If true, render at the browser's recommended resolution and ignore window.devicePixelRatio
.
+ * @property {Boolean} [automaticallyTrackDataSourceClocks=true] If true, this widget will automatically track the clock settings of newly added DataSources, updating if the DataSource's clock changes. Set this to false if you want to configure the clock independently.
+ * @property {Object} [contextOptions] Context and WebGL creation properties corresponding to options
passed to {@link Scene}.
+ * @property {SceneMode} [sceneMode=SceneMode.SCENE3D] The initial scene mode.
+ * @property {MapProjection} [mapProjection=new GeographicProjection()] The map projection to use in 2D and Columbus View modes.
+ * @property {Globe} [globe=new Globe(mapProjection.ellipsoid)] The globe to use in the scene. If set to false
, no globe will be added.
+ * @property {Boolean} [orderIndependentTranslucency=true] If true and the configuration supports it, use order independent translucency.
+ * @property {Element|String} [creditContainer] The DOM element or ID that will contain the {@link CreditDisplay}. If not specified, the credits are added to the bottom of the widget itself.
+ * @property {Element|String} [creditViewport] The DOM element or ID that will contain the credit pop up created by the {@link CreditDisplay}. If not specified, it will appear over the widget itself.
+ * @property {DataSourceCollection} [dataSources=new DataSourceCollection()] The collection of data sources visualized by the widget. If this parameter is provided,
+ * the instance is assumed to be owned by the caller and will not be destroyed when the viewer is destroyed.
+ * @property {Number} [terrainExaggeration=1.0] A scalar used to exaggerate the terrain. Note that terrain exaggeration will not modify any other primitive as they are positioned relative to the ellipsoid.
+ * @property {Boolean} [shadows=false] Determines if shadows are cast by light sources.
+ * @property {ShadowMode} [terrainShadows=ShadowMode.RECEIVE_ONLY] Determines if the terrain casts or receives shadows from light sources.
+ * @property {MapMode2D} [mapMode2D=MapMode2D.INFINITE_SCROLL] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction.
+ * @property {Boolean} [projectionPicker=false] If set to true, the ProjectionPicker widget will be created.
+ * @property {Boolean} [requestRenderMode=false] If true, rendering a frame will only occur when needed as determined by changes within the scene. Enabling reduces the CPU/GPU usage of your application and uses less battery on mobile, but requires using {@link Scene#requestRender} to render a new frame explicitly in this mode. This will be necessary in many cases after making changes to the scene in other parts of the API. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}.
+ * @property {Number} [maximumRenderTimeChange=0.0] If requestRenderMode is true, this value defines the maximum change in simulation time allowed before a render is requested. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}.
+ */
+
/**
* A base widget for building applications. It composites all of the standard Cesium widgets into one reusable package.
* The widget can always be extended by using mixins, which add functionality useful for a variety of applications.
@@ -217,52 +269,7 @@ function enableVRUI(viewer, enabled) {
* @constructor
*
* @param {Element|String} container The DOM element or ID that will contain the widget.
- * @param {Object} [options] Object with the following properties:
- * @param {Boolean} [options.animation=true] If set to false, the Animation widget will not be created.
- * @param {Boolean} [options.baseLayerPicker=true] If set to false, the BaseLayerPicker widget will not be created.
- * @param {Boolean} [options.fullscreenButton=true] If set to false, the FullscreenButton widget will not be created.
- * @param {Boolean} [options.vrButton=false] If set to true, the VRButton widget will be created.
- * @param {Boolean|GeocoderService[]} [options.geocoder=true] If set to false, the Geocoder widget will not be created.
- * @param {Boolean} [options.homeButton=true] If set to false, the HomeButton widget will not be created.
- * @param {Boolean} [options.infoBox=true] If set to false, the InfoBox widget will not be created.
- * @param {Boolean} [options.sceneModePicker=true] If set to false, the SceneModePicker widget will not be created.
- * @param {Boolean} [options.selectionIndicator=true] If set to false, the SelectionIndicator widget will not be created.
- * @param {Boolean} [options.timeline=true] If set to false, the Timeline widget will not be created.
- * @param {Boolean} [options.navigationHelpButton=true] If set to false, the navigation help button will not be created.
- * @param {Boolean} [options.navigationInstructionsInitiallyVisible=true] True if the navigation instructions should initially be visible, or false if the should not be shown until the user explicitly clicks the button.
- * @param {Boolean} [options.scene3DOnly=false] When true
, each geometry instance will only be rendered in 3D to save GPU memory.
- * @param {Boolean} [options.shouldAnimate=false] true
if the clock should attempt to advance simulation time by default, false
otherwise. This option takes precedence over setting {@link Viewer#clockViewModel}.
- * @param {ClockViewModel} [options.clockViewModel=new ClockViewModel(options.clock)] The clock view model to use to control current time.
- * @param {ProviderViewModel} [options.selectedImageryProviderViewModel] The view model for the current base imagery layer, if not supplied the first available base layer is used. This value is only valid if options.baseLayerPicker is set to true.
- * @param {ProviderViewModel[]} [options.imageryProviderViewModels=createDefaultImageryProviderViewModels()] The array of ProviderViewModels to be selectable from the BaseLayerPicker. This value is only valid if options.baseLayerPicker is set to true.
- * @param {ProviderViewModel} [options.selectedTerrainProviderViewModel] The view model for the current base terrain layer, if not supplied the first available base layer is used. This value is only valid if options.baseLayerPicker is set to true.
- * @param {ProviderViewModel[]} [options.terrainProviderViewModels=createDefaultTerrainProviderViewModels()] The array of ProviderViewModels to be selectable from the BaseLayerPicker. This value is only valid if options.baseLayerPicker is set to true.
- * @param {ImageryProvider} [options.imageryProvider=createWorldImagery()] The imagery provider to use. This value is only valid if options.baseLayerPicker is set to false.
- * @param {TerrainProvider} [options.terrainProvider=new EllipsoidTerrainProvider()] The terrain provider to use
- * @param {SkyBox} [options.skyBox] The skybox used to render the stars. When undefined
, the default stars are used.
- * @param {SkyAtmosphere} [options.skyAtmosphere] Blue sky, and the glow around the Earth's limb. Set to false
to turn it off.
- * @param {Element|String} [options.fullscreenElement=document.body] The element or id to be placed into fullscreen mode when the full screen button is pressed.
- * @param {Boolean} [options.useDefaultRenderLoop=true] True if this widget should control the render loop, false otherwise.
- * @param {Number} [options.targetFrameRate] The target frame rate when using the default render loop.
- * @param {Boolean} [options.showRenderLoopErrors=true] If true, this widget will automatically display an HTML panel to the user containing the error, if a render loop error occurs.
- * @param {Boolean} [options.useBrowserRecommendedResolution=true] If true, render at the browser's recommended resolution and ignore window.devicePixelRatio
.
- * @param {Boolean} [options.automaticallyTrackDataSourceClocks=true] If true, this widget will automatically track the clock settings of newly added DataSources, updating if the DataSource's clock changes. Set this to false if you want to configure the clock independently.
- * @param {Object} [options.contextOptions] Context and WebGL creation properties corresponding to options
passed to {@link Scene}.
- * @param {SceneMode} [options.sceneMode=SceneMode.SCENE3D] The initial scene mode.
- * @param {MapProjection} [options.mapProjection=new GeographicProjection()] The map projection to use in 2D and Columbus View modes.
- * @param {Globe} [options.globe=new Globe(mapProjection.ellipsoid)] The globe to use in the scene. If set to false
, no globe will be added.
- * @param {Boolean} [options.orderIndependentTranslucency=true] If true and the configuration supports it, use order independent translucency.
- * @param {Element|String} [options.creditContainer] The DOM element or ID that will contain the {@link CreditDisplay}. If not specified, the credits are added to the bottom of the widget itself.
- * @param {Element|String} [options.creditViewport] The DOM element or ID that will contain the credit pop up created by the {@link CreditDisplay}. If not specified, it will appear over the widget itself.
- * @param {DataSourceCollection} [options.dataSources=new DataSourceCollection()] The collection of data sources visualized by the widget. If this parameter is provided,
- * the instance is assumed to be owned by the caller and will not be destroyed when the viewer is destroyed.
- * @param {Number} [options.terrainExaggeration=1.0] A scalar used to exaggerate the terrain. Note that terrain exaggeration will not modify any other primitive as they are positioned relative to the ellipsoid.
- * @param {Boolean} [options.shadows=false] Determines if shadows are cast by light sources.
- * @param {ShadowMode} [options.terrainShadows=ShadowMode.RECEIVE_ONLY] Determines if the terrain casts or receives shadows from light sources.
- * @param {MapMode2D} [options.mapMode2D=MapMode2D.INFINITE_SCROLL] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction.
- * @param {Boolean} [options.projectionPicker=false] If set to true, the ProjectionPicker widget will be created.
- * @param {Boolean} [options.requestRenderMode=false] If true, rendering a frame will only occur when needed as determined by changes within the scene. Enabling reduces the CPU/GPU usage of your application and uses less battery on mobile, but requires using {@link Scene#requestRender} to render a new frame explicitly in this mode. This will be necessary in many cases after making changes to the scene in other parts of the API. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}.
- * @param {Number} [options.maximumRenderTimeChange=0.0] If requestRenderMode is true, this value defines the maximum change in simulation time allowed before a render is requested. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}.
+ * @param {Viewer.ConstructorOptions} [options] Object describing initialization options
*
* @exception {DeveloperError} Element with id "container" does not exist in the document.
* @exception {DeveloperError} options.selectedImageryProviderViewModel is not available when not using the BaseLayerPicker widget, specify options.imageryProvider instead.
@@ -1065,7 +1072,7 @@ Object.defineProperties(Viewer.prototype, {
/**
* Gets the canvas.
* @memberof Viewer.prototype
- * @type {Canvas}
+ * @type {HTMLCanvasElement}
* @readonly
*/
canvas: {
@@ -1321,7 +1328,7 @@ Object.defineProperties(Viewer.prototype, {
/**
* Gets or sets the Entity instance currently being tracked by the camera.
* @memberof Viewer.prototype
- * @type {Entity}
+ * @type {Entity | undefined}
*/
trackedEntity: {
get: function () {
@@ -1370,7 +1377,7 @@ Object.defineProperties(Viewer.prototype, {
/**
* Gets or sets the object instance for which to display a selection indicator.
* @memberof Viewer.prototype
- * @type {Entity}
+ * @type {Entity | undefined}
*/
selectedEntity: {
get: function () {
@@ -1439,7 +1446,7 @@ Object.defineProperties(Viewer.prototype, {
* A mixin may add additional properties, functions, or other behavior
* to the provided viewer instance.
*
- * @param {Viewer~ViewerMixin} mixin The Viewer mixin to add to this instance.
+ * @param {Viewer.ViewerMixin} mixin The Viewer mixin to add to this instance.
* @param {Object} [options] The options object to be passed to the mixin function.
*
* @see viewerDragDropMixin
@@ -2311,7 +2318,7 @@ function updateTrackedEntity(viewer) {
/**
* A function that augments a Viewer instance with additional functionality.
- * @callback Viewer~ViewerMixin
+ * @callback Viewer.ViewerMixin
* @param {Viewer} viewer The viewer instance.
* @param {Object} options Options object to be passed to the mixin function.
*
diff --git a/Source/Widgets/Viewer/viewerCesium3DTilesInspectorMixin.js b/Source/Widgets/Viewer/viewerCesium3DTilesInspectorMixin.js
index ce0a01a079c9..c4bb1761429f 100644
--- a/Source/Widgets/Viewer/viewerCesium3DTilesInspectorMixin.js
+++ b/Source/Widgets/Viewer/viewerCesium3DTilesInspectorMixin.js
@@ -5,7 +5,7 @@ import Cesium3DTilesInspector from "../Cesium3DTilesInspector/Cesium3DTilesInspe
* A mixin which adds the {@link Cesium3DTilesInspector} widget to the {@link Viewer} widget.
* Rather than being called directly, this function is normally passed as
* a parameter to {@link Viewer#extend}, as shown in the example below.
- * @exports viewerCesium3DTilesInspectorMixin
+ * @function
*
* @param {Viewer} viewer The viewer instance.
*
diff --git a/Source/Widgets/Viewer/viewerCesiumInspectorMixin.js b/Source/Widgets/Viewer/viewerCesiumInspectorMixin.js
index a7413fb3c225..de8518f1c60f 100644
--- a/Source/Widgets/Viewer/viewerCesiumInspectorMixin.js
+++ b/Source/Widgets/Viewer/viewerCesiumInspectorMixin.js
@@ -6,7 +6,7 @@ import CesiumInspector from "../CesiumInspector/CesiumInspector.js";
* A mixin which adds the CesiumInspector widget to the Viewer widget.
* Rather than being called directly, this function is normally passed as
* a parameter to {@link Viewer#extend}, as shown in the example below.
- * @exports viewerCesiumInspectorMixin
+ * @function
*
* @param {Viewer} viewer The viewer instance.
*
diff --git a/Source/Widgets/Viewer/viewerDragDropMixin.js b/Source/Widgets/Viewer/viewerDragDropMixin.js
index d111f7cdef42..5130fb1e164c 100644
--- a/Source/Widgets/Viewer/viewerDragDropMixin.js
+++ b/Source/Widgets/Viewer/viewerDragDropMixin.js
@@ -12,15 +12,15 @@ import getElement from "../getElement.js";
* A mixin which adds default drag and drop support for CZML files to the Viewer widget.
* Rather than being called directly, this function is normally passed as
* a parameter to {@link Viewer#extend}, as shown in the example below.
- * @exports viewerDragDropMixin
- * @namespace
+ * @function viewerDragDropMixin
+
* @param {Viewer} viewer The viewer instance.
* @param {Object} [options] Object with the following properties:
* @param {Element|String} [options.dropTarget=viewer.container] The DOM element which will serve as the drop target.
* @param {Boolean} [options.clearOnDrop=true] When true, dropping files will clear all existing data sources first, when false, new data sources will be loaded after the existing ones.
* @param {Boolean} [options.flyToOnDrop=true] When true, dropping files will fly to the data source once it is loaded.
* @param {Boolean} [options.clampToGround=true] When true, datasources are clamped to the ground.
- * @param {DefaultProxy} [options.proxy] The proxy to be used for KML network links.
+ * @param {Proxy} [options.proxy] The proxy to be used for KML network links.
*
* @exception {DeveloperError} Element with id does not exist in the document.
* @exception {DeveloperError} dropTarget is already defined by another mixin.
@@ -164,7 +164,7 @@ function viewerDragDropMixin(viewer, options) {
/**
* Gets or sets the proxy to be used for KML.
* @memberof viewerDragDropMixin.prototype
- * @type {DefaultProxy}
+ * @type {Proxy}
*/
proxy: {
get: function () {
diff --git a/Source/Widgets/Viewer/viewerPerformanceWatchdogMixin.js b/Source/Widgets/Viewer/viewerPerformanceWatchdogMixin.js
index 589277ad44e6..c0cbb78c517c 100644
--- a/Source/Widgets/Viewer/viewerPerformanceWatchdogMixin.js
+++ b/Source/Widgets/Viewer/viewerPerformanceWatchdogMixin.js
@@ -7,7 +7,7 @@ import PerformanceWatchdog from "../PerformanceWatchdog/PerformanceWatchdog.js";
* A mixin which adds the {@link PerformanceWatchdog} widget to the {@link Viewer} widget.
* Rather than being called directly, this function is normally passed as
* a parameter to {@link Viewer#extend}, as shown in the example below.
- * @exports viewerPerformanceWatchdogMixin
+ * @function
*
* @param {Viewer} viewer The viewer instance.
* @param {Object} [options] An object with properties.
diff --git a/Source/Widgets/createCommand.js b/Source/Widgets/createCommand.js
index 88a0aec3a735..27e761f234fd 100644
--- a/Source/Widgets/createCommand.js
+++ b/Source/Widgets/createCommand.js
@@ -12,7 +12,7 @@ import knockout from "../ThirdParty/knockout.js";
* value of canExecute
and throw if false. It also provides events for when
* a command has been or is about to be executed.
*
- * @exports createCommand
+ * @function
*
* @param {Function} func The function to execute.
* @param {Boolean} [canExecute=true] A boolean indicating whether the function can currently be executed.
diff --git a/Source/Widgets/subscribeAndEvaluate.js b/Source/Widgets/subscribeAndEvaluate.js
index 700240f76b12..768829eef8b7 100644
--- a/Source/Widgets/subscribeAndEvaluate.js
+++ b/Source/Widgets/subscribeAndEvaluate.js
@@ -6,7 +6,7 @@ import knockout from "../ThirdParty/knockout.js";
*
* @private
*
- * @exports subscribeAndEvaluate
+ * @function subscribeAndEvaluate
*
* @param {Object} owner The object containing the observable property.
* @param {String} observablePropertyName The name of the observable property.
diff --git a/Source/WorkersES6/createTaskProcessorWorker.js b/Source/WorkersES6/createTaskProcessorWorker.js
index 55a699a3012c..2b6f49308d8d 100644
--- a/Source/WorkersES6/createTaskProcessorWorker.js
+++ b/Source/WorkersES6/createTaskProcessorWorker.js
@@ -21,11 +21,11 @@ function callAndWrap(workerFunction, parameters, transferableObjects) {
* Creates an adapter function to allow a calculation function to operate as a Web Worker,
* paired with TaskProcessor, to receive tasks and return results.
*
- * @exports createTaskProcessorWorker
+ * @function createTaskProcessorWorker
*
- * @param {createTaskProcessorWorker~WorkerFunction} workerFunction The calculation function,
+ * @param {createTaskProcessorWorker.WorkerFunction} workerFunction The calculation function,
* which takes parameters and returns a result.
- * @returns {createTaskProcessorWorker~TaskProcessorWorkerFunction} A function that adapts the
+ * @returns {createTaskProcessorWorker.TaskProcessorWorkerFunction} A function that adapts the
* calculation function to work as a Web Worker onmessage listener with TaskProcessor.
*
*
@@ -101,7 +101,7 @@ function createTaskProcessorWorker(workerFunction) {
/**
* A function that performs a calculation in a Web Worker.
- * @callback createTaskProcessorWorker~WorkerFunction
+ * @callback createTaskProcessorWorker.WorkerFunction
*
* @param {Object} parameters Parameters to the calculation.
* @param {Array} transferableObjects An array that should be filled with references to objects inside
@@ -125,7 +125,7 @@ function createTaskProcessorWorker(workerFunction) {
/**
* A Web Worker message event handler function that handles the interaction with TaskProcessor,
* specifically, task ID management and posting a response message containing the result.
- * @callback createTaskProcessorWorker~TaskProcessorWorkerFunction
+ * @callback createTaskProcessorWorker.TaskProcessorWorkerFunction
*
* @param {Object} event The onmessage event object.
*/
diff --git a/Specs/Core/Cartesian2Spec.js b/Specs/Core/Cartesian2Spec.js
index 95d5d2c573f3..591d66f99f5d 100644
--- a/Specs/Core/Cartesian2Spec.js
+++ b/Specs/Core/Cartesian2Spec.js
@@ -860,12 +860,6 @@ describe("Core/Cartesian2", function () {
}).toThrowDeveloperError();
});
- it("equalsEpsilon throws with no epsilon", function () {
- expect(function () {
- Cartesian2.equalsEpsilon(new Cartesian2(), new Cartesian2(), undefined);
- }).toThrowDeveloperError();
- });
-
it("fromElements returns a cartesian2 with corrrect coordinates", function () {
var cartesian2 = Cartesian2.fromElements(2, 2);
var expectedResult = new Cartesian2(2, 2);
diff --git a/Specs/Core/Cartesian3Spec.js b/Specs/Core/Cartesian3Spec.js
index b00b85e7e4f0..338e05fa27e1 100644
--- a/Specs/Core/Cartesian3Spec.js
+++ b/Specs/Core/Cartesian3Spec.js
@@ -1031,12 +1031,6 @@ describe("Core/Cartesian3", function () {
}).toThrowDeveloperError();
});
- it("equalsEpsilon throws with no epsilon", function () {
- expect(function () {
- Cartesian3.equalsEpsilon(new Cartesian3(), new Cartesian3(), undefined);
- }).toThrowDeveloperError();
- });
-
it("cross throw with no left paramater", function () {
var right = new Cartesian3(4, 3, 6);
expect(function () {
diff --git a/Specs/Core/Cartesian4Spec.js b/Specs/Core/Cartesian4Spec.js
index f153832e553f..813007d128e0 100644
--- a/Specs/Core/Cartesian4Spec.js
+++ b/Specs/Core/Cartesian4Spec.js
@@ -1011,12 +1011,6 @@ describe("Core/Cartesian4", function () {
}).toThrowDeveloperError();
});
- it("equalsEpsilon throws with no epsilon", function () {
- expect(function () {
- Cartesian4.equalsEpsilon(new Cartesian4(), new Cartesian4(), undefined);
- }).toThrowDeveloperError();
- });
-
it("minimumByComponent throws with no result", function () {
expect(function () {
Cartesian4.minimumByComponent(new Cartesian4(), new Cartesian4());
diff --git a/Specs/Core/CartographicSpec.js b/Specs/Core/CartographicSpec.js
index 8c662bde0cf0..358907e22867 100644
--- a/Specs/Core/CartographicSpec.js
+++ b/Specs/Core/CartographicSpec.js
@@ -216,10 +216,4 @@ describe("Core/Cartographic", function () {
it("clone returns undefined without cartographic parameter", function () {
expect(Cartographic.clone(undefined)).toBeUndefined();
});
-
- it("equalsEpsilon throws without numeric epsilon", function () {
- expect(function () {
- Cartographic.equalsEpsilon(new Cartographic(), new Cartographic(), {});
- }).toThrowDeveloperError();
- });
});
diff --git a/Specs/Core/ColorSpec.js b/Specs/Core/ColorSpec.js
index ba0a0cf21171..911d06b12e01 100644
--- a/Specs/Core/ColorSpec.js
+++ b/Specs/Core/ColorSpec.js
@@ -184,7 +184,19 @@ describe("Core/Color", function () {
expect(Color.fromCssColorString("#00F")).toEqual(Color.BLUE);
});
- it("fromCssColorString supports the #rrggbb", function () {
+ it("fromCssColorString supports the #rgba format", function () {
+ expect(Color.fromCssColorString("#369c")).toEqual(
+ new Color(0.2, 0.4, 0.6, 0.8)
+ );
+ });
+
+ it("fromCssColorString supports the #rgba format with uppercase", function () {
+ expect(Color.fromCssColorString("#369C")).toEqual(
+ new Color(0.2, 0.4, 0.6, 0.8)
+ );
+ });
+
+ it("fromCssColorString supports the #rrggbb format", function () {
expect(Color.fromCssColorString("#336699")).toEqual(
new Color(0.2, 0.4, 0.6, 1.0)
);
@@ -202,6 +214,18 @@ describe("Core/Color", function () {
expect(Color.fromCssColorString("#0000FF")).toEqual(Color.BLUE);
});
+ it("fromCssColorString supports the #rrggbbaa format", function () {
+ expect(Color.fromCssColorString("#336699cc")).toEqual(
+ new Color(0.2, 0.4, 0.6, 0.8)
+ );
+ });
+
+ it("fromCssColorString supports the #rrggbbaa format with uppercase", function () {
+ expect(Color.fromCssColorString("#336699CC")).toEqual(
+ new Color(0.2, 0.4, 0.6, 0.8)
+ );
+ });
+
it("fromCssColorString supports the rgb() format with absolute values", function () {
expect(Color.fromCssColorString("rgb(255, 0, 0)")).toEqual(Color.RED);
expect(Color.fromCssColorString("rgb(0, 255, 0)")).toEqual(Color.LIME);
diff --git a/Specs/Core/MathSpec.js b/Specs/Core/MathSpec.js
index 7c38c87ac2e8..d065817d3afd 100644
--- a/Specs/Core/MathSpec.js
+++ b/Specs/Core/MathSpec.js
@@ -339,12 +339,6 @@ describe("Core/Math", function () {
}).toThrowDeveloperError();
});
- it("equalsEpsilon throws for undefined relativeEpsilon", function () {
- expect(function () {
- CesiumMath.equalsEpsilon(1.0, 5.0, undefined);
- }).toThrowDeveloperError();
- });
-
it("equalsEpsilon throws for undefined", function () {
expect(function () {
CesiumMath.equalsEpsilon();
diff --git a/Specs/Core/Matrix2Spec.js b/Specs/Core/Matrix2Spec.js
index 975b25d1c4a2..d1f9666e0b31 100644
--- a/Specs/Core/Matrix2Spec.js
+++ b/Specs/Core/Matrix2Spec.js
@@ -740,12 +740,6 @@ describe("Core/Matrix2", function () {
}).toThrowDeveloperError();
});
- it("equalsEpsilon throws with non-number parameter", function () {
- expect(function () {
- Matrix2.equalsEpsilon(new Matrix2(), new Matrix2(), {});
- }).toThrowDeveloperError();
- });
-
it("getColumn throws without result parameter", function () {
expect(function () {
Matrix2.getColumn(new Matrix2(), 1);
diff --git a/Specs/Core/Matrix3Spec.js b/Specs/Core/Matrix3Spec.js
index b6dc75eafcdd..bfd75f43f763 100644
--- a/Specs/Core/Matrix3Spec.js
+++ b/Specs/Core/Matrix3Spec.js
@@ -1373,12 +1373,6 @@ describe("Core/Matrix3", function () {
}).toThrowDeveloperError();
});
- it("equalsEpsilon throws with non-number parameter", function () {
- expect(function () {
- Matrix3.equalsEpsilon(new Matrix3(), new Matrix3(), {});
- }).toThrowDeveloperError();
- });
-
it("getColumn throws without result parameter", function () {
expect(function () {
Matrix3.getColumn(new Matrix3(), 2);
diff --git a/Specs/Core/Matrix4Spec.js b/Specs/Core/Matrix4Spec.js
index da2c3e55af50..6fad177a2d8d 100644
--- a/Specs/Core/Matrix4Spec.js
+++ b/Specs/Core/Matrix4Spec.js
@@ -4306,12 +4306,6 @@ describe("Core/Matrix4", function () {
}).toThrowDeveloperError();
});
- it("equalsEpsilon throws with non-number parameter", function () {
- expect(function () {
- Matrix4.equalsEpsilon(new Matrix4(), new Matrix4(), {});
- }).toThrowDeveloperError();
- });
-
it("getTranslation throws without matrix parameter", function () {
expect(function () {
Matrix4.getTranslation(undefined);
@@ -4566,21 +4560,6 @@ describe("Core/Matrix4", function () {
}).toThrowDeveloperError();
});
- it("computeViewportTransformation works", function () {
- expect(function () {
- Matrix4.computeViewportTransformation(
- {
- x: 0,
- y: 0,
- width: 4.0,
- height: 6.0,
- },
- 0.0,
- 2.0
- );
- }).toThrowDeveloperError();
- });
-
it("Matrix4 objects can be used as array like objects", function () {
var matrix = new Matrix4(
1,
diff --git a/Specs/Core/PixelFormatSpec.js b/Specs/Core/PixelFormatSpec.js
new file mode 100644
index 000000000000..1c9e7ebb0c51
--- /dev/null
+++ b/Specs/Core/PixelFormatSpec.js
@@ -0,0 +1,38 @@
+import { PixelDatatype } from "../../Source/Cesium.js";
+import { PixelFormat } from "../../Source/Cesium.js";
+
+describe("Core/PixelFormat", function () {
+ it("flipY works", function () {
+ var width = 1;
+ var height = 2;
+ var values = [255, 0, 0, 0, 255, 0];
+ var expectedValues = [0, 255, 0, 255, 0, 0];
+ var dataBuffer = new Uint8Array(values);
+ var expectedDataBuffer = new Uint8Array(expectedValues);
+
+ var flipped = PixelFormat.flipY(
+ dataBuffer,
+ PixelFormat.RGB,
+ PixelDatatype.UNSIGNED_BYTE,
+ width,
+ height
+ );
+ expect(flipped).toEqual(expectedDataBuffer);
+ });
+
+ it("flipY returns early if height is 1", function () {
+ var width = 1;
+ var height = 1;
+ var values = [255, 255, 255];
+ var dataBuffer = new Uint8Array(values);
+
+ var flipped = PixelFormat.flipY(
+ dataBuffer,
+ PixelFormat.RGB,
+ PixelDatatype.UNSIGNED_BYTE,
+ width,
+ height
+ );
+ expect(flipped).toBe(dataBuffer);
+ });
+});
diff --git a/Specs/Core/QuaternionSpec.js b/Specs/Core/QuaternionSpec.js
index 45ec1c8d2d69..d330f5905009 100644
--- a/Specs/Core/QuaternionSpec.js
+++ b/Specs/Core/QuaternionSpec.js
@@ -1152,12 +1152,6 @@ describe("Core/Quaternion", function () {
}).toThrowDeveloperError();
});
- it("equalsEpsilon throws with no epsilon", function () {
- expect(function () {
- Quaternion.equalsEpsilon(new Quaternion(), new Quaternion(), undefined);
- }).toThrowDeveloperError();
- });
-
it("conjugate throws with no result", function () {
expect(function () {
Quaternion.conjugate(new Quaternion());
diff --git a/Specs/Core/RectangleSpec.js b/Specs/Core/RectangleSpec.js
index 4b18f74f707a..36db8a65726d 100644
--- a/Specs/Core/RectangleSpec.js
+++ b/Specs/Core/RectangleSpec.js
@@ -1014,14 +1014,6 @@ describe("Core/Rectangle", function () {
}).toThrowDeveloperError();
});
- it("equalsEpsilon throws with no epsilon", function () {
- var rectangle = new Rectangle(west, south, east, north);
- var other = new Rectangle();
- expect(function () {
- rectangle.equalsEpsilon(other, undefined);
- }).toThrowDeveloperError();
- });
-
it("intersection throws with no rectangle", function () {
expect(function () {
Rectangle.intersection(undefined);
diff --git a/Specs/Core/ResourceSpec.js b/Specs/Core/ResourceSpec.js
index 10310b831ef4..5c971aa08381 100644
--- a/Specs/Core/ResourceSpec.js
+++ b/Specs/Core/ResourceSpec.js
@@ -59,6 +59,9 @@ describe("Core/Resource", function () {
expect(resource.url).toEqual(
proxy.getURL("http://test.com/tileset?key1=value1&key2=value2")
);
+ expect(String(resource)).toEqual(
+ proxy.getURL("http://test.com/tileset?key1=value1&key2=value2")
+ );
expect(resource.queryParameters).toEqual({
key1: "value1",
key2: "value2",
@@ -81,6 +84,7 @@ describe("Core/Resource", function () {
var url = "http://invalid.domain.com/tileset";
var resource = new Resource(url);
expect(resource.url).toEqual(url);
+ expect(String(resource)).toEqual(url);
expect(resource.queryParameters).toEqual({});
expect(resource.templateValues).toEqual({});
expect(resource.headers).toEqual({});
diff --git a/Specs/Core/TimeIntervalSpec.js b/Specs/Core/TimeIntervalSpec.js
index 2ada0a768700..2de525dc7623 100644
--- a/Specs/Core/TimeIntervalSpec.js
+++ b/Specs/Core/TimeIntervalSpec.js
@@ -633,14 +633,6 @@ describe("Core/TimeInterval", function () {
}).toThrowDeveloperError();
});
- it("equalsEpsilon throws without epsilon.", function () {
- var left = new TimeInterval();
- var right = new TimeInterval();
- expect(function () {
- TimeInterval.equalsEpsilon(left, right, undefined);
- }).toThrowDeveloperError();
- });
-
it("intersect throws without left.", function () {
var right = new TimeInterval();
var result = new TimeInterval();
@@ -649,14 +641,6 @@ describe("Core/TimeInterval", function () {
}).toThrowDeveloperError();
});
- it("intersect throws without result.", function () {
- var left = new TimeInterval();
- var right = new TimeInterval();
- expect(function () {
- TimeInterval.intersect(left, right, undefined);
- }).toThrowDeveloperError();
- });
-
it("contains throws without interval.", function () {
var date = new JulianDate();
expect(function () {
diff --git a/Specs/Core/TransformsSpec.js b/Specs/Core/TransformsSpec.js
index fdcb883fb128..7abad2f543dd 100644
--- a/Specs/Core/TransformsSpec.js
+++ b/Specs/Core/TransformsSpec.js
@@ -1716,6 +1716,59 @@ describe("Core/Transforms", function () {
expect(returnedResult).toEqualEpsilon(expected, CesiumMath.EPSILON12);
});
+ it("rotationMatrixFromPositionVelocity works without a result parameter", function () {
+ var matrix = Transforms.rotationMatrixFromPositionVelocity(
+ Cartesian3.UNIT_X,
+ Cartesian3.UNIT_Y
+ );
+ var expected = new Matrix3(0, 0, 1, 1, 0, 0, 0, 1, 0);
+ expect(matrix).toEqualEpsilon(expected, CesiumMath.EPSILON14);
+
+ matrix = Transforms.rotationMatrixFromPositionVelocity(
+ Cartesian3.UNIT_X,
+ Cartesian3.UNIT_Z
+ );
+ expected = new Matrix3(0, 0, 1, 0, -1, 0, 1, 0, 0);
+ expect(matrix).toEqualEpsilon(expected, CesiumMath.EPSILON14);
+
+ matrix = Transforms.rotationMatrixFromPositionVelocity(
+ Cartesian3.UNIT_Y,
+ Cartesian3.UNIT_Z
+ );
+ expected = new Matrix3(0, 1, 0, 0, 0, 1, 1, 0, 0);
+ expect(matrix).toEqualEpsilon(expected, CesiumMath.EPSILON14);
+ });
+
+ it("rotationMatrixFromPositionVelocity works with a result parameter", function () {
+ var result = new Matrix3();
+ Transforms.rotationMatrixFromPositionVelocity(
+ Cartesian3.UNIT_X,
+ Cartesian3.UNIT_Y,
+ Ellipsoid.WGS84,
+ result
+ );
+ var expected = new Matrix3(0, 0, 1, 1, 0, 0, 0, 1, 0);
+ expect(result).toEqualEpsilon(expected, CesiumMath.EPSILON14);
+
+ Transforms.rotationMatrixFromPositionVelocity(
+ Cartesian3.UNIT_X,
+ Cartesian3.UNIT_Z,
+ Ellipsoid.WGS84,
+ result
+ );
+ expected = new Matrix3(0, 0, 1, 0, -1, 0, 1, 0, 0);
+ expect(result).toEqualEpsilon(expected, CesiumMath.EPSILON14);
+
+ Transforms.rotationMatrixFromPositionVelocity(
+ Cartesian3.UNIT_Y,
+ Cartesian3.UNIT_Z,
+ Ellipsoid.WGS84,
+ result
+ );
+ expected = new Matrix3(0, 1, 0, 0, 0, 1, 1, 0, 0);
+ expect(result).toEqualEpsilon(expected, CesiumMath.EPSILON14);
+ });
+
it("basisTo2D projects translation", function () {
var ellipsoid = Ellipsoid.WGS84;
var projection = new GeographicProjection(ellipsoid);
diff --git a/Specs/Core/buildModuleUrlSpec.js b/Specs/Core/buildModuleUrlSpec.js
index 73f23163f133..ef480b38dae4 100644
--- a/Specs/Core/buildModuleUrlSpec.js
+++ b/Specs/Core/buildModuleUrlSpec.js
@@ -17,12 +17,25 @@ describe("Core/buildModuleUrl", function () {
var r = buildModuleUrl._cesiumScriptRegex;
expect(r.exec("Cesium.js")[1]).toEqual("");
+ expect(r.exec("Cesium.js?v=1.7")[1]).toEqual("");
expect(r.exec("assets/foo/Cesium.js")[1]).toEqual("assets/foo/");
+ expect(r.exec("assets/foo/Cesium.js?v=1.7")[1]).toEqual("assets/foo/");
expect(
r.exec("http://example.invalid/Cesium/assets/foo/Cesium.js")[1]
).toEqual("http://example.invalid/Cesium/assets/foo/");
+ expect(
+ r.exec("http://example.invalid/Cesium/assets/foo/Cesium.js?v=1.7")[1]
+ ).toEqual("http://example.invalid/Cesium/assets/foo/");
+ expect(r.exec("cesium.js")).toBeNull();
+ expect(r.exec("Cesium.js%20")).toBeNull();
+ expect(r.exec("Cesium.min.js")).toBeNull();
+ expect(r.exec("CesiumSomething.js")).toBeNull();
+ expect(r.exec("CesiumSomething.js?v=1.7")).toBeNull();
expect(r.exec("assets/foo/bar.cesium.js")).toBeNull();
+ expect(r.exec("assets/foo/bar.cesium.js?v=1.7")).toBeNull();
+ expect(r.exec("assets/foo/CesiumSomething.js")).toBeNull();
+ expect(r.exec("assets/foo/CesiumSomething.js?v=1.7")).toBeNull();
});
it("CESIUM_BASE_URL works with trailing slash", function () {
diff --git a/Specs/Data/Cesium3DTiles/PointCloud/PointCloudWithUnicodePropertyNames/pointCloudWithUnicodePropertyNames.pnts b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudWithUnicodePropertyNames/pointCloudWithUnicodePropertyNames.pnts
new file mode 100644
index 000000000000..10038a2586de
Binary files /dev/null and b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudWithUnicodePropertyNames/pointCloudWithUnicodePropertyNames.pnts differ
diff --git a/Specs/Data/Cesium3DTiles/PointCloud/PointCloudWithUnicodePropertyNames/tileset.json b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudWithUnicodePropertyNames/tileset.json
new file mode 100644
index 000000000000..02bdf5115813
--- /dev/null
+++ b/Specs/Data/Cesium3DTiles/PointCloud/PointCloudWithUnicodePropertyNames/tileset.json
@@ -0,0 +1,40 @@
+{
+ "asset": {
+ "version": "1.0"
+ },
+ "extensions": {},
+ "geometricError": 17.32,
+ "root": {
+ "transform": [
+ 0.968635634376879,
+ 0.24848542777253735,
+ 0,
+ 0,
+ -0.15986460794399626,
+ 0.6231776137472074,
+ 0.7655670897127491,
+ 0,
+ 0.190232265775849,
+ -0.7415555636019701,
+ 0.6433560687121489,
+ 0,
+ 1215012.8828876738,
+ -4736313.051199594,
+ 4081605.22126042,
+ 1
+ ],
+ "refine": "ADD",
+ "boundingVolume": {
+ "sphere": [
+ 0,
+ 0,
+ 0,
+ 5
+ ]
+ },
+ "geometricError": 0,
+ "content": {
+ "uri": "pointCloudWithUnicodePropertyNames.pnts"
+ }
+ }
+}
diff --git a/Specs/MockTerrainProvider.js b/Specs/MockTerrainProvider.js
index c44d2d4d0471..3688a8b39663 100644
--- a/Specs/MockTerrainProvider.js
+++ b/Specs/MockTerrainProvider.js
@@ -16,6 +16,7 @@ function MockTerrainProvider() {
this.tilingScheme.getNumberOfXTilesAtLevel(0)
);
this.ready = true;
+ this.readyPromise = when.resolve();
this.hasWaterMask = true;
this._tileDataAvailable = {};
diff --git a/Specs/Renderer/AutomaticUniformSpec.js b/Specs/Renderer/AutomaticUniformSpec.js
index c795dbba7ae3..c7cea212aae4 100644
--- a/Specs/Renderer/AutomaticUniformSpec.js
+++ b/Specs/Renderer/AutomaticUniformSpec.js
@@ -1,5 +1,6 @@
import { Cartesian2 } from "../../Source/Cesium.js";
import { Cartesian3 } from "../../Source/Cesium.js";
+import { Cartographic } from "../../Source/Cesium.js";
import { Color } from "../../Source/Cesium.js";
import { defaultValue } from "../../Source/Cesium.js";
import { DirectionalLight } from "../../Source/Cesium.js";
@@ -73,6 +74,7 @@ describe(
),
rightWC: defaultValue(right, Cartesian3.clone(Cartesian3.UNIT_X)),
upWC: defaultValue(up, Cartesian3.clone(Cartesian3.UNIT_Y)),
+ positionCartographic: new Cartographic(0.0, 0.0, 10.0),
};
}
@@ -1945,6 +1947,20 @@ describe(
}).contextToRender();
});
+ it("has czm_eyeHeight", function () {
+ var frameState = createFrameState(context, createMockCamera());
+ context.uniformState.update(frameState);
+
+ var fs =
+ "void main() { " +
+ " gl_FragColor = vec4(czm_eyeHeight == 10.0); " +
+ "}";
+ expect({
+ context: context,
+ fragmentShader: fs,
+ }).contextToRender();
+ });
+
it("has czm_eyeHeight2D == 0,0 in Scene3D", function () {
var fs =
"void main() { " +
diff --git a/Specs/Scene/CameraSpec.js b/Specs/Scene/CameraSpec.js
index 34f1c857c97f..7dcb39f01bc4 100644
--- a/Specs/Scene/CameraSpec.js
+++ b/Specs/Scene/CameraSpec.js
@@ -3494,6 +3494,7 @@ describe("Scene/Camera", function () {
startObject: {},
stopObject: {},
duration: 0.001,
+ complete: jasmine.createSpy("complete"),
cancelTween: jasmine.createSpy("cancelTween"),
});
@@ -3509,9 +3510,43 @@ describe("Scene/Camera", function () {
camera.cancelFlight();
expect(createdTween.cancelTween).toHaveBeenCalled();
+ expect(createdTween.complete).not.toHaveBeenCalled();
expect(camera._currentFlight).toBeUndefined();
});
+ it("can complete a flight", function () {
+ spyOn(CameraFlightPath, "createTween").and.returnValue({
+ startObject: {},
+ stopObject: {},
+ duration: 0.001,
+ complete: jasmine.createSpy("complete"),
+ cancelTween: jasmine.createSpy("cancelTween"),
+ });
+
+ spyOn(camera, "setView");
+
+ var options = {
+ destination: Cartesian3.fromDegrees(-117.16, 32.71, 15000.0),
+ orientation: {
+ heading: 1,
+ pitch: 2,
+ roll: 3,
+ },
+ };
+ camera.flyTo(options);
+
+ expect(camera._currentFlight).toBeDefined();
+
+ var createdTween = camera._currentFlight;
+ spyOn(createdTween, "cancelTween");
+ camera.completeFlight();
+
+ expect(createdTween.cancelTween).toHaveBeenCalled();
+ expect(createdTween.complete).toHaveBeenCalled();
+ expect(camera._currentFlight).toBeUndefined();
+ expect(camera.setView).toHaveBeenCalledWith(options);
+ });
+
it("flyTo with heading, pitch and roll", function () {
scene.mode = SceneMode.SCENE3D;
diff --git a/Specs/Scene/Cesium3DTileStyleSpec.js b/Specs/Scene/Cesium3DTileStyleSpec.js
index 585dabf29891..67375afa1da3 100644
--- a/Specs/Scene/Cesium3DTileStyleSpec.js
+++ b/Specs/Scene/Cesium3DTileStyleSpec.js
@@ -4121,11 +4121,11 @@ describe("Scene/Cesium3DTileStyle", function () {
// The default color style is white, the default show style is true, and the default pointSize is 1.0,
// but the generated generated shader functions should just be undefined. We don't want all the points to be white.
var style = new Cesium3DTileStyle({});
- var colorFunction = style.getColorShaderFunction("getColor", "", {});
- var showFunction = style.getShowShaderFunction("getShow", "", {});
+ var colorFunction = style.getColorShaderFunction("getColor", {}, {});
+ var showFunction = style.getShowShaderFunction("getShow", {}, {});
var pointSizeFunction = style.getPointSizeShaderFunction(
"getPointSize",
- "",
+ {},
{}
);
expect(colorFunction).toBeUndefined();
diff --git a/Specs/Scene/ConditionsExpressionSpec.js b/Specs/Scene/ConditionsExpressionSpec.js
index 3a7cdca7c9d6..5b648895ac92 100644
--- a/Specs/Scene/ConditionsExpressionSpec.js
+++ b/Specs/Scene/ConditionsExpressionSpec.js
@@ -95,20 +95,23 @@ describe("Scene/ConditionsExpression", function () {
it("gets shader function", function () {
var expression = new ConditionsExpression(jsonExp);
+ var properyNameMap = {
+ Height: "a_height",
+ };
var shaderFunction = expression.getShaderFunction(
"getColor",
- "",
+ properyNameMap,
{},
"vec4"
);
var expected =
"vec4 getColor() \n" +
"{ \n" +
- " if ((Height > 100.0)) \n" +
+ " if ((a_height > 100.0)) \n" +
" { \n" +
" return vec4(vec3(0.0, 0.0, 1.0), 1.0); \n" +
" } \n" +
- " else if ((Height > 50.0)) \n" +
+ " else if ((a_height > 50.0)) \n" +
" { \n" +
" return vec4(vec3(1.0, 0.0, 0.0), 1.0); \n" +
" } \n" +
@@ -125,7 +128,7 @@ describe("Scene/ConditionsExpression", function () {
var expression = new ConditionsExpression([]);
var shaderFunction = expression.getShaderFunction(
"getColor",
- "",
+ {},
{},
"vec4"
);
diff --git a/Specs/Scene/DebugCameraPrimitiveSpec.js b/Specs/Scene/DebugCameraPrimitiveSpec.js
index 661473f20d0c..8c81ed2707bc 100644
--- a/Specs/Scene/DebugCameraPrimitiveSpec.js
+++ b/Specs/Scene/DebugCameraPrimitiveSpec.js
@@ -55,6 +55,7 @@ describe(
it("constructs with options", function () {
var p = new DebugCameraPrimitive({
camera: camera,
+ frustumSplits: [0.1, 1000.0],
color: Color.YELLOW,
updateOnChange: false,
show: false,
diff --git a/Specs/Scene/ExpressionSpec.js b/Specs/Scene/ExpressionSpec.js
index f603d03ebbf0..ef1cabe1ff2a 100644
--- a/Specs/Scene/ExpressionSpec.js
+++ b/Specs/Scene/ExpressionSpec.js
@@ -3417,7 +3417,7 @@ describe("Scene/Expression", function () {
var expression = new Expression("true");
var shaderFunction = expression.getShaderFunction(
"getShow",
- "",
+ {},
{},
"bool"
);
@@ -3428,169 +3428,194 @@ describe("Scene/Expression", function () {
it("gets shader expression for variable", function () {
var expression = new Expression("${property}");
- var shaderExpression = expression.getShaderExpression("prefix_", {});
- var expected = "prefix_property";
+ var propertyNameMap = {
+ property: "a_property",
+ };
+ var shaderExpression = expression.getShaderExpression(propertyNameMap, {});
+ var expected = "a_property";
+ expect(shaderExpression).toEqual(expected);
+ });
+
+ it("gets shader expression for feature variable with bracket notation", function () {
+ var expression = new Expression("${feature['property']}");
+ var propertyNameMap = {
+ property: "a_property",
+ };
+ var shaderExpression = expression.getShaderExpression(propertyNameMap, {});
+ var expected = "a_property";
+ expect(shaderExpression).toEqual(expected);
+ });
+
+ it("gets shader expression for feature variable with dot notation", function () {
+ var expression = new Expression("${feature.property}");
+ var propertyNameMap = {
+ property: "a_property",
+ };
+ var shaderExpression = expression.getShaderExpression(propertyNameMap, {});
+ var expected = "a_property";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for unary not", function () {
var expression = new Expression("!true");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "!true";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for unary negative", function () {
var expression = new Expression("-5.0");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "-5.0";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for unary positive", function () {
var expression = new Expression("+5.0");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "+5.0";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for converting to literal boolean", function () {
var expression = new Expression("Boolean(1.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "bool(1.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for converting to literal number", function () {
var expression = new Expression("Number(true)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "float(true)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for binary addition", function () {
var expression = new Expression("1.0 + 2.0");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "(1.0 + 2.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for binary subtraction", function () {
var expression = new Expression("1.0 - 2.0");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "(1.0 - 2.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for binary multiplication", function () {
var expression = new Expression("1.0 * 2.0");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "(1.0 * 2.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for binary division", function () {
var expression = new Expression("1.0 / 2.0");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "(1.0 / 2.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for binary modulus", function () {
var expression = new Expression("1.0 % 2.0");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "mod(1.0, 2.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for binary equals strict", function () {
var expression = new Expression("1.0 === 2.0");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "(1.0 == 2.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for binary not equals strict", function () {
var expression = new Expression("1.0 !== 2.0");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "(1.0 != 2.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for binary less than", function () {
var expression = new Expression("1.0 < 2.0");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "(1.0 < 2.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for binary less than or equals", function () {
var expression = new Expression("1.0 <= 2.0");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "(1.0 <= 2.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for binary greater than", function () {
var expression = new Expression("1.0 > 2.0");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "(1.0 > 2.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for binary greater than or equals", function () {
var expression = new Expression("1.0 >= 2.0");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "(1.0 >= 2.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for logical and", function () {
var expression = new Expression("true && false");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "(true && false)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for logical or", function () {
var expression = new Expression("true || false");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "(true || false)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for ternary conditional", function () {
var expression = new Expression("true ? 1.0 : 2.0");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "(true ? 1.0 : 2.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for array indexing", function () {
+ var propertyNameMap = { property: "property" };
+
var expression = new Expression("${property[0]}");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression(propertyNameMap, {});
var expected = "property[0]";
expect(shaderExpression).toEqual(expected);
expression = new Expression("${property[4 / 2]}");
- shaderExpression = expression.getShaderExpression("", {});
+ shaderExpression = expression.getShaderExpression(propertyNameMap, {});
expected = "property[int((4.0 / 2.0))]";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for array", function () {
var expression = new Expression("[1.0, 2.0]");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "vec2(1.0, 2.0)";
expect(shaderExpression).toEqual(expected);
expression = new Expression("[1.0, 2.0, 3.0]");
- shaderExpression = expression.getShaderExpression("", {});
+ shaderExpression = expression.getShaderExpression({}, {});
expected = "vec3(1.0, 2.0, 3.0)";
expect(shaderExpression).toEqual(expected);
expression = new Expression("[1.0, 2.0, 3.0, 4.0]");
- shaderExpression = expression.getShaderExpression("", {});
+ shaderExpression = expression.getShaderExpression({}, {});
expected = "vec4(1.0, 2.0, 3.0, 4.0)";
expect(shaderExpression).toEqual(expected);
});
@@ -3598,136 +3623,179 @@ describe("Scene/Expression", function () {
it("throws when getting shader expression for array of invalid length", function () {
var expression = new Expression("[]");
expect(function () {
- return expression.getShaderExpression("", {});
+ return expression.getShaderExpression({}, {});
}).toThrowRuntimeError();
expression = new Expression("[1.0]");
expect(function () {
- return expression.getShaderExpression("", {});
+ return expression.getShaderExpression({}, {});
}).toThrowRuntimeError();
expression = new Expression("[1.0, 2.0, 3.0, 4.0, 5.0]");
expect(function () {
- return expression.getShaderExpression("", {});
+ return expression.getShaderExpression({}, {});
}).toThrowRuntimeError();
});
it("gets shader expression for boolean", function () {
var expression = new Expression("true || false");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "(true || false)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for integer", function () {
var expression = new Expression("1");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "1.0";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for float", function () {
var expression = new Expression("1.02");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "1.02";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for color", function () {
+ var propertyNameMap = { property: "property" };
var shaderState = { translucent: false };
var expression = new Expression("color()");
- var shaderExpression = expression.getShaderExpression("", shaderState);
+ var shaderExpression = expression.getShaderExpression(
+ propertyNameMap,
+ shaderState
+ );
var expected = "vec4(1.0)";
expect(shaderExpression).toEqual(expected);
expect(shaderState.translucent).toBe(false);
shaderState = { translucent: false };
expression = new Expression('color("red")');
- shaderExpression = expression.getShaderExpression("", shaderState);
+ shaderExpression = expression.getShaderExpression(
+ propertyNameMap,
+ shaderState
+ );
expected = "vec4(vec3(1.0, 0.0, 0.0), 1.0)";
expect(shaderExpression).toEqual(expected);
expect(shaderState.translucent).toBe(false);
shaderState = { translucent: false };
expression = new Expression('color("#FFF")');
- shaderExpression = expression.getShaderExpression("", shaderState);
+ shaderExpression = expression.getShaderExpression(
+ propertyNameMap,
+ shaderState
+ );
expected = "vec4(vec3(1.0, 1.0, 1.0), 1.0)";
expect(shaderExpression).toEqual(expected);
expect(shaderState.translucent).toBe(false);
shaderState = { translucent: false };
expression = new Expression('color("#FF0000")');
- shaderExpression = expression.getShaderExpression("", shaderState);
+ shaderExpression = expression.getShaderExpression(
+ propertyNameMap,
+ shaderState
+ );
expected = "vec4(vec3(1.0, 0.0, 0.0), 1.0)";
expect(shaderExpression).toEqual(expected);
expect(shaderState.translucent).toBe(false);
shaderState = { translucent: false };
expression = new Expression('color("rgb(255, 0, 0)")');
- shaderExpression = expression.getShaderExpression("", shaderState);
+ shaderExpression = expression.getShaderExpression(
+ propertyNameMap,
+ shaderState
+ );
expected = "vec4(vec3(1.0, 0.0, 0.0), 1.0)";
expect(shaderExpression).toEqual(expected);
expect(shaderState.translucent).toBe(false);
shaderState = { translucent: false };
expression = new Expression('color("red", 0.5)');
- shaderExpression = expression.getShaderExpression("", shaderState);
+ shaderExpression = expression.getShaderExpression(
+ propertyNameMap,
+ shaderState
+ );
expected = "vec4(vec3(1.0, 0.0, 0.0), 0.5)";
expect(shaderExpression).toEqual(expected);
expect(shaderState.translucent).toBe(true);
shaderState = { translucent: false };
expression = new Expression("rgb(255, 0, 0)");
- shaderExpression = expression.getShaderExpression("", shaderState);
+ shaderExpression = expression.getShaderExpression(
+ propertyNameMap,
+ shaderState
+ );
expected = "vec4(1.0, 0.0, 0.0, 1.0)";
expect(shaderExpression).toEqual(expected);
expect(shaderState.translucent).toBe(false);
shaderState = { translucent: false };
expression = new Expression("rgb(255, ${property}, 0)");
- shaderExpression = expression.getShaderExpression("", shaderState);
+ shaderExpression = expression.getShaderExpression(
+ propertyNameMap,
+ shaderState
+ );
expected = "vec4(255.0 / 255.0, property / 255.0, 0.0 / 255.0, 1.0)";
expect(shaderExpression).toEqual(expected);
expect(shaderState.translucent).toBe(false);
shaderState = { translucent: false };
expression = new Expression("rgba(255, 0, 0, 0.5)");
- shaderExpression = expression.getShaderExpression("", shaderState);
+ shaderExpression = expression.getShaderExpression(
+ propertyNameMap,
+ shaderState
+ );
expected = "vec4(1.0, 0.0, 0.0, 0.5)";
expect(shaderExpression).toEqual(expected);
expect(shaderState.translucent).toBe(true);
shaderState = { translucent: false };
expression = new Expression("rgba(255, ${property}, 0, 0.5)");
- shaderExpression = expression.getShaderExpression("", shaderState);
+ shaderExpression = expression.getShaderExpression(
+ propertyNameMap,
+ shaderState
+ );
expected = "vec4(255.0 / 255.0, property / 255.0, 0.0 / 255.0, 0.5)";
expect(shaderExpression).toEqual(expected);
expect(shaderState.translucent).toBe(true);
shaderState = { translucent: false };
expression = new Expression("hsl(1.0, 0.5, 0.5)");
- shaderExpression = expression.getShaderExpression("", shaderState);
+ shaderExpression = expression.getShaderExpression(
+ propertyNameMap,
+ shaderState
+ );
expected = "vec4(0.75, 0.25, 0.25, 1.0)";
expect(shaderExpression).toEqual(expected);
expect(shaderState.translucent).toBe(false);
shaderState = { translucent: false };
expression = new Expression("hsla(1.0, 0.5, 0.5, 0.5)");
- shaderExpression = expression.getShaderExpression("", shaderState);
+ shaderExpression = expression.getShaderExpression(
+ propertyNameMap,
+ shaderState
+ );
expected = "vec4(0.75, 0.25, 0.25, 0.5)";
expect(shaderExpression).toEqual(expected);
expect(shaderState.translucent).toBe(true);
shaderState = { translucent: false };
expression = new Expression("hsl(1.0, ${property}, 0.5)");
- shaderExpression = expression.getShaderExpression("", shaderState);
+ shaderExpression = expression.getShaderExpression(
+ propertyNameMap,
+ shaderState
+ );
expected = "vec4(czm_HSLToRGB(vec3(1.0, property, 0.5)), 1.0)";
expect(shaderExpression).toEqual(expected);
expect(shaderState.translucent).toBe(false);
shaderState = { translucent: false };
expression = new Expression("hsla(1.0, ${property}, 0.5, 0.5)");
- shaderExpression = expression.getShaderExpression("", shaderState);
+ shaderExpression = expression.getShaderExpression(
+ propertyNameMap,
+ shaderState
+ );
expected = "vec4(czm_HSLToRGB(vec3(1.0, property, 0.5)), 0.5)";
expect(shaderExpression).toEqual(expected);
expect(shaderState.translucent).toBe(true);
@@ -3738,7 +3806,7 @@ describe("Scene/Expression", function () {
var expression = new Expression(
"color().r + color().g + color().b + color().a"
);
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected =
"(((vec4(1.0)[0] + vec4(1.0)[1]) + vec4(1.0)[2]) + vec4(1.0)[3])";
expect(shaderExpression).toEqual(expected);
@@ -3747,34 +3815,38 @@ describe("Scene/Expression", function () {
expression = new Expression(
"color().x + color().y + color().z + color().w"
);
- shaderExpression = expression.getShaderExpression("", {});
+ shaderExpression = expression.getShaderExpression({}, {});
expect(shaderExpression).toEqual(expected);
// [0], [1], [2], [3]
expression = new Expression(
"color()[0] + color()[1] + color()[2] + color()[3]"
);
- shaderExpression = expression.getShaderExpression("", {});
+ shaderExpression = expression.getShaderExpression({}, {});
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for vector", function () {
+ var propertyNameMap = {
+ property: "property",
+ };
+
var expression = new Expression("vec4(1, 2, 3, 4)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression(propertyNameMap, {});
expect(shaderExpression).toEqual("vec4(1.0, 2.0, 3.0, 4.0)");
expression = new Expression("vec4(1) + vec4(2)");
- shaderExpression = expression.getShaderExpression("", {});
+ shaderExpression = expression.getShaderExpression(propertyNameMap, {});
expect(shaderExpression).toEqual("(vec4(1.0) + vec4(2.0))");
expression = new Expression("vec4(1, ${property}, vec2(1, 2).x, 0)");
- shaderExpression = expression.getShaderExpression("", {});
+ shaderExpression = expression.getShaderExpression(propertyNameMap, {});
expect(shaderExpression).toEqual(
"vec4(1.0, property, vec2(1.0, 2.0)[0], 0.0)"
);
expression = new Expression("vec4(vec3(2), 1.0)");
- shaderExpression = expression.getShaderExpression("", {});
+ shaderExpression = expression.getShaderExpression(propertyNameMap, {});
expect(shaderExpression).toEqual("vec4(vec3(2.0), 1.0)");
});
@@ -3783,7 +3855,7 @@ describe("Scene/Expression", function () {
var expression = new Expression(
"vec4(1).x + vec4(1).y + vec4(1).z + vec4(1).w"
);
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected =
"(((vec4(1.0)[0] + vec4(1.0)[1]) + vec4(1.0)[2]) + vec4(1.0)[3])";
expect(shaderExpression).toEqual(expected);
@@ -3792,202 +3864,202 @@ describe("Scene/Expression", function () {
expression = new Expression(
"vec4(1)[0] + vec4(1)[1] + vec4(1)[2] + vec4(1)[3]"
);
- shaderExpression = expression.getShaderExpression("", {});
+ shaderExpression = expression.getShaderExpression({}, {});
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for tiles3d_tileset_time", function () {
var expression = new Expression("${tiles3d_tileset_time}");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "u_time";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for abs", function () {
var expression = new Expression("abs(-1.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "abs(-1.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for cos", function () {
var expression = new Expression("cos(0.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "cos(0.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for sin", function () {
var expression = new Expression("sin(0.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "sin(0.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for tan", function () {
var expression = new Expression("tan(0.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "tan(0.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for acos", function () {
var expression = new Expression("acos(0.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "acos(0.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for asin", function () {
var expression = new Expression("asin(0.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "asin(0.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for atan", function () {
var expression = new Expression("atan(0.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "atan(0.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for sqrt", function () {
var expression = new Expression("sqrt(1.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "sqrt(1.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for sign", function () {
var expression = new Expression("sign(1.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "sign(1.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for floor", function () {
var expression = new Expression("floor(1.5)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "floor(1.5)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for ceil", function () {
var expression = new Expression("ceil(1.2)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "ceil(1.2)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for round", function () {
var expression = new Expression("round(1.2)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "floor(1.2 + 0.5)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for exp", function () {
var expression = new Expression("exp(1.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "exp(1.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for exp2", function () {
var expression = new Expression("exp2(1.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "exp2(1.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for log", function () {
var expression = new Expression("log(1.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "log(1.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for log2", function () {
var expression = new Expression("log2(1.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "log2(1.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for fract", function () {
var expression = new Expression("fract(1.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "fract(1.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for clamp", function () {
var expression = new Expression("clamp(50.0, 0.0, 100.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "clamp(50.0, 0.0, 100.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for mix", function () {
var expression = new Expression("mix(0.0, 2.0, 0.5)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "mix(0.0, 2.0, 0.5)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for atan2", function () {
var expression = new Expression("atan2(0.0,1.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "atan(0.0, 1.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for pow", function () {
var expression = new Expression("pow(2.0,2.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "pow(2.0, 2.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for min", function () {
var expression = new Expression("min(3.0,5.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "min(3.0, 5.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for max", function () {
var expression = new Expression("max(3.0,5.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "max(3.0, 5.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for length", function () {
var expression = new Expression("length(3.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "length(3.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for normalize", function () {
var expression = new Expression("normalize(3.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "normalize(3.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for distance", function () {
var expression = new Expression("distance(0.0, 1.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "distance(0.0, 1.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for dot", function () {
var expression = new Expression("dot(1.0, 2.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "dot(1.0, 2.0)";
expect(shaderExpression).toEqual(expected);
});
@@ -3996,35 +4068,35 @@ describe("Scene/Expression", function () {
var expression = new Expression(
"cross(vec3(1.0, 1.0, 1.0), vec3(2.0, 2.0, 2.0))"
);
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "cross(vec3(1.0, 1.0, 1.0), vec3(2.0, 2.0, 2.0))";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for isNaN", function () {
var expression = new Expression("isNaN(1.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "(1.0 != 1.0)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for isFinite", function () {
var expression = new Expression("isFinite(1.0)");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "(abs(1.0) < czm_infinity)";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for null", function () {
var expression = new Expression("null");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "czm_infinity";
expect(shaderExpression).toEqual(expected);
});
it("gets shader expression for undefined", function () {
var expression = new Expression("undefined");
- var shaderExpression = expression.getShaderExpression("", {});
+ var shaderExpression = expression.getShaderExpression({}, {});
var expected = "czm_infinity";
expect(shaderExpression).toEqual(expected);
});
@@ -4032,85 +4104,85 @@ describe("Scene/Expression", function () {
it("throws when getting shader expression for regex", function () {
var expression = new Expression('regExp("a").test("abc")');
expect(function () {
- return expression.getShaderExpression("", {});
+ return expression.getShaderExpression({}, {});
}).toThrowRuntimeError();
expression = new Expression('regExp("a(.)", "i").exec("Abc")');
expect(function () {
- return expression.getShaderExpression("", {});
+ return expression.getShaderExpression({}, {});
}).toThrowRuntimeError();
expression = new Expression('regExp("a") =~ "abc"');
expect(function () {
- return expression.getShaderExpression("", {});
+ return expression.getShaderExpression({}, {});
}).toThrowRuntimeError();
expression = new Expression('regExp("a") !~ "abc"');
expect(function () {
- return expression.getShaderExpression("", {});
+ return expression.getShaderExpression({}, {});
}).toThrowRuntimeError();
});
it("throws when getting shader expression for member expression with dot", function () {
var expression = new Expression("${property.name}");
expect(function () {
- return expression.getShaderExpression("", {});
+ return expression.getShaderExpression({}, {});
}).toThrowRuntimeError();
});
it("throws when getting shader expression for string member expression with brackets", function () {
var expression = new Expression('${property["name"]}');
expect(function () {
- return expression.getShaderExpression("", {});
+ return expression.getShaderExpression({}, {});
}).toThrowRuntimeError();
});
it("throws when getting shader expression for String", function () {
var expression = new Expression("String(1.0)");
expect(function () {
- return expression.getShaderExpression("", {});
+ return expression.getShaderExpression({}, {});
}).toThrowRuntimeError();
});
it("throws when getting shader expression for toString", function () {
var expression = new Expression('color("red").toString()');
expect(function () {
- return expression.getShaderExpression("", {});
+ return expression.getShaderExpression({}, {});
}).toThrowRuntimeError();
});
it("throws when getting shader expression for literal string", function () {
var expression = new Expression('"name"');
expect(function () {
- return expression.getShaderExpression("", {});
+ return expression.getShaderExpression({}, {});
}).toThrowRuntimeError();
});
it("throws when getting shader expression for variable in string", function () {
var expression = new Expression('"${property}"');
expect(function () {
- return expression.getShaderExpression("", {});
+ return expression.getShaderExpression({}, {});
}).toThrowRuntimeError();
});
it("throws when getting shader expression for isExactClass", function () {
var expression = new Expression('isExactClass("door")');
expect(function () {
- return expression.getShaderExpression("", {});
+ return expression.getShaderExpression({}, {});
}).toThrowRuntimeError();
});
it("throws when getting shader expression for isClass", function () {
var expression = new Expression('isClass("door")');
expect(function () {
- return expression.getShaderExpression("", {});
+ return expression.getShaderExpression({}, {});
}).toThrowRuntimeError();
});
it("throws when getting shader expression for getExactClassName", function () {
var expression = new Expression("getExactClassName()");
expect(function () {
- return expression.getShaderExpression("", {});
+ return expression.getShaderExpression({}, {});
}).toThrowRuntimeError();
});
});
diff --git a/Specs/Scene/GlobeSpec.js b/Specs/Scene/GlobeSpec.js
index fae9596de8a0..c0088821a015 100644
--- a/Specs/Scene/GlobeSpec.js
+++ b/Specs/Scene/GlobeSpec.js
@@ -3,6 +3,10 @@ import { Rectangle } from "../../Source/Cesium.js";
import { Resource } from "../../Source/Cesium.js";
import { Globe } from "../../Source/Cesium.js";
import { SingleTileImageryProvider } from "../../Source/Cesium.js";
+import { Color } from "../../Source/Cesium.js";
+import { Cartesian3 } from "../../Source/Cesium.js";
+import { HeadingPitchRoll } from "../../Source/Cesium.js";
+import { NearFarScalar } from "../../Source/Cesium.js";
import createScene from "../createScene.js";
import pollToPromise from "../pollToPromise.js";
@@ -412,6 +416,78 @@ describe(
);
});
});
+
+ it("gets underground color", function () {
+ expect(globe.undergroundColor).toEqual(Color.BLACK);
+ });
+
+ it("sets underground color", function () {
+ globe.undergroundColor = Color.RED;
+
+ scene.camera.setView({
+ destination: new Cartesian3(
+ -524251.65918537375,
+ -5316355.5357514685,
+ 3400179.253223899
+ ),
+ orientation: new HeadingPitchRoll(
+ 0.22779127099032603,
+ -0.7030060668670961,
+ 0.0024147223687949193
+ ),
+ });
+
+ return updateUntilDone(globe).then(function () {
+ expect(scene).toRender([255, 0, 0, 255]);
+ });
+ });
+
+ it("gets underground color by distance", function () {
+ expect(globe.undergroundColorAlphaByDistance).toBeDefined();
+ });
+
+ it("sets underground color by distance", function () {
+ globe.baseColor = Color.BLACK;
+ globe.undergroundColor = Color.RED;
+ var radius = globe.ellipsoid.maximumRadius;
+ globe.undergroundColorAlphaByDistance = new NearFarScalar(
+ radius * 0.25,
+ 0.0,
+ radius * 2.0,
+ 1.0
+ );
+
+ scene.camera.setView({
+ destination: new Cartesian3(
+ -524251.65918537375,
+ -5316355.5357514685,
+ 3400179.253223899
+ ),
+ orientation: new HeadingPitchRoll(
+ 0.24245689061958142,
+ -0.445653254172905,
+ 0.0024147223687949193
+ ),
+ });
+
+ return updateUntilDone(globe).then(function () {
+ expect(scene).toRenderAndCall(function (rgba) {
+ expect(rgba[0]).toBeGreaterThan(0);
+ expect(rgba[0]).toBeLessThan(255);
+ });
+ });
+ });
+
+ it("throws if underground color by distance far is less than near", function () {
+ expect(function () {
+ globe.undergroundColorAlphaByDistance = new NearFarScalar(
+ 1.0,
+ 0.0,
+ 0.0,
+ 1.0
+ );
+ }).toThrowDeveloperError();
+ });
},
"WebGL"
);
diff --git a/Specs/Scene/GlobeSurfaceTileProviderSpec.js b/Specs/Scene/GlobeSurfaceTileProviderSpec.js
index d615b23fc2b7..d81a3f01b372 100644
--- a/Specs/Scene/GlobeSurfaceTileProviderSpec.js
+++ b/Specs/Scene/GlobeSurfaceTileProviderSpec.js
@@ -622,6 +622,8 @@ describe(
);
layer.alpha = 0.123;
+ layer.nightAlpha = 0.658;
+ layer.dayAlpha = 0.356;
layer.brightness = 0.456;
layer.contrast = 0.654;
layer.gamma = 0.321;
@@ -651,6 +653,8 @@ describe(
++tileCommandCount;
expect(uniforms.u_dayTextureAlpha()).toEqual([0.123]);
+ expect(uniforms.u_dayTextureNightAlpha()).toEqual([0.658]);
+ expect(uniforms.u_dayTextureDayAlpha()).toEqual([0.356]);
expect(uniforms.u_dayTextureBrightness()).toEqual([0.456]);
expect(uniforms.u_dayTextureContrast()).toEqual([0.654]);
expect(uniforms.u_dayTextureOneOverGamma()).toEqual([1.0 / 0.321]);
diff --git a/Specs/Scene/GlobeTranslucencyFramebufferSpec.js b/Specs/Scene/GlobeTranslucencyFramebufferSpec.js
new file mode 100644
index 000000000000..d2dfeda2d2fb
--- /dev/null
+++ b/Specs/Scene/GlobeTranslucencyFramebufferSpec.js
@@ -0,0 +1,110 @@
+import { BoundingRectangle } from "../../Source/Cesium.js";
+import { Framebuffer } from "../../Source/Cesium.js";
+import { GlobeTranslucencyFramebuffer } from "../../Source/Cesium.js";
+import { PassState } from "../../Source/Cesium.js";
+import { PixelDatatype } from "../../Source/Cesium.js";
+import { Texture } from "../../Source/Cesium.js";
+import createScene from "../createScene.js";
+
+describe("Scene/GlobeTranslucencyFramebuffer", function () {
+ var scene;
+
+ beforeAll(function () {
+ scene = createScene();
+ });
+
+ afterAll(function () {
+ scene.destroyForSpecs();
+ });
+
+ it("creates resources", function () {
+ var globeTranslucency = new GlobeTranslucencyFramebuffer();
+ var context = scene.context;
+ var viewport = new BoundingRectangle(0, 0, 100, 100);
+ var passState = new PassState(context);
+ globeTranslucency.updateAndClear(false, viewport, context, passState);
+ expect(globeTranslucency._colorTexture).toBeDefined();
+ expect(globeTranslucency._framebuffer).toBeDefined();
+ expect(globeTranslucency._packedDepthTexture).toBeDefined();
+ expect(globeTranslucency._packedDepthFramebuffer).toBeDefined();
+
+ if (context.depthTexture) {
+ expect(globeTranslucency._depthStencilTexture).toBeDefined();
+ } else {
+ expect(globeTranslucency._depthStencilRenderbuffer).toBeDefined();
+ }
+
+ expect(globeTranslucency._packedDepthCommand).toBeDefined();
+ expect(globeTranslucency._clearCommand).toBeDefined();
+ });
+
+ it("recreates resources when viewport changes", function () {
+ var globeTranslucency = new GlobeTranslucencyFramebuffer();
+ var frameState = scene.frameState;
+ var context = frameState.context;
+ var viewport = new BoundingRectangle(0, 0, 100, 100);
+ var passState = new PassState(context);
+ globeTranslucency.updateAndClear(false, viewport, context, passState);
+ var firstColorTexture = globeTranslucency._colorTexture;
+ var firstFramebuffer = globeTranslucency._framebuffer;
+ var firstPackedDepthFramebuffer = globeTranslucency._packedDepthFramebuffer;
+ expect(globeTranslucency._clearCommand.framebuffer).toBe(firstFramebuffer);
+ expect(globeTranslucency._packedDepthCommand.framebuffer).toBe(
+ firstPackedDepthFramebuffer
+ );
+
+ viewport.width = 50;
+ globeTranslucency.updateAndClear(false, viewport, context, passState);
+ expect(firstColorTexture.isDestroyed()).toBe(true);
+ expect(globeTranslucency._colorTexture).not.toBe(firstColorTexture);
+ expect(globeTranslucency._clearCommand.framebuffer).not.toBe(
+ firstFramebuffer
+ );
+ expect(globeTranslucency._packedDepthCommand.framebuffer).not.toBe(
+ firstPackedDepthFramebuffer
+ );
+ });
+
+ it("recreates resources when HDR changes", function () {
+ if (!scene.highDynamicRangeSupported) {
+ return;
+ }
+
+ var frameState = scene.frameState;
+ var context = frameState.context;
+ var globeTranslucency = new GlobeTranslucencyFramebuffer();
+ var viewport = new BoundingRectangle(0, 0, 100, 100);
+ var passState = new PassState(context);
+ globeTranslucency.updateAndClear(false, viewport, context, passState);
+ var firstColorTexture = globeTranslucency._colorTexture;
+
+ var expectedPixelDatatype = context.halfFloatingPointTexture
+ ? PixelDatatype.HALF_FLOAT
+ : PixelDatatype.FLOAT;
+ globeTranslucency.updateAndClear(true, viewport, context, passState);
+ expect(firstColorTexture.isDestroyed()).toBe(true);
+ expect(globeTranslucency._colorTexture).not.toBe(firstColorTexture);
+ expect(globeTranslucency._colorTexture.pixelDatatype).toBe(
+ expectedPixelDatatype
+ );
+ });
+
+ it("destroys", function () {
+ var globeTranslucency = new GlobeTranslucencyFramebuffer();
+ var frameState = scene.frameState;
+ var context = frameState.context;
+ var viewport = new BoundingRectangle(0, 0, 100, 100);
+ var passState = new PassState(context);
+
+ globeTranslucency.updateAndClear(false, viewport, context, passState);
+
+ spyOn(Texture.prototype, "destroy").and.callThrough();
+ spyOn(Framebuffer.prototype, "destroy").and.callThrough();
+
+ globeTranslucency.destroy();
+
+ expect(globeTranslucency.isDestroyed()).toBe(true);
+ expect(Texture.prototype.destroy).toHaveBeenCalled();
+ expect(Framebuffer.prototype.destroy).toHaveBeenCalled();
+ });
+});
diff --git a/Specs/Scene/GlobeTranslucencyStateSpec.js b/Specs/Scene/GlobeTranslucencyStateSpec.js
new file mode 100644
index 000000000000..ffae30855719
--- /dev/null
+++ b/Specs/Scene/GlobeTranslucencyStateSpec.js
@@ -0,0 +1,719 @@
+import { Color } from "../../Source/Cesium.js";
+import { DrawCommand } from "../../Source/Cesium.js";
+import { FrustumCommands } from "../../Source/Cesium.js";
+import { Globe } from "../../Source/Cesium.js";
+import { GlobeTranslucencyFramebuffer } from "../../Source/Cesium.js";
+import { GlobeTranslucencyState } from "../../Source/Cesium.js";
+import { NearFarScalar } from "../../Source/Cesium.js";
+import { Pass } from "../../Source/Cesium.js";
+import { PassState } from "../../Source/Cesium.js";
+import { RenderState } from "../../Source/Cesium.js";
+import { SceneMode } from "../../Source/Cesium.js";
+import { ShaderProgram } from "../../Source/Cesium.js";
+import { ShaderSource } from "../../Source/Cesium.js";
+import createScene from "../createScene.js";
+
+var scene;
+var globe;
+var frameState;
+var state;
+var framebuffer;
+
+function reset() {
+ scene._globe = globe;
+
+ globe.show = true;
+ globe.translucency.enabled = false;
+ globe.translucency.frontFaceAlpha = 1.0;
+ globe.translucency.frontFaceAlphaByDistance = undefined;
+ globe.translucency.backFaceAlpha = 1.0;
+ globe.translucency.backFaceAlphaByDistance = undefined;
+ globe.baseColor = Color.WHITE;
+ globe.depthTestAgainstTerrain = false;
+
+ frameState.commandList.length = 0;
+ frameState.passes.pick = false;
+ frameState.frameNumber = 0;
+
+ scene._cameraUnderground = false;
+ scene._mode = SceneMode.SCENE3D;
+}
+
+function createShaderProgram(colorString) {
+ var vs = "void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0); }";
+ var fs = "void main() { gl_FragColor = vec4(" + colorString + "); }";
+
+ var vertexShaderSource = new ShaderSource({
+ sources: [vs],
+ });
+
+ var fragmentShaderSource = new ShaderSource({
+ sources: [fs],
+ });
+
+ return ShaderProgram.fromCache({
+ context: scene.context,
+ vertexShaderSource: vertexShaderSource,
+ fragmentShaderSource: fragmentShaderSource,
+ });
+}
+
+function createDrawCommand() {
+ var uniformMap = {};
+ var shaderProgram = createShaderProgram("0.0");
+
+ var renderState = RenderState.fromCache({
+ depthMask: true,
+ cull: {
+ enabled: true,
+ },
+ });
+
+ var drawCommand = new DrawCommand({
+ shaderProgram: shaderProgram,
+ uniformMap: uniformMap,
+ renderState: renderState,
+ });
+
+ return drawCommand;
+}
+
+describe("Scene/GlobeTranslucencyState", function () {
+ beforeAll(function () {
+ scene = createScene();
+ scene.globe = new Globe();
+ globe = scene.globe;
+ frameState = scene.frameState;
+ state = new GlobeTranslucencyState();
+ framebuffer = new GlobeTranslucencyFramebuffer();
+ });
+
+ afterAll(function () {
+ scene.destroyForSpecs();
+ });
+
+ beforeEach(function () {
+ reset();
+ });
+
+ it("gets front face alpha by distance", function () {
+ // Opaque
+ reset();
+ state.update(scene);
+ var frontFaceAlphaByDistance = state.frontFaceAlphaByDistance;
+ var backFaceAlphaByDistance = state.backFaceAlphaByDistance;
+ expect(frontFaceAlphaByDistance.nearValue).toBe(1.0);
+ expect(frontFaceAlphaByDistance.farValue).toBe(1.0);
+ expect(backFaceAlphaByDistance.nearValue).toBe(1.0);
+ expect(backFaceAlphaByDistance.farValue).toBe(1.0);
+
+ // Front and back translucent
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.translucency.backFaceAlpha = 0.25;
+ state.update(scene);
+ expect(frontFaceAlphaByDistance.nearValue).toBe(0.5);
+ expect(frontFaceAlphaByDistance.farValue).toBe(0.5);
+ expect(backFaceAlphaByDistance.nearValue).toBe(0.25);
+ expect(backFaceAlphaByDistance.farValue).toBe(0.25);
+
+ // Front and back translucent with alpha by distance
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.translucency.backFaceAlpha = 0.25;
+ globe.translucency.frontFaceAlphaByDistance = new NearFarScalar(
+ 0.0,
+ 0.5,
+ 1.0,
+ 0.75
+ );
+ state.update(scene);
+ expect(frontFaceAlphaByDistance.nearValue).toBe(0.25);
+ expect(frontFaceAlphaByDistance.farValue).toBe(0.375);
+ expect(backFaceAlphaByDistance.nearValue).toBe(0.25);
+ expect(backFaceAlphaByDistance.farValue).toBe(0.25);
+ });
+
+ it("detects if globe is translucent", function () {
+ // Returns false when globe is undefined
+ reset();
+ scene._globe = undefined;
+ state.update(scene);
+ expect(state.translucent).toBe(false);
+
+ // Returns false when globe.show is false
+ reset();
+ globe.show = false;
+ state.update(scene);
+ expect(state.translucent).toBe(false);
+
+ // Returns false for default globe
+ reset();
+ state.update(scene);
+ expect(state.translucent).toBe(false);
+
+ // Returns true when base color is translucent
+ reset();
+ globe.translucency.enabled = true;
+ globe.baseColor = Color.TRANSPARENT;
+ state.update(scene);
+ expect(state.translucent).toBe(true);
+
+ // Returns true when front face alpha is less than 1.0
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ state.update(scene);
+ expect(state.translucent).toBe(true);
+ });
+
+ it("detects if sun is visible through globe", function () {
+ // Returns true when globe is undefined
+ reset();
+ scene._globe = undefined;
+ state.update(scene);
+ expect(state.sunVisibleThroughGlobe).toBe(true);
+
+ // Returns true when globe.show is false
+ reset();
+ globe.show = false;
+ state.update(scene);
+ expect(state.sunVisibleThroughGlobe).toBe(true);
+
+ // Returns false for default globe
+ reset();
+ state.update(scene);
+ expect(state.sunVisibleThroughGlobe).toBe(false);
+
+ // Returns true if front face and back face are translucent and camera is above ground
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.translucency.backFaceAlpha = 0.5;
+ state.update(scene);
+ expect(state.sunVisibleThroughGlobe).toBe(true);
+
+ // Returns false if front face is translucent and back face is opaque and camera is above ground
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ state.update(scene);
+ expect(state.sunVisibleThroughGlobe).toBe(false);
+
+ // Returns true if front face is translucent and camera is underground
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ scene._cameraUnderground = true;
+ state.update(scene);
+ expect(state.sunVisibleThroughGlobe).toBe(true);
+ });
+
+ it("detects if environment is visible", function () {
+ // Returns true when globe is undefined
+ reset();
+ scene._globe = undefined;
+ state.update(scene);
+ expect(state.environmentVisible).toBe(true);
+
+ // Returns true when globe.show is false
+ reset();
+ globe.show = false;
+ state.update(scene);
+ expect(state.environmentVisible).toBe(true);
+
+ // Returns true for default globe
+ reset();
+ state.update(scene);
+ expect(state.environmentVisible).toBe(true);
+
+ // Returns false if globe is opaque and camera is underground
+ reset();
+ scene._cameraUnderground = true;
+ state.update(scene);
+ expect(state.environmentVisible).toBe(false);
+
+ // Returns true if front faces are translucent and camera is underground
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ scene._cameraUnderground = true;
+ state.update(scene);
+ expect(state.environmentVisible).toBe(true);
+ });
+
+ it("detects whether to use depth plane", function () {
+ // Returns false when globe is undefined
+ reset();
+ scene._globe = undefined;
+ state.update(scene);
+ expect(state.useDepthPlane).toBe(false);
+
+ // Returns false when globe.show is false
+ reset();
+ globe.show = false;
+ state.update(scene);
+ expect(state.useDepthPlane).toBe(false);
+
+ // Returns false if camera is underground
+ reset();
+ scene._cameraUnderground = true;
+ state.update(scene);
+ expect(state.useDepthPlane).toBe(false);
+
+ // Return false when globe is translucent
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ state.update(scene);
+ expect(state.useDepthPlane).toBe(false);
+ });
+
+ it("gets number of texture uniforms required", function () {
+ // Returns zero if globe is opaque
+ reset();
+ state.update(scene);
+ expect(state.numberOfTextureUniforms).toBe(0);
+
+ // Returns two when globe is translucent and manual depth testing is required
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ state.update(scene);
+ expect(state.numberOfTextureUniforms).toBe(1 + scene.context.depthTexture);
+
+ // Returns one when globe is translucent and manual depth testing is not required
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.depthTestAgainstTerrain = true;
+ state.update(scene);
+ expect(state.numberOfTextureUniforms).toBe(1);
+ });
+
+ function checkTypes(state, typeArrays) {
+ var derivedCommandTypes = state._derivedCommandTypes;
+ var derivedBlendCommandTypes = state._derivedBlendCommandTypes;
+ var derivedPickCommandTypes = state._derivedPickCommandTypes;
+ var derivedCommandTypesToUpdate = state._derivedCommandTypesToUpdate;
+
+ var length = state._derivedCommandsLength;
+ var blendLength = state._derivedBlendCommandsLength;
+ var pickLength = state._derivedPickCommandsLength;
+ var updateLength = state._derivedCommandsToUpdateLength;
+
+ var types = derivedCommandTypes.slice(0, length);
+ var blendTypes = derivedBlendCommandTypes.slice(0, blendLength);
+ var pickTypes = derivedPickCommandTypes.slice(0, pickLength);
+ var updateTypes = derivedCommandTypesToUpdate.slice(0, updateLength);
+
+ expect(types).toEqual(typeArrays[0]);
+ expect(blendTypes).toEqual(typeArrays[1]);
+ expect(pickTypes).toEqual(typeArrays[2]);
+ expect(updateTypes).toEqual(typeArrays[3]);
+ }
+
+ it("gets derived commands to update", function () {
+ // Front opaque
+ reset();
+ state.update(scene);
+ checkTypes(state, [[], [], [], []]);
+
+ // Front translucent, back opaque
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.depthTestAgainstTerrain = true;
+ state.update(scene);
+ checkTypes(state, [
+ [2, 1, 5],
+ [1, 5],
+ [2, 1, 9],
+ [1, 2, 5, 9],
+ ]);
+
+ // Front translucent, back opaque, manual depth test
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ state.update(scene);
+
+ if (frameState.context.depthTexture) {
+ checkTypes(state, [
+ [2, 1, 7],
+ [1, 7],
+ [2, 1, 9],
+ [1, 2, 7, 9],
+ ]);
+ } else {
+ checkTypes(state, [
+ [2, 1, 5],
+ [1, 5],
+ [2, 1, 9],
+ [1, 2, 5, 9],
+ ]);
+ }
+
+ // Front translucent, back opaque, manual depth test, camera underground
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ scene._cameraUnderground = true;
+ state.update(scene);
+ if (frameState.context.depthTexture) {
+ checkTypes(state, [
+ [3, 0, 8],
+ [0, 8],
+ [3, 0, 10],
+ [0, 3, 8, 10],
+ ]);
+ } else {
+ checkTypes(state, [
+ [3, 0, 6],
+ [0, 6],
+ [3, 0, 10],
+ [0, 3, 6, 10],
+ ]);
+ }
+
+ // Front translucent, back translucent
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.translucency.backFaceAlpha = 0.5;
+ state.update(scene);
+ checkTypes(state, [
+ [4, 6, 5],
+ [6, 5],
+ [4, 10, 9],
+ [4, 5, 6, 9, 10],
+ ]);
+
+ // Front translucent, back translucent, camera underground
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.translucency.backFaceAlpha = 0.5;
+ scene._cameraUnderground = true;
+ state.update(scene);
+ checkTypes(state, [
+ [4, 5, 6],
+ [5, 6],
+ [4, 9, 10],
+ [4, 5, 6, 9, 10],
+ ]);
+
+ // Translucent, 2D
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ scene._mode = SceneMode.SCENE2D;
+ state.update(scene);
+ checkTypes(state, [
+ [2, 5],
+ [2, 5],
+ [2, 9],
+ [2, 5, 9],
+ ]);
+ });
+
+ it("detects when derived command requirements have changed", function () {
+ // Front opaque
+ reset();
+ state.update(scene);
+
+ // Front translucent, back opaque
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.depthTestAgainstTerrain = true;
+ state.update(scene);
+ expect(state._derivedCommandsDirty).toBe(true);
+
+ // Same state
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.depthTestAgainstTerrain = true;
+ state.update(scene);
+ expect(state._derivedCommandsDirty).toBe(false);
+ });
+
+ it("does not update derived commands when globe is opaque", function () {
+ var command = createDrawCommand();
+
+ reset();
+ state.update(scene);
+ state.updateDerivedCommands(command, frameState);
+ var derivedCommands = command.derivedCommands.globeTranslucency;
+ expect(derivedCommands).toBeUndefined();
+ });
+
+ it("updates derived commands", function () {
+ var command = createDrawCommand();
+ var uniformMap = command.uniformMap;
+ var shaderProgram = command.shaderProgram;
+ var renderState = command.renderState;
+
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.depthTestAgainstTerrain = true;
+ state.update(scene);
+ state.updateDerivedCommands(command, frameState);
+ var derivedCommands = command.derivedCommands.globeTranslucency;
+ expect(derivedCommands).toBeDefined();
+ expect(derivedCommands.opaqueBackFaceCommand).toBeDefined();
+ expect(derivedCommands.depthOnlyFrontFaceCommand).toBeDefined();
+ expect(derivedCommands.translucentFrontFaceCommand).toBeDefined();
+ expect(derivedCommands.pickFrontFaceCommand).toBeDefined();
+ expect(derivedCommands.pickBackFaceCommand).toBeUndefined();
+
+ var derivedCommand = derivedCommands.translucentFrontFaceCommand;
+ var derivedUniformMap = derivedCommand.uniformMap;
+ var derivedShaderProgram = derivedCommand.shaderProgram;
+ var derivedRenderState = derivedCommand.renderState;
+
+ expect(derivedUniformMap).not.toBe(uniformMap);
+ expect(derivedShaderProgram).not.toBe(shaderProgram);
+ expect(derivedRenderState).not.toBe(renderState);
+
+ // Check that the derived commands get updated when the command changes
+ command.uniformMap = {};
+ command.shaderProgram = createShaderProgram("1.0");
+ command.renderState = RenderState.fromCache({
+ colorMask: {
+ red: false,
+ },
+ });
+
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.depthTestAgainstTerrain = true;
+ state.update(scene);
+ state.updateDerivedCommands(command, frameState);
+ derivedCommands = command.derivedCommands.globeTranslucency;
+ derivedCommand = derivedCommands.translucentFrontFaceCommand;
+
+ expect(derivedCommand.uniformMap).not.toBe(derivedUniformMap);
+ expect(derivedCommand.shaderProgram).not.toBe(derivedShaderProgram);
+ expect(derivedCommand.renderState).not.toBe(derivedRenderState);
+ expect(derivedCommand.uniformMap).not.toBe(uniformMap);
+ expect(derivedCommand.shaderProgram).not.toBe(shaderProgram);
+ expect(derivedCommand.renderState).not.toBe(renderState);
+
+ // Check that cached shader programs and render states are used
+ command.uniformMap = uniformMap;
+ command.shaderProgram = shaderProgram;
+ command.renderState = renderState;
+
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.depthTestAgainstTerrain = true;
+ state.update(scene);
+ state.updateDerivedCommands(command, frameState);
+ derivedCommands = command.derivedCommands.globeTranslucency;
+ derivedCommand = derivedCommands.translucentFrontFaceCommand;
+
+ expect(derivedCommand.uniformMap).not.toBe(derivedUniformMap);
+ expect(derivedCommand.shaderProgram).toBe(derivedShaderProgram);
+ expect(derivedCommand.renderState).toBe(derivedRenderState);
+ });
+
+ it("does not push derived commands when blend command is in the pick pass", function () {
+ var command = createDrawCommand();
+
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ frameState.passes.pick = true;
+ state.update(scene);
+ state.updateDerivedCommands(command, frameState);
+ state.pushDerivedCommands(command, true, frameState);
+
+ expect(frameState.commandList.length).toBe(0);
+ });
+
+ it("pushes globe command when globe is opaque", function () {
+ var command = createDrawCommand();
+
+ reset();
+ state.update(scene);
+ state.updateDerivedCommands(command, frameState);
+ state.pushDerivedCommands(command, false, frameState);
+
+ expect(frameState.commandList.length).toBe(1);
+ expect(frameState.commandList[0]).toBe(command);
+ });
+
+ it("pushes derived commands when globe is translucent", function () {
+ var command = createDrawCommand();
+
+ // isBlendCommand = false
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.depthTestAgainstTerrain = true;
+ state.update(scene);
+ state.updateDerivedCommands(command, frameState);
+ state.pushDerivedCommands(command, false, frameState);
+
+ var derivedCommands = command.derivedCommands.globeTranslucency;
+ expect(frameState.commandList).toEqual([
+ derivedCommands.depthOnlyFrontFaceCommand,
+ derivedCommands.opaqueBackFaceCommand,
+ derivedCommands.translucentFrontFaceCommand,
+ ]);
+
+ // isBlendCommand = true
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.depthTestAgainstTerrain = true;
+ state.update(scene);
+ state.updateDerivedCommands(command, frameState);
+ state.pushDerivedCommands(command, true, frameState);
+
+ expect(frameState.commandList).toEqual([
+ derivedCommands.opaqueBackFaceCommand,
+ derivedCommands.translucentFrontFaceCommand,
+ ]);
+
+ // picking
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.depthTestAgainstTerrain = true;
+ frameState.passes.pick = true;
+ state.update(scene);
+ state.updateDerivedCommands(command, frameState);
+ state.pushDerivedCommands(command, false, frameState);
+
+ expect(frameState.commandList).toEqual([
+ derivedCommands.depthOnlyFrontFaceCommand,
+ derivedCommands.opaqueBackFaceCommand,
+ derivedCommands.pickFrontFaceCommand,
+ ]);
+ });
+
+ it("executes globe commands", function () {
+ var context = frameState.context;
+ var passState = new PassState(context);
+ var command = createDrawCommand();
+
+ var executeCommand = jasmine.createSpy("executeCommand");
+ spyOn(GlobeTranslucencyFramebuffer.prototype, "clearClassification");
+
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.depthTestAgainstTerrain = true;
+ state.update(scene);
+ state.updateDerivedCommands(command, frameState);
+ state.pushDerivedCommands(command, false, frameState);
+
+ var globeCommands = frameState.commandList;
+
+ var frustumCommands = new FrustumCommands();
+ frustumCommands.commands[Pass.GLOBE] = globeCommands;
+ frustumCommands.indices[Pass.GLOBE] = globeCommands.length;
+
+ state.executeGlobeCommands(
+ frustumCommands,
+ executeCommand,
+ framebuffer,
+ scene,
+ passState
+ );
+
+ expect(executeCommand).toHaveBeenCalledWith(
+ command.derivedCommands.globeTranslucency.opaqueBackFaceCommand,
+ scene,
+ context,
+ passState
+ );
+ expect(
+ GlobeTranslucencyFramebuffer.prototype.clearClassification
+ ).toHaveBeenCalled();
+ });
+
+ it("does not execute globe commands if there are no commands", function () {
+ var frameState = scene.frameState;
+ var context = frameState.context;
+ var passState = new PassState(context);
+
+ var frustumCommands = new FrustumCommands();
+
+ var executeCommand = jasmine.createSpy("executeCommand");
+ state.executeGlobeCommands(
+ frustumCommands,
+ executeCommand,
+ framebuffer,
+ scene,
+ passState
+ );
+
+ expect(executeCommand).not.toHaveBeenCalled();
+ });
+
+ it("executes classification commands", function () {
+ var context = frameState.context;
+ var passState = new PassState(context);
+ var command = createDrawCommand();
+
+ var executeCommand = jasmine.createSpy("executeCommand");
+ spyOn(GlobeTranslucencyFramebuffer.prototype, "packDepth");
+ spyOn(GlobeTranslucencyFramebuffer.prototype, "clearClassification");
+
+ reset();
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ globe.depthTestAgainstTerrain = true;
+ state.update(scene);
+ state.updateDerivedCommands(command, frameState);
+ state.pushDerivedCommands(command, false, frameState);
+
+ var classificationCommand = createDrawCommand();
+ var globeCommands = frameState.commandList;
+ var classificationCommands = [classificationCommand];
+ var frustumCommands = new FrustumCommands();
+ frustumCommands.commands[Pass.GLOBE] = globeCommands;
+ frustumCommands.indices[Pass.GLOBE] = globeCommands.length;
+ frustumCommands.commands[
+ Pass.TERRAIN_CLASSIFICATION
+ ] = classificationCommands;
+ frustumCommands.indices[Pass.TERRAIN_CLASSIFICATION] =
+ classificationCommands.length;
+
+ state.executeGlobeClassificationCommands(
+ frustumCommands,
+ executeCommand,
+ framebuffer,
+ scene,
+ passState
+ );
+
+ expect(executeCommand).toHaveBeenCalledWith(
+ classificationCommand,
+ scene,
+ context,
+ passState
+ );
+ expect(executeCommand).toHaveBeenCalledWith(
+ command.derivedCommands.globeTranslucency.depthOnlyFrontFaceCommand,
+ scene,
+ context,
+ passState
+ );
+
+ if (context.depthTexture) {
+ expect(
+ GlobeTranslucencyFramebuffer.prototype.packDepth
+ ).toHaveBeenCalled();
+ }
+ });
+});
diff --git a/Specs/Scene/ModelOutlineLoaderSpec.js b/Specs/Scene/ModelOutlineLoaderSpec.js
index 4ca993cd6c29..49dce0d2f111 100644
--- a/Specs/Scene/ModelOutlineLoaderSpec.js
+++ b/Specs/Scene/ModelOutlineLoaderSpec.js
@@ -499,13 +499,21 @@ describe(
});
});
- it("switches to 32-bit indices if more than 65536 vertices are required", function () {
+ it("switches to 32-bit indices if more than 65535 vertices are required", function () {
+ if (!scene.context.elementIndexUint) {
+ // This extension is supported everywhere these days, except possibly
+ // in our mocked WebGL context used in the tests on Travis. Consistent
+ // with the approach in ModelSpec.js, `loads a gltf with uint32 indices`,
+ // we'll just give this test a pass if uint indices aren't supported.
+ return;
+ }
+
var vertices = [];
var indices = [];
var edges = [];
// Tricky model is 9 vertices. Add copies of it until we're just under 65636 vertices.
- for (var i = 0; vertices.length / 7 + 9 <= 65536; ++i) {
+ for (var i = 0; vertices.length / 7 + 9 <= 65535; ++i) {
createTrickyModel(vertices, indices, edges, 2, true, true, true);
}
@@ -575,6 +583,10 @@ describe(
}
}
+ var rendererIndexBuffer =
+ model._rendererResources.buffers[triangleIndexAccessor.bufferView];
+ expect(rendererIndexBuffer.bytesPerIndex).toBe(4);
+
builder.destroy();
});
});
diff --git a/Specs/Scene/PointCloud3DTileContentSpec.js b/Specs/Scene/PointCloud3DTileContentSpec.js
index accbed387171..4f391defe678 100644
--- a/Specs/Scene/PointCloud3DTileContentSpec.js
+++ b/Specs/Scene/PointCloud3DTileContentSpec.js
@@ -58,6 +58,8 @@ describe(
"./Data/Cesium3DTiles/PointCloud/PointCloudBatched/tileset.json";
var pointCloudWithPerPointPropertiesUrl =
"./Data/Cesium3DTiles/PointCloud/PointCloudWithPerPointProperties/tileset.json";
+ var pointCloudWithUnicodePropertyNamesUrl =
+ "./Data/Cesium3DTiles/PointCloud/PointCloudWithUnicodePropertyNames/tileset.json";
var pointCloudWithTransformUrl =
"./Data/Cesium3DTiles/PointCloud/PointCloudWithTransform/tileset.json";
var pointCloudTilesetUrl =
@@ -789,6 +791,24 @@ describe(
});
});
+ it("applies shader style with unicode property names", function () {
+ return Cesium3DTilesTester.loadTileset(
+ scene,
+ pointCloudWithUnicodePropertyNamesUrl
+ ).then(function (tileset) {
+ tileset.style = new Cesium3DTileStyle({
+ color: "color() * ${feature['temperature ℃']}",
+ });
+ expect(scene).toRenderAndCall(function (rgba) {
+ // Pixel color is some shade of gray
+ expect(rgba[0]).toBe(rgba[1]);
+ expect(rgba[0]).toBe(rgba[2]);
+ expect(rgba[0]).toBeGreaterThan(0);
+ expect(rgba[0]).toBeLessThan(255);
+ });
+ });
+ });
+
it("rebuilds shader style when expression changes", function () {
return Cesium3DTilesTester.loadTileset(scene, pointCloudTilesetUrl).then(
function (tileset) {
diff --git a/Specs/Scene/QuadtreePrimitiveSpec.js b/Specs/Scene/QuadtreePrimitiveSpec.js
index 78162ab71599..b97ef4142a0b 100644
--- a/Specs/Scene/QuadtreePrimitiveSpec.js
+++ b/Specs/Scene/QuadtreePrimitiveSpec.js
@@ -12,6 +12,7 @@ import { Rectangle } from "../../Source/Cesium.js";
import { Visibility } from "../../Source/Cesium.js";
import { Camera } from "../../Source/Cesium.js";
import { GlobeSurfaceTileProvider } from "../../Source/Cesium.js";
+import { GlobeTranslucencyState } from "../../Source/Cesium.js";
import { ImageryLayerCollection } from "../../Source/Cesium.js";
import { QuadtreePrimitive } from "../../Source/Cesium.js";
import { QuadtreeTileLoadState } from "../../Source/Cesium.js";
@@ -62,6 +63,7 @@ describe("Scene/QuadtreePrimitive", function () {
]),
afterRender: [],
pixelRatio: 1.0,
+ globeTranslucencyState: new GlobeTranslucencyState(),
};
frameState.cullingVolume.computeVisibility.and.returnValue(
diff --git a/Specs/Scene/SceneSpec.js b/Specs/Scene/SceneSpec.js
index 9ed339c2928d..65ba5488ea1d 100644
--- a/Specs/Scene/SceneSpec.js
+++ b/Specs/Scene/SceneSpec.js
@@ -40,6 +40,10 @@ import { SceneTransforms } from "../../Source/Cesium.js";
import { ScreenSpaceCameraController } from "../../Source/Cesium.js";
import { SunLight } from "../../Source/Cesium.js";
import { TweenCollection } from "../../Source/Cesium.js";
+import { Sun } from "../../Source/Cesium.js";
+import { GroundPrimitive } from "../../Source/Cesium.js";
+import { PerInstanceColorAppearance } from "../../Source/Cesium.js";
+import { ColorGeometryInstanceAttribute } from "../../Source/Cesium.js";
import createCanvas from "../createCanvas.js";
import createScene from "../createScene.js";
import pollToPromise from "../pollToPromise.js";
@@ -64,6 +68,8 @@ describe(
}),
});
simpleRenderState = new RenderState();
+
+ return GroundPrimitive.initializeTerrainHeights();
});
afterEach(function () {
@@ -2058,22 +2064,6 @@ describe(
});
});
- it("detects that camera is above ground if screen space camera controller adjusted height for terrain", function () {
- var scene = createScene();
- var globe = new Globe();
- scene.globe = globe;
-
- spyOn(
- ScreenSpaceCameraController.prototype,
- "adjustedHeightForTerrain"
- ).and.returnValue(true);
-
- return updateGlobeUntilDone(scene).then(function () {
- expect(scene.cameraUnderground).toBe(false);
- scene.destroyForSpecs();
- });
- });
-
it("detects that camera is above ground if globe is undefined", function () {
var scene = createScene();
scene.renderForSpecs();
@@ -2174,6 +2164,211 @@ describe(
scene.destroyForSpecs();
});
});
+
+ it("does not occlude primitives when the globe is translucent", function () {
+ var scene = createScene();
+ var globe = new Globe();
+ scene.globe = globe;
+
+ // A primitive at height -25000.0 is less than the minor axis for WGS84 and will get culled unless the globe is translucent
+ var center = Cartesian3.fromRadians(
+ 2.3929070618374535,
+ -0.07149851443375346,
+ -25000.0,
+ globe.ellipsoid
+ );
+ var radius = 10.0;
+
+ var command = new DrawCommand({
+ shaderProgram: simpleShaderProgram,
+ renderState: simpleRenderState,
+ pass: Pass.OPAQUE,
+ boundingVolume: new BoundingSphere(center, radius),
+ });
+
+ scene.primitives.add(new CommandMockPrimitive(command));
+
+ spyOn(DrawCommand.prototype, "execute"); // Don't execute any commands, just watch what gets added to the frustum commands list
+
+ scene.renderForSpecs();
+ expect(getFrustumCommandsLength(scene, Pass.OPAQUE)).toBe(0);
+
+ scene.globe.translucency.enabled = true;
+ scene.globe.translucency.frontFaceAlpha = 0.5;
+
+ scene.renderForSpecs();
+ expect(getFrustumCommandsLength(scene, Pass.OPAQUE)).toBe(1);
+
+ scene.destroyForSpecs();
+ });
+
+ it("does not render environment when camera is underground and translucency is disabled", function () {
+ var scene = createScene();
+ var globe = new Globe();
+ scene.globe = globe;
+ scene.sun = new Sun();
+
+ // Look underground at the sun
+ scene.camera.setView({
+ destination: new Cartesian3(
+ 2838477.9315700866,
+ -4939120.816857662,
+ 1978094.4576285738
+ ),
+ orientation: new HeadingPitchRoll(
+ 5.955798516387474,
+ -1.0556025616093283,
+ 0.39098563693868016
+ ),
+ });
+
+ return updateGlobeUntilDone(scene).then(function () {
+ var time = JulianDate.fromIso8601(
+ "2020-04-25T03:07:26.04924034334544558Z"
+ );
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+ scene.renderForSpecs(time);
+
+ expect(scene.environmentState.isSunVisible).toBe(true);
+ globe.translucency.enabled = false;
+ scene.renderForSpecs(time);
+ expect(scene.environmentState.isSunVisible).toBe(false);
+ scene.destroyForSpecs(time);
+ });
+ });
+
+ it("renders globe with translucency", function () {
+ var scene = createScene();
+ var globe = new Globe();
+ scene.globe = globe;
+
+ scene.camera.setView({
+ destination: new Cartesian3(
+ 2764681.3022502237,
+ -20999839.371941473,
+ 14894754.464869803
+ ),
+ orientation: new HeadingPitchRoll(
+ 6.283185307179586,
+ -1.5687983447998315,
+ 0
+ ),
+ });
+
+ return updateGlobeUntilDone(scene).then(function () {
+ var opaqueColor;
+ expect(scene).toRenderAndCall(function (rgba) {
+ opaqueColor = rgba;
+ });
+
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+
+ expect(scene).toRenderAndCall(function (rgba) {
+ expect(rgba).not.toEqual(opaqueColor);
+ });
+ });
+ });
+
+ it("renders ground primitive on translucent globe", function () {
+ var scene = createScene();
+ var globe = new Globe();
+ scene.globe = globe;
+ globe.baseColor = Color.BLACK;
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+
+ scene.camera.setView({
+ destination: new Cartesian3(
+ -557278.4840232887,
+ -6744284.200717078,
+ 2794079.461722868
+ ),
+ orientation: new HeadingPitchRoll(
+ 6.283185307179586,
+ -1.5687983448015541,
+ 0
+ ),
+ });
+
+ var redRectangleInstance = new GeometryInstance({
+ geometry: new RectangleGeometry({
+ rectangle: Rectangle.fromDegrees(-110.0, 20.0, -80.0, 25.0),
+ vertexFormat: PerInstanceColorAppearance.VERTEX_FORMAT,
+ }),
+ attributes: {
+ color: ColorGeometryInstanceAttribute.fromColor(
+ new Color(1.0, 0.0, 0.0, 0.5)
+ ),
+ },
+ });
+
+ scene.primitives.add(
+ new GroundPrimitive({
+ geometryInstances: [redRectangleInstance],
+ appearance: new PerInstanceColorAppearance({
+ closed: true,
+ }),
+ asynchronous: false,
+ })
+ );
+
+ return updateGlobeUntilDone(scene).then(function () {
+ expect(scene).toRenderAndCall(function (rgba) {
+ expect(rgba[0]).toBeGreaterThan(0);
+ });
+ });
+ });
+
+ it("picks ground primitive on translucent globe", function () {
+ var scene = createScene();
+ var globe = new Globe();
+ scene.globe = globe;
+ globe.baseColor = Color.BLACK;
+ globe.translucency.enabled = true;
+ globe.translucency.frontFaceAlpha = 0.5;
+
+ scene.camera.setView({
+ destination: new Cartesian3(
+ -557278.4840232887,
+ -6744284.200717078,
+ 2794079.461722868
+ ),
+ orientation: new HeadingPitchRoll(
+ 6.283185307179586,
+ -1.5687983448015541,
+ 0
+ ),
+ });
+
+ var redRectangleInstance = new GeometryInstance({
+ geometry: new RectangleGeometry({
+ rectangle: Rectangle.fromDegrees(-110.0, 20.0, -80.0, 25.0),
+ vertexFormat: PerInstanceColorAppearance.VERTEX_FORMAT,
+ }),
+ attributes: {
+ color: ColorGeometryInstanceAttribute.fromColor(
+ new Color(1.0, 0.0, 0.0, 0.5)
+ ),
+ },
+ });
+
+ var primitive = scene.primitives.add(
+ new GroundPrimitive({
+ geometryInstances: [redRectangleInstance],
+ appearance: new PerInstanceColorAppearance({
+ closed: true,
+ }),
+ asynchronous: false,
+ })
+ );
+
+ return updateGlobeUntilDone(scene).then(function () {
+ expect(scene).toPickPrimitive(primitive);
+ });
+ });
},
+
"WebGL"
);
diff --git a/Specs/Scene/ScreenSpaceCameraControllerSpec.js b/Specs/Scene/ScreenSpaceCameraControllerSpec.js
index cc0ea14890db..4881111f4d22 100644
--- a/Specs/Scene/ScreenSpaceCameraControllerSpec.js
+++ b/Specs/Scene/ScreenSpaceCameraControllerSpec.js
@@ -34,6 +34,8 @@ describe("Scene/ScreenSpaceCameraController", function () {
this.mapProjection = new GeographicProjection(ellipsoid);
this.terrainExaggeration = 1.0;
this.screenSpaceCameraController = undefined;
+ this.cameraUnderground = false;
+ this.globeHeight = 0.0;
}
function MockGlobe(ellipsoid) {
@@ -55,6 +57,7 @@ describe("Scene/ScreenSpaceCameraController", function () {
tilesWaitingForChildren: 0,
},
};
+ this.show = true;
}
beforeAll(function () {
usePointerEvents = FeatureDetection.supportsPointerEvents();
@@ -183,6 +186,8 @@ describe("Scene/ScreenSpaceCameraController", function () {
mapProjection: scene.mapProjection,
};
+ scene.cameraUnderground = false;
+
var maxRadii = ellipsoid.maximumRadius;
var frustum = new OrthographicOffCenterFrustum();
frustum.right = maxRadii * Math.PI;
@@ -210,6 +215,9 @@ describe("Scene/ScreenSpaceCameraController", function () {
mapProjection: scene.mapProjection,
};
+ scene.cameraUnderground = false;
+ controller.enableCollisionDetection = true;
+
var maxRadii = ellipsoid.maximumRadius;
camera.position = new Cartesian3(0.0, 0.0, maxRadii);
camera.direction = Cartesian3.negate(Cartesian3.UNIT_Z, new Cartesian3());
@@ -217,6 +225,31 @@ describe("Scene/ScreenSpaceCameraController", function () {
camera.right = Cartesian3.clone(Cartesian3.UNIT_X);
}
+ function setUpCVUnderground() {
+ scene.mode = SceneMode.COLUMBUS_VIEW;
+
+ var ellipsoid = Ellipsoid.WGS84;
+ scene.globe = new MockGlobe(ellipsoid);
+ scene.mapProjection = new GeographicProjection(ellipsoid);
+
+ scene.frameState = {
+ mode: scene.mode,
+ mapProjection: scene.mapProjection,
+ };
+
+ scene.cameraUnderground = true;
+ controller.enableCollisionDetection = false;
+
+ camera.position = new Cartesian3(0.0, 0.0, -100.0);
+ camera.direction = Cartesian3.clone(Cartesian3.UNIT_Z);
+ camera.up = Cartesian3.clone(Cartesian3.UNIT_Y);
+ camera.right = Cartesian3.cross(
+ camera.direction,
+ camera.up,
+ new Cartesian3()
+ );
+ }
+
function setUp3D() {
scene.mode = SceneMode.SCENE3D;
@@ -227,6 +260,21 @@ describe("Scene/ScreenSpaceCameraController", function () {
mode: scene.mode,
mapProjection: scene.mapProjection,
};
+
+ scene.cameraUnderground = false;
+ controller.enableCollisionDetection = true;
+ }
+
+ function setUp3DUnderground() {
+ setUp3D();
+ scene.globe = new MockGlobe(scene.mapProjection.ellipsoid);
+ scene.cameraUnderground = true;
+ controller.enableCollisionDetection = false;
+
+ camera.setView({ destination: Camera.DEFAULT_VIEW_RECTANGLE });
+ var positionCart = Ellipsoid.WGS84.cartesianToCartographic(camera.position);
+ positionCart.height = -100.0;
+ camera.position = Ellipsoid.WGS84.cartographicToCartesian(positionCart);
}
it("constructor throws without a scene", function () {
@@ -718,6 +766,26 @@ describe("Scene/ScreenSpaceCameraController", function () {
expect(position.z).toEqual(camera.position.z);
});
+ it("translates in Columbus view when camera is underground", function () {
+ setUpCVUnderground();
+
+ var position = Cartesian3.clone(camera.position);
+ var startPosition = new Cartesian2(
+ canvas.clientWidth / 2,
+ canvas.clientHeight / 4
+ );
+ var endPosition = new Cartesian2(
+ canvas.clientWidth / 2,
+ canvas.clientHeight / 2
+ );
+
+ moveMouse(MouseButtons.LEFT, startPosition, endPosition);
+ updateController();
+ expect(position.x).toEqual(camera.position.x);
+ expect(position.y).not.toEqual(camera.position.y);
+ expect(position.z).toEqual(camera.position.z);
+ });
+
it("looks in Columbus view", function () {
setUpCV();
var position = Cartesian3.clone(camera.position);
@@ -804,6 +872,24 @@ describe("Scene/ScreenSpaceCameraController", function () {
expect(position.z).toBeLessThan(camera.position.z);
});
+ it("zoom in Columbus view when camera is underground", function () {
+ setUpCVUnderground();
+
+ var position = Cartesian3.clone(camera.position);
+ var startPosition = new Cartesian2(
+ canvas.clientWidth / 2,
+ canvas.clientHeight / 4
+ );
+ var endPosition = new Cartesian2(
+ canvas.clientWidth / 2,
+ canvas.clientHeight / 2
+ );
+
+ moveMouse(MouseButtons.RIGHT, startPosition, endPosition);
+ updateController();
+ expect(position.z).toBeLessThan(camera.position.z);
+ });
+
it("rotates in Columbus view", function () {
setUpCV();
var startPosition = new Cartesian2(
@@ -869,6 +955,25 @@ describe("Scene/ScreenSpaceCameraController", function () {
).toEqualEpsilon(camera.up, CesiumMath.EPSILON14);
});
+ it("rotates in Columbus view when camera is underground", function () {
+ setUpCVUnderground();
+ camera.position.y = -100.0;
+
+ var position = Cartesian3.clone(camera.position);
+ var startPosition = new Cartesian2(
+ canvas.clientWidth / 2,
+ canvas.clientHeight / 2
+ );
+ var endPosition = new Cartesian2(
+ (3 * canvas.clientWidth) / 8,
+ (3 * canvas.clientHeight) / 8
+ );
+
+ moveMouse(MouseButtons.MIDDLE, startPosition, endPosition);
+ updateController();
+ expect(camera.position).not.toEqual(position);
+ });
+
it("zooms in Columus view with camera transform set", function () {
setUpCV();
@@ -988,6 +1093,28 @@ describe("Scene/ScreenSpaceCameraController", function () {
).toEqualEpsilon(camera.up, CesiumMath.EPSILON14);
});
+ it("strafes in 3D when camera is underground", function () {
+ setUp3DUnderground();
+
+ var position = Cartesian3.clone(camera.position);
+ var direction = Cartesian3.clone(camera.direction);
+
+ var startPosition = new Cartesian2(
+ canvas.clientWidth / 2,
+ canvas.clientHeight / 2
+ );
+ var endPosition = new Cartesian2(
+ (3 * canvas.clientWidth) / 8,
+ (3 * canvas.clientHeight) / 8
+ );
+
+ moveMouse(MouseButtons.LEFT, startPosition, endPosition);
+ updateController();
+
+ expect(camera.position).not.toEqual(position);
+ expect(camera.direction).toEqual(direction);
+ });
+
it("rotates in 3D", function () {
setUp3D();
var position = Cartesian3.clone(camera.position);
@@ -1225,6 +1352,34 @@ describe("Scene/ScreenSpaceCameraController", function () {
expect(frustumWidth).toBeLessThan(camera.frustum.width);
});
+ it("zoom in 3D when camera is underground", function () {
+ setUp3DUnderground();
+
+ var position = Cartesian3.clone(camera.position);
+ var direction = Cartesian3.clone(camera.direction);
+
+ var startPosition = new Cartesian2(
+ canvas.clientWidth / 2,
+ canvas.clientHeight / 4
+ );
+ var endPosition = new Cartesian2(
+ canvas.clientWidth / 2,
+ canvas.clientHeight / 2
+ );
+
+ moveMouse(MouseButtons.RIGHT, startPosition, endPosition);
+ updateController();
+ var vector = Cartesian3.subtract(
+ camera.position,
+ position,
+ new Cartesian3()
+ );
+ var normalizedVector = Cartesian3.normalize(vector, vector);
+
+ expect(normalizedVector).toEqualEpsilon(direction, CesiumMath.EPSILON2);
+ expect(camera.direction).toEqualEpsilon(direction, CesiumMath.EPSILON6);
+ });
+
it("tilts in 3D", function () {
setUp3D();
var position = Cartesian3.clone(camera.position);
@@ -1319,6 +1474,27 @@ describe("Scene/ScreenSpaceCameraController", function () {
).toEqualEpsilon(camera.up, CesiumMath.EPSILON14);
});
+ it("tilts in 3D when camera is underground", function () {
+ setUp3DUnderground();
+
+ var position = Cartesian3.clone(camera.position);
+ var direction = Cartesian3.clone(camera.direction);
+
+ var startPosition = new Cartesian2(
+ canvas.clientWidth / 2,
+ canvas.clientHeight / 2
+ );
+ var endPosition = new Cartesian2(
+ canvas.clientWidth / 2,
+ canvas.clientHeight / 4
+ );
+
+ moveMouse(MouseButtons.MIDDLE, startPosition, endPosition);
+ updateController();
+ expect(camera.position).not.toEqual(position);
+ expect(camera.direction).not.toEqual(direction);
+ });
+
it("looks in 3D", function () {
setUp3D();
var position = Cartesian3.clone(camera.position);
diff --git a/Specs/Scene/ShadowVolumeAppearanceSpec.js b/Specs/Scene/ShadowVolumeAppearanceSpec.js
index fd5e69eff2a0..deba2c4feb9b 100644
--- a/Specs/Scene/ShadowVolumeAppearanceSpec.js
+++ b/Specs/Scene/ShadowVolumeAppearanceSpec.js
@@ -21,7 +21,7 @@ describe("Scene/ShadowVolumeAppearance", function () {
"attribute float batchId;\n" +
"void main() {\n" +
" vec4 position = czm_computePosition();\n" +
- " gl_Position = czm_depthClampFarPlane(czm_modelViewProjectionRelativeToEye * position);\n" +
+ " gl_Position = czm_depthClamp(czm_modelViewProjectionRelativeToEye * position);\n" +
"}\n";
var unitSphereEllipsoid = Ellipsoid.UNIT_SPHERE;
diff --git a/Specs/Scene/SkyAtmosphereSpec.js b/Specs/Scene/SkyAtmosphereSpec.js
index 71b98e38971f..016f32779427 100644
--- a/Specs/Scene/SkyAtmosphereSpec.js
+++ b/Specs/Scene/SkyAtmosphereSpec.js
@@ -57,7 +57,7 @@ describe(
var command = s.update(scene.frameState);
expect(command).toBeDefined();
- expect(s._cameraAndRadiiAndDynamicAtmosphereColor.w).toBe(1);
+ expect(s._radiiAndDynamicAtmosphereColor.z).toBe(1);
command.execute(scene.context); // Not reliable enough across browsers to test pixels
s.destroy();
@@ -72,7 +72,7 @@ describe(
var command = s.update(scene.frameState);
expect(command).toBeDefined();
- expect(s._cameraAndRadiiAndDynamicAtmosphereColor.w).toBe(2);
+ expect(s._radiiAndDynamicAtmosphereColor.z).toBe(2);
command.execute(scene.context); // Not reliable enough across browsers to test pixels
s.destroy();
@@ -87,7 +87,7 @@ describe(
var command = s.update(scene.frameState);
expect(command).toBeDefined();
- expect(s._cameraAndRadiiAndDynamicAtmosphereColor.w).toBe(0);
+ expect(s._radiiAndDynamicAtmosphereColor.z).toBe(0);
command.execute(scene.context); // Not reliable enough across browsers to test pixels
s.destroy();
diff --git a/Specs/Scene/computeFlyToLocationForRectangleSpec.js b/Specs/Scene/computeFlyToLocationForRectangleSpec.js
index 24c4069c14ab..872c84c1a628 100644
--- a/Specs/Scene/computeFlyToLocationForRectangleSpec.js
+++ b/Specs/Scene/computeFlyToLocationForRectangleSpec.js
@@ -1,10 +1,10 @@
-import { EllipsoidTerrainProvider } from "../../Source/Cesium.js";
import { Rectangle } from "../../Source/Cesium.js";
import { computeFlyToLocationForRectangle } from "../../Source/Cesium.js";
import { Globe } from "../../Source/Cesium.js";
import { SceneMode } from "../../Source/Cesium.js";
import createScene from "../createScene.js";
import { when } from "../../Source/Cesium.js";
+import MockTerrainProvider from "../MockTerrainProvider.js";
describe("Scene/computeFlyToLocationForRectangle", function () {
var scene;
@@ -19,7 +19,7 @@ describe("Scene/computeFlyToLocationForRectangle", function () {
function sampleTest(sceneMode) {
//Pretend we have terrain with availability.
- var terrainProvider = new EllipsoidTerrainProvider();
+ var terrainProvider = new MockTerrainProvider();
terrainProvider.availability = {};
scene.globe = new Globe();
@@ -86,7 +86,7 @@ describe("Scene/computeFlyToLocationForRectangle", function () {
});
it("returns height above ellipsoid when in 2D", function () {
- var terrainProvider = new EllipsoidTerrainProvider();
+ var terrainProvider = new MockTerrainProvider();
terrainProvider.availability = {};
scene.globe = new Globe();
@@ -111,7 +111,7 @@ describe("Scene/computeFlyToLocationForRectangle", function () {
it("returns height above ellipsoid when terrain not available", function () {
scene.globe = new Globe();
- scene.terrainProvider = new EllipsoidTerrainProvider();
+ scene.terrainProvider = new MockTerrainProvider();
var rectangle = new Rectangle(0.2, 0.4, 0.6, 0.8);
spyOn(computeFlyToLocationForRectangle, "_sampleTerrainMostDetailed");
@@ -130,7 +130,7 @@ describe("Scene/computeFlyToLocationForRectangle", function () {
});
it("waits for terrain to become ready", function () {
- var terrainProvider = new EllipsoidTerrainProvider();
+ var terrainProvider = new MockTerrainProvider();
spyOn(terrainProvider.readyPromise, "then").and.callThrough();
scene.globe = new Globe();
diff --git a/Specs/TypeScript/index.ts b/Specs/TypeScript/index.ts
new file mode 100644
index 000000000000..97f13e0a3e3e
--- /dev/null
+++ b/Specs/TypeScript/index.ts
@@ -0,0 +1,379 @@
+import {
+ ArcGisMapServerImageryProvider,
+ ArcGISTiledElevationTerrainProvider,
+ BingMapsImageryProvider,
+ BoxGeometry,
+ BoxOutlineGeometry,
+ CallbackProperty,
+ Camera,
+ Cartesian3,
+ CesiumTerrainProvider,
+ CheckerboardMaterialProperty,
+ CircleGeometry,
+ CircleOutlineGeometry,
+ ColorMaterialProperty,
+ CompositeMaterialProperty,
+ CompositePositionProperty,
+ CompositeProperty,
+ ConstantPositionProperty,
+ ConstantProperty,
+ CoplanarPolygonGeometry,
+ CoplanarPolygonOutlineGeometry,
+ CorridorGeometry,
+ CorridorOutlineGeometry,
+ CustomDataSource,
+ CylinderGeometry,
+ CylinderOutlineGeometry,
+ CzmlDataSource,
+ DataSource,
+ EllipseGeometry,
+ EllipseOutlineGeometry,
+ EllipsoidGeometry,
+ EllipsoidOutlineGeometry,
+ EllipsoidTerrainProvider,
+ EntityCollection,
+ FrustumGeometry,
+ FrustumOutlineGeometry,
+ GeoJsonDataSource,
+ GeometryInstance,
+ GoogleEarthEnterpriseImageryProvider,
+ GoogleEarthEnterpriseMapsProvider,
+ GoogleEarthEnterpriseMetadata,
+ GoogleEarthEnterpriseTerrainProvider,
+ GridImageryProvider,
+ GridMaterialProperty,
+ GroundPolylineGeometry,
+ ImageMaterialProperty,
+ ImageryProvider,
+ IonImageryProvider,
+ KmlDataSource,
+ MapboxImageryProvider,
+ MapboxStyleImageryProvider,
+ MaterialProperty,
+ NodeTransformationProperty,
+ OpenStreetMapImageryProvider,
+ OrthographicFrustum,
+ PlaneGeometry,
+ PlaneOutlineGeometry,
+ PolygonGeometry,
+ PolygonHierarchy,
+ PolygonOutlineGeometry,
+ PolylineArrowMaterialProperty,
+ PolylineDashMaterialProperty,
+ PolylineGeometry,
+ PolylineGlowMaterialProperty,
+ PolylineOutlineMaterialProperty,
+ PolylineVolumeGeometry,
+ PolylineVolumeOutlineGeometry,
+ PositionProperty,
+ PositionPropertyArray,
+ Property,
+ PropertyArray,
+ PropertyBag,
+ Quaternion,
+ Rectangle,
+ RectangleGeometry,
+ RectangleOutlineGeometry,
+ ReferenceProperty,
+ SampledPositionProperty,
+ SampledProperty,
+ Scene,
+ SimplePolylineGeometry,
+ SingleTileImageryProvider,
+ SphereGeometry,
+ SphereOutlineGeometry,
+ StripeMaterialProperty,
+ TerrainProvider,
+ TileCoordinatesImageryProvider,
+ TileMapServiceImageryProvider,
+ TimeIntervalCollectionPositionProperty,
+ TimeIntervalCollectionProperty,
+ UrlTemplateImageryProvider,
+ VelocityOrientationProperty,
+ VelocityVectorProperty,
+ VRTheWorldTerrainProvider,
+ WallGeometry,
+ WallOutlineGeometry,
+ WebMapServiceImageryProvider,
+ WebMapTileServiceImageryProvider,
+} from "cesium";
+
+// Verify ImageryProvider instances conform to the expected interface
+let imageryProvider: ImageryProvider;
+imageryProvider = new WebMapServiceImageryProvider({ url: "", layers: "0" });
+imageryProvider = new BingMapsImageryProvider({ url: "" });
+imageryProvider = new ArcGisMapServerImageryProvider({ url: "" });
+imageryProvider = new BingMapsImageryProvider({ url: "" });
+imageryProvider = new OpenStreetMapImageryProvider({ url: "" });
+imageryProvider = new TileMapServiceImageryProvider({ url: "" });
+imageryProvider = new GridImageryProvider({ url: "" });
+imageryProvider = new IonImageryProvider({ assetId: 2 });
+imageryProvider = new MapboxImageryProvider({ mapId: "" });
+imageryProvider = new MapboxStyleImageryProvider({ styleId: "" });
+imageryProvider = new SingleTileImageryProvider({ url: "" });
+imageryProvider = new TileCoordinatesImageryProvider();
+imageryProvider = new UrlTemplateImageryProvider({ url: "" });
+imageryProvider = new WebMapServiceImageryProvider({ url: "", layers: "" });
+imageryProvider = new GoogleEarthEnterpriseImageryProvider({
+ url: "",
+ metadata: new GoogleEarthEnterpriseMetadata(""),
+});
+imageryProvider = new GoogleEarthEnterpriseMapsProvider({
+ url: "",
+ channel: 1,
+});
+imageryProvider = new WebMapTileServiceImageryProvider({
+ url: "",
+ layer: "",
+ style: "",
+ tileMatrixSetID: "",
+});
+
+// Verify TerrainProvider instances conform to the expected interface
+let terrainProvider: TerrainProvider;
+terrainProvider = new ArcGISTiledElevationTerrainProvider({ url: "" });
+terrainProvider = new CesiumTerrainProvider({ url: "" });
+terrainProvider = new EllipsoidTerrainProvider();
+terrainProvider = new VRTheWorldTerrainProvider({ url: "" });
+terrainProvider = new GoogleEarthEnterpriseTerrainProvider({
+ url: "",
+ metadata: new GoogleEarthEnterpriseMetadata(""),
+});
+
+// Verify DataSource instances conform to the expected interface
+let dataSource: DataSource;
+dataSource = new CzmlDataSource();
+dataSource = new GeoJsonDataSource();
+dataSource = new KmlDataSource({
+ canvas: document.createElement("canvas"),
+ camera: new Camera(new Scene()),
+});
+dataSource = new CustomDataSource();
+
+// Verify Property instances conform to the expected interface
+let property: Property;
+property = new CallbackProperty(() => 0, false);
+property = new ConstantProperty(1);
+property = new TimeIntervalCollectionProperty();
+property = new CompositeProperty();
+property = new SampledProperty(Cartesian3);
+property = new PropertyBag();
+property = new PropertyArray();
+property = new PositionProperty();
+property = new MaterialProperty();
+property = new VelocityVectorProperty();
+property = new VelocityOrientationProperty();
+property = new PositionPropertyArray();
+property = new NodeTransformationProperty();
+property = new ReferenceProperty(new EntityCollection(), "object1", [
+ "billboard",
+ "scale",
+]);
+
+// Verify PositionProperty instances conform to the expected PositionProperty and Property interfaces
+let positionProperty: PositionProperty;
+property = positionProperty = new SampledPositionProperty();
+property = positionProperty = new CompositePositionProperty();
+property = positionProperty = new ConstantPositionProperty();
+property = positionProperty = new TimeIntervalCollectionPositionProperty();
+property = positionProperty = new ReferenceProperty(
+ new EntityCollection(),
+ "object1",
+ ["billboard", "scale"]
+);
+
+// Verify MaterialProperty instances conform to the expected MaterialProperty and Property interfaces
+let materialProperty: MaterialProperty;
+property = materialProperty = new ColorMaterialProperty();
+property = materialProperty = new CompositeMaterialProperty();
+property = materialProperty = new GridMaterialProperty();
+property = materialProperty = new ImageMaterialProperty();
+property = materialProperty = new PolylineGlowMaterialProperty();
+property = materialProperty = new PolylineOutlineMaterialProperty();
+property = materialProperty = new StripeMaterialProperty();
+property = materialProperty = new CheckerboardMaterialProperty();
+property = materialProperty = new PolylineDashMaterialProperty();
+property = materialProperty = new PolylineArrowMaterialProperty();
+
+// Verify GeometryInstance can be take XXXGeometry objects.
+let geometryInstance: GeometryInstance;
+
+geometryInstance = new GeometryInstance({
+ geometry: new BoxGeometry({
+ minimum: new Cartesian3(0, 0, 0),
+ maximum: new Cartesian3(1, 1, 1),
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new BoxOutlineGeometry({
+ minimum: new Cartesian3(0, 0, 0),
+ maximum: new Cartesian3(1, 1, 1),
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new CircleGeometry({
+ center: new Cartesian3(0, 0, 0),
+ radius: 10,
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new CircleOutlineGeometry({
+ center: new Cartesian3(0, 0, 0),
+ radius: 10,
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new CoplanarPolygonGeometry({
+ polygonHierarchy: new PolygonHierarchy(),
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new CoplanarPolygonOutlineGeometry({
+ polygonHierarchy: new PolygonHierarchy(),
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new CorridorGeometry({ positions: [], width: 1 }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new CorridorOutlineGeometry({ positions: [], width: 1 }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new CylinderGeometry({
+ bottomRadius: 10,
+ length: 10,
+ topRadius: 10,
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new CylinderOutlineGeometry({
+ bottomRadius: 10,
+ length: 10,
+ topRadius: 10,
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new EllipseGeometry({
+ center: Cartesian3.ZERO,
+ semiMajorAxis: 1,
+ semiMinorAxis: 10,
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new EllipseOutlineGeometry({
+ center: Cartesian3.ZERO,
+ semiMajorAxis: 1,
+ semiMinorAxis: 10,
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new EllipsoidGeometry(),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new EllipsoidOutlineGeometry(),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new FrustumGeometry({
+ frustum: new OrthographicFrustum(),
+ orientation: new Quaternion(),
+ origin: Cartesian3.ZERO,
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new FrustumOutlineGeometry({
+ frustum: new OrthographicFrustum(),
+ orientation: new Quaternion(),
+ origin: Cartesian3.ZERO,
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new GroundPolylineGeometry({ positions: [] }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new PlaneGeometry(),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new PlaneOutlineGeometry(),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new PolygonGeometry({ polygonHierarchy: new PolygonHierarchy() }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new PolygonOutlineGeometry({
+ polygonHierarchy: new PolygonHierarchy(),
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new PolylineGeometry({
+ positions: [],
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new PolylineVolumeGeometry({
+ polylinePositions: [],
+ shapePositions: [],
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new PolylineVolumeOutlineGeometry({
+ polylinePositions: [],
+ shapePositions: [],
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new RectangleGeometry({ rectangle: Rectangle.MAX_VALUE }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new RectangleOutlineGeometry({ rectangle: Rectangle.MAX_VALUE }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new SimplePolylineGeometry({
+ positions: [],
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new SphereGeometry(),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new SphereOutlineGeometry(),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new WallGeometry({
+ positions: [],
+ }),
+});
+
+geometryInstance = new GeometryInstance({
+ geometry: new WallOutlineGeometry({
+ positions: [],
+ }),
+});
diff --git a/Specs/TypeScript/tsconfig.json b/Specs/TypeScript/tsconfig.json
new file mode 100644
index 000000000000..1b1b0d541573
--- /dev/null
+++ b/Specs/TypeScript/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "compilerOptions": {
+ "noEmit": true,
+ "types": [],
+ "strict": true
+ },
+ "include": [
+ "index.ts",
+ "../../Source/Cesium.d.ts"
+ ]
+}
\ No newline at end of file
diff --git a/Tools/jsdoc/cesium_template/publish.js b/Tools/jsdoc/cesium_template/publish.js
index dd7d1163c5e8..1cd1c6960ec8 100644
--- a/Tools/jsdoc/cesium_template/publish.js
+++ b/Tools/jsdoc/cesium_template/publish.js
@@ -120,7 +120,7 @@ function addAttribs(f) {
attrib +
'">' +
htmlsafe(attrib) +
- ""
+ " "
);
})
.join("");
@@ -217,6 +217,7 @@ function buildNav(members) {
var items = members.modules
.concat(members.classes)
+ .concat(members.globals)
.concat(members.namespaces)
.sort(function (a, b) {
return a.longname.toLowerCase().localeCompare(b.longname.toLowerCase());
@@ -436,6 +437,7 @@ exports.publish = function (taffyData, opts, tutorials) {
var classes = taffy(members.classes);
var modules = taffy(members.modules);
var namespaces = taffy(members.namespaces);
+ var globals = taffy(members.globals);
var typesJson = {};
@@ -450,6 +452,10 @@ exports.publish = function (taffyData, opts, tutorials) {
items = helper.find(namespaces, { longname: longname });
}
+ if (!items.length) {
+ items = helper.find(globals, { longname: longname });
+ }
+
if (items.length) {
var title = items[0].name;
var filename = helper.longnameToUrl[longname];
diff --git a/Tools/jsdoc/cesium_template/static/javascript/cesiumDoc.js b/Tools/jsdoc/cesium_template/static/javascript/cesiumDoc.js
index b6ba444a5a9c..ecff98ccacbf 100644
--- a/Tools/jsdoc/cesium_template/static/javascript/cesiumDoc.js
+++ b/Tools/jsdoc/cesium_template/static/javascript/cesiumDoc.js
@@ -47,8 +47,11 @@
for (var i = 0; i < links.length; i++) {
var link = links[i];
var prefix = link.href.split("?")[0];
+ var parts = prefix.split("#");
link.href =
- prefix + (searchTerm === "" ? "" : "?classFilter=" + searchTerm);
+ parts[0] +
+ (searchTerm === "" ? "" : "?classFilter=" + searchTerm) +
+ (parts[1] ? "#" + parts[1] : "");
}
}
diff --git a/Tools/jsdoc/cesium_template/static/styles/jsdoc-default.css b/Tools/jsdoc/cesium_template/static/styles/jsdoc-default.css
index e28aab65849e..7bbda2ddc887 100644
--- a/Tools/jsdoc/cesium_template/static/styles/jsdoc-default.css
+++ b/Tools/jsdoc/cesium_template/static/styles/jsdoc-default.css
@@ -603,7 +603,6 @@ span.attribute-constant {
color: #fff;
font-size: 0.7em;
padding: 2px 4px;
- margin-right: 8px;
margin-bottom: 1px;
position: relative;
top: -1px;
diff --git a/Tools/jsdoc/conf.json b/Tools/jsdoc/conf.json
index 84d69edfb90c..f775c5099463 100644
--- a/Tools/jsdoc/conf.json
+++ b/Tools/jsdoc/conf.json
@@ -3,12 +3,19 @@
"allowUnknownTags": false
},
"source": {
- "include": ["Source"],
- "exclude": ["Source/ThirdParty", "Source/Workers"],
+ "include": [
+ "Source"
+ ],
+ "exclude": [
+ "Source/ThirdParty",
+ "Source/Workers"
+ ],
"includePattern": ".+\\.js(doc)?$",
"excludePattern": "(^|\\/|\\\\)_"
},
- "plugins": ["./Tools/jsdoc/cesiumTags"],
+ "plugins": [
+ "./Tools/jsdoc/cesiumTags"
+ ],
"templates": {
"cleverLinks": true,
"default": {
@@ -21,4 +28,4 @@
"template": "./Tools/jsdoc/cesium_template",
"recurse": true
}
-}
+}
\ No newline at end of file
diff --git a/Tools/jsdoc/ts-conf.json b/Tools/jsdoc/ts-conf.json
new file mode 100644
index 000000000000..22c743f44ba5
--- /dev/null
+++ b/Tools/jsdoc/ts-conf.json
@@ -0,0 +1,33 @@
+{
+ "tags": {
+ "allowUnknownTags": false
+ },
+ "source": {
+ "include": [
+ "Source"
+ ],
+ "exclude": [
+ "Source/ThirdParty",
+ "Source/Workers"
+ ],
+ "includePattern": ".+\\.js(doc)?$",
+ "excludePattern": "(^|\\/|\\\\)_"
+ },
+ "plugins": [
+ "./Tools/jsdoc/cesiumTags",
+ "tsd-jsdoc/dist/plugin"
+ ],
+ "templates": {
+ "cleverLinks": true,
+ "default": {
+ "outputSourceFiles": false
+ },
+ "sourceUrl": "https://github.com/CesiumGS/cesium/blob/{version}/Source/{filename}"
+ },
+ "opts": {
+ "destination": "Source",
+ "template": "tsd-jsdoc/dist",
+ "outFile": "Cesium.d.ts",
+ "recurse": true
+ }
+}
diff --git a/Tools/jsdoc/tsconfig.json b/Tools/jsdoc/tsconfig.json
new file mode 100644
index 000000000000..2cd41ea62053
--- /dev/null
+++ b/Tools/jsdoc/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "compilerOptions": {
+ "noEmit": true,
+ "types": []
+ },
+ "files": [
+ "../../Source/Cesium.d.ts"
+ ]
+}
diff --git a/gulpfile.cjs b/gulpfile.cjs
index 6ae377e8d828..4e159b3c826c 100644
--- a/gulpfile.cjs
+++ b/gulpfile.cjs
@@ -1,1446 +1,1889 @@
/*eslint-env node*/
-'use strict';
-
-var fs = require('fs');
-var path = require('path');
-var os = require('os');
-var child_process = require('child_process');
-var crypto = require('crypto');
-var zlib = require('zlib');
-var readline = require('readline');
-var request = require('request');
-
-var globby = require('globby');
-var gulpTap = require('gulp-tap');
-var gulpUglify = require('gulp-uglify');
-var open = require('open');
-var rimraf = require('rimraf');
-var glslStripComments = require('glsl-strip-comments');
-var mkdirp = require('mkdirp');
-var mergeStream = require('merge-stream');
-var streamToPromise = require('stream-to-promise');
-var gulp = require('gulp');
-var gulpInsert = require('gulp-insert');
-var gulpZip = require('gulp-zip');
-var gulpRename = require('gulp-rename');
-var gulpReplace = require('gulp-replace');
-var Promise = require('bluebird');
-var Karma = require('karma');
-var yargs = require('yargs');
-var AWS = require('aws-sdk');
-var mime = require('mime');
-var rollup = require('rollup');
-var rollupPluginStripPragma = require('rollup-plugin-strip-pragma');
-var rollupPluginExternalGlobals = require('rollup-plugin-external-globals');
-var rollupPluginUglify = require('rollup-plugin-uglify');
-var cleanCSS = require('gulp-clean-css');
-
-var packageJson = require('./package.json');
+"use strict";
+
+var fs = require("fs");
+var path = require("path");
+var os = require("os");
+var child_process = require("child_process");
+var crypto = require("crypto");
+var zlib = require("zlib");
+var readline = require("readline");
+var request = require("request");
+
+var globby = require("globby");
+var gulpTap = require("gulp-tap");
+var gulpUglify = require("gulp-uglify");
+var open = require("open");
+var rimraf = require("rimraf");
+var glslStripComments = require("glsl-strip-comments");
+var mkdirp = require("mkdirp");
+var mergeStream = require("merge-stream");
+var streamToPromise = require("stream-to-promise");
+var gulp = require("gulp");
+var gulpInsert = require("gulp-insert");
+var gulpZip = require("gulp-zip");
+var gulpRename = require("gulp-rename");
+var gulpReplace = require("gulp-replace");
+var Promise = require("bluebird");
+var Karma = require("karma");
+var yargs = require("yargs");
+var AWS = require("aws-sdk");
+var mime = require("mime");
+var rollup = require("rollup");
+var rollupPluginStripPragma = require("rollup-plugin-strip-pragma");
+var rollupPluginExternalGlobals = require("rollup-plugin-external-globals");
+var rollupPluginUglify = require("rollup-plugin-uglify");
+var cleanCSS = require("gulp-clean-css");
+var typescript = require("typescript");
+
+var packageJson = require("./package.json");
var version = packageJson.version;
if (/\.0$/.test(version)) {
- version = version.substring(0, version.length - 2);
+ version = version.substring(0, version.length - 2);
}
-var karmaConfigFile = path.join(__dirname, 'Specs/karma.conf.js');
-var travisDeployUrl = 'http://cesium-dev.s3-website-us-east-1.amazonaws.com/cesium/';
+var karmaConfigFile = path.join(__dirname, "Specs/karma.conf.js");
+var travisDeployUrl =
+ "http://cesium-dev.s3-website-us-east-1.amazonaws.com/cesium/";
//Gulp doesn't seem to have a way to get the currently running tasks for setting
//per-task variables. We use the command line argument here to detect which task is being run.
var taskName = process.argv[2];
-var noDevelopmentGallery = taskName === 'release' || taskName === 'makeZipFile';
-var minifyShaders = taskName === 'minify' || taskName === 'minifyRelease' || taskName === 'release' || taskName === 'makeZipFile' || taskName === 'buildApps';
+var noDevelopmentGallery = taskName === "release" || taskName === "makeZipFile";
+var minifyShaders =
+ taskName === "minify" ||
+ taskName === "minifyRelease" ||
+ taskName === "release" ||
+ taskName === "makeZipFile" ||
+ taskName === "buildApps";
var verbose = yargs.argv.verbose;
var concurrency = yargs.argv.concurrency;
if (!concurrency) {
- concurrency = os.cpus().length;
+ concurrency = os.cpus().length;
}
-var sourceFiles = ['Source/**/*.js',
- '!Source/*.js',
- '!Source/Workers/**',
- '!Source/WorkersES6/**',
- 'Source/WorkersES6/createTaskProcessorWorker.js',
- '!Source/ThirdParty/Workers/**',
- '!Source/ThirdParty/google-earth-dbroot-parser.js',
- '!Source/ThirdParty/pako_inflate.js',
- '!Source/ThirdParty/crunch.js'];
-
-var watchedFiles = ['Source/**/*.js',
- '!Source/Cesium.js',
- '!Source/Build/**',
- '!Source/Shaders/**/*.js',
- 'Source/Shaders/**/*.glsl',
- '!Source/ThirdParty/Shaders/*.js',
- 'Source/ThirdParty/Shaders/*.glsl',
- '!Source/Workers/**',
- 'Source/Workers/cesiumWorkerBootstrapper.js',
- 'Source/Workers/transferTypedArrayTest.js',
- '!Specs/SpecList.js'];
-
-var filesToClean = ['Source/Cesium.js',
- 'Source/Shaders/**/*.js',
- 'Source/Workers/**',
- '!Source/Workers/cesiumWorkerBootstrapper.js',
- '!Source/Workers/transferTypedArrayTest.js',
- 'Source/ThirdParty/Shaders/*.js',
- 'Specs/SpecList.js',
- 'Apps/Sandcastle/jsHintOptions.js',
- 'Apps/Sandcastle/gallery/gallery-index.js',
- 'Apps/Sandcastle/templates/bucket.css',
- 'Cesium-*.zip',
- 'cesium-*.tgz'];
-
-var filesToConvertES6 = ['Source/**/*.js',
- 'Specs/**/*.js',
- '!Source/ThirdParty/**',
- '!Source/Cesium.js',
- '!Source/copyrightHeader.js',
- '!Source/Shaders/**',
- '!Source/Workers/cesiumWorkerBootstrapper.js',
- '!Source/Workers/transferTypedArrayTest.js',
- '!Specs/karma-main.js',
- '!Specs/karma.conf.js',
- '!Specs/spec-main.js',
- '!Specs/SpecList.js',
- '!Specs/TestWorkers/**'
- ];
+var sourceFiles = [
+ "Source/**/*.js",
+ "!Source/*.js",
+ "!Source/Workers/**",
+ "!Source/WorkersES6/**",
+ "Source/WorkersES6/createTaskProcessorWorker.js",
+ "!Source/ThirdParty/Workers/**",
+ "!Source/ThirdParty/google-earth-dbroot-parser.js",
+ "!Source/ThirdParty/pako_inflate.js",
+ "!Source/ThirdParty/crunch.js",
+];
+
+var watchedFiles = [
+ "Source/**/*.js",
+ "!Source/Cesium.js",
+ "!Source/Build/**",
+ "!Source/Shaders/**/*.js",
+ "Source/Shaders/**/*.glsl",
+ "!Source/ThirdParty/Shaders/*.js",
+ "Source/ThirdParty/Shaders/*.glsl",
+ "!Source/Workers/**",
+ "Source/Workers/cesiumWorkerBootstrapper.js",
+ "Source/Workers/transferTypedArrayTest.js",
+ "!Specs/SpecList.js",
+];
+
+var filesToClean = [
+ "Source/Cesium.js",
+ "Source/Shaders/**/*.js",
+ "Source/Workers/**",
+ "!Source/Workers/cesiumWorkerBootstrapper.js",
+ "!Source/Workers/transferTypedArrayTest.js",
+ "Source/ThirdParty/Shaders/*.js",
+ "Specs/SpecList.js",
+ "Apps/Sandcastle/jsHintOptions.js",
+ "Apps/Sandcastle/gallery/gallery-index.js",
+ "Apps/Sandcastle/templates/bucket.css",
+ "Cesium-*.zip",
+ "cesium-*.tgz",
+];
+
+var filesToConvertES6 = [
+ "Source/**/*.js",
+ "Specs/**/*.js",
+ "!Source/ThirdParty/**",
+ "!Source/Cesium.js",
+ "!Source/copyrightHeader.js",
+ "!Source/Shaders/**",
+ "!Source/Workers/cesiumWorkerBootstrapper.js",
+ "!Source/Workers/transferTypedArrayTest.js",
+ "!Specs/karma-main.js",
+ "!Specs/karma.conf.js",
+ "!Specs/spec-main.js",
+ "!Specs/SpecList.js",
+ "!Specs/TestWorkers/**",
+];
function rollupWarning(message) {
- // Ignore eval warnings in third-party code we don't have control over
- if (message.code === 'EVAL' && /(protobuf-minimal|crunch)\.js$/.test(message.loc.file)) {
- return;
- }
- console.log(message);
+ // Ignore eval warnings in third-party code we don't have control over
+ if (
+ message.code === "EVAL" &&
+ /(protobuf-minimal|crunch)\.js$/.test(message.loc.file)
+ ) {
+ return;
+ }
+ console.log(message);
}
-var copyrightHeader = fs.readFileSync(path.join('Source', 'copyrightHeader.js'), "utf8");
+var copyrightHeader = fs.readFileSync(
+ path.join("Source", "copyrightHeader.js"),
+ "utf8"
+);
function createWorkers() {
- rimraf.sync('Build/createWorkers');
-
- globby.sync([
- 'Source/Workers/**',
- '!Source/Workers/cesiumWorkerBootstrapper.js',
- '!Source/Workers/transferTypedArrayTest.js'
- ]).forEach(function(file) {
- rimraf.sync(file);
+ rimraf.sync("Build/createWorkers");
+
+ globby
+ .sync([
+ "Source/Workers/**",
+ "!Source/Workers/cesiumWorkerBootstrapper.js",
+ "!Source/Workers/transferTypedArrayTest.js",
+ ])
+ .forEach(function (file) {
+ rimraf.sync(file);
});
- var workers = globby.sync([
- 'Source/WorkersES6/**'
- ]);
-
- return rollup.rollup({
- input: workers,
- onwarn: rollupWarning
- }).then(function(bundle) {
- return bundle.write({
- dir: 'Build/createWorkers',
- banner: '/* This file is automatically rebuilt by the Cesium build process. */',
- format: 'amd'
- });
- }).then(function(){
- return streamToPromise(
- gulp.src('Build/createWorkers/**').pipe(gulp.dest('Source/Workers'))
- );
- }).then(function() {
- rimraf.sync('Build/createWorkers');
+ var workers = globby.sync(["Source/WorkersES6/**"]);
+
+ return rollup
+ .rollup({
+ input: workers,
+ onwarn: rollupWarning,
+ })
+ .then(function (bundle) {
+ return bundle.write({
+ dir: "Build/createWorkers",
+ banner:
+ "/* This file is automatically rebuilt by the Cesium build process. */",
+ format: "amd",
+ });
+ })
+ .then(function () {
+ return streamToPromise(
+ gulp.src("Build/createWorkers/**").pipe(gulp.dest("Source/Workers"))
+ );
+ })
+ .then(function () {
+ rimraf.sync("Build/createWorkers");
});
}
-gulp.task('build', function() {
- mkdirp.sync('Build');
- fs.writeFileSync('Build/package.json', JSON.stringify({
- type: 'commonjs'
- }), "utf8");
- glslToJavaScript(minifyShaders, 'Build/minifyShaders.state');
- createCesiumJs();
- createSpecList();
- createJsHintOptions();
- return Promise.join(createWorkers(), createGalleryList());
+gulp.task("build", function () {
+ mkdirp.sync("Build");
+ fs.writeFileSync(
+ "Build/package.json",
+ JSON.stringify({
+ type: "commonjs",
+ }),
+ "utf8"
+ );
+ glslToJavaScript(minifyShaders, "Build/minifyShaders.state");
+ createCesiumJs();
+ createSpecList();
+ createJsHintOptions();
+ return Promise.join(createWorkers(), createGalleryList());
});
-gulp.task('build-watch', function() {
- return gulp.watch(watchedFiles, gulp.series('build'));
+gulp.task("build-watch", function () {
+ return gulp.watch(watchedFiles, gulp.series("build"));
});
-gulp.task('buildApps', function() {
- return Promise.join(
- buildCesiumViewer(),
- buildSandcastle()
- );
+gulp.task("build-ts", function () {
+ createTypeScriptDefinitions();
+ return Promise.resolve();
});
-gulp.task('build-specs', function buildSpecs() {
- var externalCesium = rollupPluginExternalGlobals({
- '../Source/Cesium.js': 'Cesium',
- '../../Source/Cesium.js': 'Cesium',
- '../../../Source/Cesium.js': 'Cesium',
- '../../../../Source/Cesium.js': 'Cesium'
- });
-
- var removePragmas = rollupPluginStripPragma({
- pragmas: ['debug']
- });
+gulp.task("buildApps", function () {
+ return Promise.join(buildCesiumViewer(), buildSandcastle());
+});
- var promise = Promise.join(
- rollup.rollup({
- input: 'Specs/SpecList.js',
- plugins: [externalCesium],
- onwarn: rollupWarning
- }).then(function(bundle) {
+gulp.task("build-specs", function buildSpecs() {
+ var externalCesium = rollupPluginExternalGlobals({
+ "../Source/Cesium.js": "Cesium",
+ "../../Source/Cesium.js": "Cesium",
+ "../../../Source/Cesium.js": "Cesium",
+ "../../../../Source/Cesium.js": "Cesium",
+ });
+
+ var removePragmas = rollupPluginStripPragma({
+ pragmas: ["debug"],
+ });
+
+ var promise = Promise.join(
+ rollup
+ .rollup({
+ input: "Specs/SpecList.js",
+ plugins: [externalCesium],
+ onwarn: rollupWarning,
+ })
+ .then(function (bundle) {
+ return bundle.write({
+ file: "Build/Specs/Specs.js",
+ format: "iife",
+ });
+ })
+ .then(function () {
+ return rollup
+ .rollup({
+ input: "Specs/spec-main.js",
+ plugins: [removePragmas, externalCesium],
+ })
+ .then(function (bundle) {
return bundle.write({
- file: 'Build/Specs/Specs.js',
- format: 'iife'
+ file: "Build/Specs/spec-main.js",
+ format: "iife",
});
- }).then(function(){
- return rollup.rollup({
- input: 'Specs/spec-main.js',
- plugins: [removePragmas, externalCesium]
- }).then(function(bundle) {
- return bundle.write({
- file: 'Build/Specs/spec-main.js',
- format: 'iife'
- });
- });
- }).then(function(){
- return rollup.rollup({
- input: 'Specs/karma-main.js',
- plugins: [removePragmas, externalCesium],
- onwarn: rollupWarning
- }).then(function(bundle) {
- return bundle.write({
- file: 'Build/Specs/karma-main.js',
- name: 'karmaMain',
- format: 'iife'
- });
+ });
+ })
+ .then(function () {
+ return rollup
+ .rollup({
+ input: "Specs/karma-main.js",
+ plugins: [removePragmas, externalCesium],
+ onwarn: rollupWarning,
+ })
+ .then(function (bundle) {
+ return bundle.write({
+ file: "Build/Specs/karma-main.js",
+ name: "karmaMain",
+ format: "iife",
});
- })
- );
+ });
+ })
+ );
- return promise;
+ return promise;
});
-gulp.task('clean', function(done) {
- rimraf.sync('Build');
- globby.sync(filesToClean).forEach(function(file) {
- rimraf.sync(file);
- });
- done();
+gulp.task("clean", function (done) {
+ rimraf.sync("Build");
+ globby.sync(filesToClean).forEach(function (file) {
+ rimraf.sync(file);
+ });
+ done();
});
function cloc() {
- var cmdLine;
- var clocPath = path.join('node_modules', 'cloc', 'lib', 'cloc');
-
- //Run cloc on primary Source files only
- var source = new Promise(function(resolve, reject) {
- cmdLine = 'perl ' + clocPath + ' --quiet --progress-rate=0' +
- ' Source/ --exclude-dir=Assets,ThirdParty,Workers --not-match-f=copyrightHeader.js';
-
- child_process.exec(cmdLine, function(error, stdout, stderr) {
- if (error) {
- console.log(stderr);
- return reject(error);
- }
- console.log('Source:');
- console.log(stdout);
- resolve();
- });
+ var cmdLine;
+
+ //Run cloc on primary Source files only
+ var source = new Promise(function (resolve, reject) {
+ cmdLine =
+ "npx cloc" +
+ " --quiet --progress-rate=0" +
+ " Source/ --exclude-dir=Assets,ThirdParty,Workers --not-match-f=copyrightHeader.js";
+
+ child_process.exec(cmdLine, function (error, stdout, stderr) {
+ if (error) {
+ console.log(stderr);
+ return reject(error);
+ }
+ console.log("Source:");
+ console.log(stdout);
+ resolve();
});
-
- //If running cloc on source succeeded, also run it on the tests.
- return source.then(function() {
- return new Promise(function(resolve, reject) {
- cmdLine = 'perl ' + clocPath + ' --quiet --progress-rate=0' +
- ' Specs/ --exclude-dir=Data';
- child_process.exec(cmdLine, function(error, stdout, stderr) {
- if (error) {
- console.log(stderr);
- return reject(error);
- }
- console.log('Specs:');
- console.log(stdout);
- resolve();
- });
- });
+ });
+
+ //If running cloc on source succeeded, also run it on the tests.
+ return source.then(function () {
+ return new Promise(function (resolve, reject) {
+ cmdLine =
+ "npx cloc" +
+ " --quiet --progress-rate=0" +
+ " Specs/ --exclude-dir=Data";
+ child_process.exec(cmdLine, function (error, stdout, stderr) {
+ if (error) {
+ console.log(stderr);
+ return reject(error);
+ }
+ console.log("Specs:");
+ console.log(stdout);
+ resolve();
+ });
});
+ });
}
-gulp.task('cloc', gulp.series('clean', cloc));
+gulp.task("cloc", gulp.series("clean", cloc));
function combine() {
- var outputDirectory = path.join('Build', 'CesiumUnminified');
- return combineJavaScript({
- removePragmas: false,
- optimizer: 'none',
- outputDirectory: outputDirectory
- });
+ var outputDirectory = path.join("Build", "CesiumUnminified");
+ return combineJavaScript({
+ removePragmas: false,
+ optimizer: "none",
+ outputDirectory: outputDirectory,
+ });
}
-gulp.task('combine', gulp.series('build', combine));
-gulp.task('default', gulp.series('combine'));
+gulp.task("combine", gulp.series("build", combine));
+gulp.task("default", gulp.series("combine"));
function combineRelease() {
- var outputDirectory = path.join('Build', 'CesiumUnminified');
- return combineJavaScript({
- removePragmas: true,
- optimizer: 'none',
- outputDirectory: outputDirectory
- });
+ var outputDirectory = path.join("Build", "CesiumUnminified");
+ return combineJavaScript({
+ removePragmas: true,
+ optimizer: "none",
+ outputDirectory: outputDirectory,
+ });
}
-gulp.task('combineRelease', gulp.series('build', combineRelease));
+gulp.task("combineRelease", gulp.series("build", combineRelease));
//Builds the documentation
function generateDocumentation() {
- var envPathSeperator = os.platform() === 'win32' ? ';' : ':';
+ child_process.execSync("npx jsdoc --configure Tools/jsdoc/conf.json", {
+ stdio: "inherit",
+ env: Object.assign({}, process.env, { CESIUM_VERSION: version }),
+ });
- return new Promise(function(resolve, reject) {
- child_process.exec('jsdoc --configure Tools/jsdoc/conf.json', {
- env : {
- PATH : process.env.PATH + envPathSeperator + 'node_modules/.bin',
- CESIUM_VERSION : version
- }
- }, function(error, stdout, stderr) {
- if (error) {
- console.log(stderr);
- return reject(error);
- }
- console.log(stdout);
- var stream = gulp.src('Documentation/Images/**').pipe(gulp.dest('Build/Documentation/Images'));
- return streamToPromise(stream).then(resolve);
- });
- });
+ var stream = gulp
+ .src("Documentation/Images/**")
+ .pipe(gulp.dest("Build/Documentation/Images"));
+
+ return streamToPromise(stream);
}
-gulp.task('generateDocumentation', generateDocumentation);
+gulp.task("generateDocumentation", generateDocumentation);
-gulp.task('generateDocumentation-watch', function() {
- return generateDocumentation().done(function() {
- console.log('Listening for changes in documentation...');
- return gulp.watch(sourceFiles, gulp.series('generateDocumentation'));
- });
+gulp.task("generateDocumentation-watch", function () {
+ return generateDocumentation().done(function () {
+ console.log("Listening for changes in documentation...");
+ return gulp.watch(sourceFiles, gulp.series("generateDocumentation"));
+ });
});
-gulp.task('release', gulp.series('build', combine, minifyRelease, generateDocumentation));
-
-gulp.task('makeZipFile', gulp.series('release', function() {
+gulp.task(
+ "release",
+ gulp.series(
+ "build",
+ "build-ts",
+ combine,
+ minifyRelease,
+ generateDocumentation
+ )
+);
+
+gulp.task(
+ "makeZipFile",
+ gulp.series("release", function () {
//For now we regenerate the JS glsl to force it to be unminified in the release zip
//See https://github.com/CesiumGS/cesium/pull/3106#discussion_r42793558 for discussion.
- glslToJavaScript(false, 'Build/minifyShaders.state');
-
- var builtSrc = gulp.src([
- 'Build/Cesium/**',
- 'Build/CesiumUnminified/**',
- 'Build/Documentation/**'
- ], {
- base : '.'
- });
+ glslToJavaScript(false, "Build/minifyShaders.state");
+
+ var builtSrc = gulp.src(
+ [
+ "Build/Cesium/**",
+ "Build/CesiumUnminified/**",
+ "Build/Documentation/**",
+ ],
+ {
+ base: ".",
+ }
+ );
- var staticSrc = gulp.src([
- 'Apps/**',
- '!Apps/Sandcastle/gallery/development/**',
- 'Source/**',
- 'Specs/**',
- 'ThirdParty/**',
- 'favicon.ico',
- 'gulpfile.cjs',
- 'server.cjs',
- 'package.json',
- 'LICENSE.md',
- 'CHANGES.md',
- 'README.md',
- 'web.config'
- ], {
- base : '.'
- });
+ var staticSrc = gulp.src(
+ [
+ "Apps/**",
+ "!Apps/Sandcastle/gallery/development/**",
+ "Source/**",
+ "Specs/**",
+ "ThirdParty/**",
+ "favicon.ico",
+ "gulpfile.cjs",
+ "server.cjs",
+ "package.json",
+ "LICENSE.md",
+ "CHANGES.md",
+ "README.md",
+ "web.config",
+ ],
+ {
+ base: ".",
+ }
+ );
- var indexSrc = gulp.src('index.release.html').pipe(gulpRename('index.html'));
+ var indexSrc = gulp
+ .src("index.release.html")
+ .pipe(gulpRename("index.html"));
return mergeStream(builtSrc, staticSrc, indexSrc)
- .pipe(gulpTap(function(file) {
- // Work around an issue with gulp-zip where archives generated on Windows do
- // not properly have their directory executable mode set.
- // see https://github.com/sindresorhus/gulp-zip/issues/64#issuecomment-205324031
- if (file.isDirectory()) {
- file.stat.mode = parseInt('40777', 8);
- }
- }))
- .pipe(gulpZip('Cesium-' + version + '.zip'))
- .pipe(gulp.dest('.'));
-}));
-
-gulp.task('minify', gulp.series('build', function() {
+ .pipe(
+ gulpTap(function (file) {
+ // Work around an issue with gulp-zip where archives generated on Windows do
+ // not properly have their directory executable mode set.
+ // see https://github.com/sindresorhus/gulp-zip/issues/64#issuecomment-205324031
+ if (file.isDirectory()) {
+ file.stat.mode = parseInt("40777", 8);
+ }
+ })
+ )
+ .pipe(gulpZip("Cesium-" + version + ".zip"))
+ .pipe(gulp.dest("."));
+ })
+);
+
+gulp.task(
+ "minify",
+ gulp.series("build", function () {
return combineJavaScript({
- removePragmas : false,
- optimizer : 'uglify2',
- outputDirectory : path.join('Build', 'Cesium')
+ removePragmas: false,
+ optimizer: "uglify2",
+ outputDirectory: path.join("Build", "Cesium"),
});
-}));
+ })
+);
function minifyRelease() {
- return combineJavaScript({
- removePragmas: true,
- optimizer: 'uglify2',
- outputDirectory: path.join('Build', 'Cesium')
- });
+ return combineJavaScript({
+ removePragmas: true,
+ optimizer: "uglify2",
+ outputDirectory: path.join("Build", "Cesium"),
+ });
}
-gulp.task('minifyRelease', gulp.series('build', minifyRelease));
+gulp.task("minifyRelease", gulp.series("build", minifyRelease));
function isTravisPullRequest() {
- return process.env.TRAVIS_PULL_REQUEST !== undefined && process.env.TRAVIS_PULL_REQUEST !== 'false';
+ return (
+ process.env.TRAVIS_PULL_REQUEST !== undefined &&
+ process.env.TRAVIS_PULL_REQUEST !== "false"
+ );
}
-gulp.task('deploy-s3', function(done) {
- if (isTravisPullRequest()) {
- console.log('Skipping deployment for non-pull request.');
- done();
- return;
- }
-
- var argv = yargs.usage('Usage: deploy-s3 -b [Bucket Name] -d [Upload Directory]')
- .demand(['b', 'd']).argv;
-
- var uploadDirectory = argv.d;
- var bucketName = argv.b;
- var cacheControl = argv.c ? argv.c : 'max-age=3600';
-
- if (argv.confirm) {
- // skip prompt for travis
+gulp.task("deploy-s3", function (done) {
+ if (isTravisPullRequest()) {
+ console.log("Skipping deployment for non-pull request.");
+ done();
+ return;
+ }
+
+ var argv = yargs
+ .usage("Usage: deploy-s3 -b [Bucket Name] -d [Upload Directory]")
+ .demand(["b", "d"]).argv;
+
+ var uploadDirectory = argv.d;
+ var bucketName = argv.b;
+ var cacheControl = argv.c ? argv.c : "max-age=3600";
+
+ if (argv.confirm) {
+ // skip prompt for travis
+ deployCesium(bucketName, uploadDirectory, cacheControl, done);
+ return;
+ }
+
+ var iface = readline.createInterface({
+ input: process.stdin,
+ output: process.stdout,
+ });
+
+ // prompt for confirmation
+ iface.question(
+ "Files from your computer will be published to the " +
+ bucketName +
+ " bucket. Continue? [y/n] ",
+ function (answer) {
+ iface.close();
+ if (answer === "y") {
deployCesium(bucketName, uploadDirectory, cacheControl, done);
- return;
+ } else {
+ console.log("Deploy aborted by user.");
+ done();
+ }
}
-
- var iface = readline.createInterface({
- input: process.stdin,
- output: process.stdout
- });
-
- // prompt for confirmation
- iface.question('Files from your computer will be published to the ' + bucketName + ' bucket. Continue? [y/n] ', function(answer) {
- iface.close();
- if (answer === 'y') {
- deployCesium(bucketName, uploadDirectory, cacheControl, done);
- } else {
- console.log('Deploy aborted by user.');
- done();
- }
- });
-
+ );
});
// Deploy cesium to s3
function deployCesium(bucketName, uploadDirectory, cacheControl, done) {
- var readFile = Promise.promisify(fs.readFile);
- var gzip = Promise.promisify(zlib.gzip);
- var concurrencyLimit = 2000;
-
- var s3 = new AWS.S3({
- maxRetries : 10,
- retryDelayOptions : {
- base : 500
+ var readFile = Promise.promisify(fs.readFile);
+ var gzip = Promise.promisify(zlib.gzip);
+ var concurrencyLimit = 2000;
+
+ var s3 = new AWS.S3({
+ maxRetries: 10,
+ retryDelayOptions: {
+ base: 500,
+ },
+ });
+
+ var existingBlobs = [];
+ var totalFiles = 0;
+ var uploaded = 0;
+ var skipped = 0;
+ var errors = [];
+
+ var prefix = uploadDirectory + "/";
+ return listAll(s3, bucketName, prefix, existingBlobs)
+ .then(function () {
+ return globby(
+ [
+ "Apps/**",
+ "Build/**",
+ "Source/**",
+ "Specs/**",
+ "ThirdParty/**",
+ "*.md",
+ "favicon.ico",
+ "gulpfile.cjs",
+ "index.html",
+ "package.json",
+ "server.cjs",
+ "web.config",
+ "*.zip",
+ "*.tgz",
+ ],
+ {
+ dot: true, // include hidden files
}
- });
-
- var existingBlobs = [];
- var totalFiles = 0;
- var uploaded = 0;
- var skipped = 0;
- var errors = [];
-
- var prefix = uploadDirectory + '/';
- return listAll(s3, bucketName, prefix, existingBlobs)
- .then(function() {
- return globby([
- 'Apps/**',
- 'Build/**',
- 'Source/**',
- 'Specs/**',
- 'ThirdParty/**',
- '*.md',
- 'favicon.ico',
- 'gulpfile.cjs',
- 'index.html',
- 'package.json',
- 'server.cjs',
- 'web.config',
- '*.zip',
- '*.tgz'
- ], {
- dot : true // include hidden files
- });
- }).then(function(files) {
- return Promise.map(files, function(file) {
- var blobName = uploadDirectory + '/' + file;
- var mimeLookup = getMimeType(blobName);
- var contentType = mimeLookup.type;
- var compress = mimeLookup.compress;
- var contentEncoding = compress ? 'gzip' : undefined;
- var etag;
-
- totalFiles++;
-
- return readFile(file)
- .then(function(content) {
- if (!compress) {
- return content;
- }
-
- var alreadyCompressed = (content[0] === 0x1f) && (content[1] === 0x8b);
- if (alreadyCompressed) {
- console.log('Skipping compressing already compressed file: ' + file);
- return content;
- }
-
- return gzip(content);
+ );
+ })
+ .then(function (files) {
+ return Promise.map(
+ files,
+ function (file) {
+ var blobName = uploadDirectory + "/" + file;
+ var mimeLookup = getMimeType(blobName);
+ var contentType = mimeLookup.type;
+ var compress = mimeLookup.compress;
+ var contentEncoding = compress ? "gzip" : undefined;
+ var etag;
+
+ totalFiles++;
+
+ return readFile(file)
+ .then(function (content) {
+ if (!compress) {
+ return content;
+ }
+
+ var alreadyCompressed =
+ content[0] === 0x1f && content[1] === 0x8b;
+ if (alreadyCompressed) {
+ console.log(
+ "Skipping compressing already compressed file: " + file
+ );
+ return content;
+ }
+
+ return gzip(content);
+ })
+ .then(function (content) {
+ // compute hash and etag
+ var hash = crypto.createHash("md5").update(content).digest("hex");
+ etag = crypto.createHash("md5").update(content).digest("base64");
+
+ var index = existingBlobs.indexOf(blobName);
+ if (index <= -1) {
+ return content;
+ }
+
+ // remove files as we find them on disk
+ existingBlobs.splice(index, 1);
+
+ // get file info
+ return s3
+ .headObject({
+ Bucket: bucketName,
+ Key: blobName,
})
- .then(function(content) {
- // compute hash and etag
- var hash = crypto.createHash('md5').update(content).digest('hex');
- etag = crypto.createHash('md5').update(content).digest('base64');
-
- var index = existingBlobs.indexOf(blobName);
- if (index <= -1) {
- return content;
- }
-
- // remove files as we find them on disk
- existingBlobs.splice(index, 1);
-
- // get file info
- return s3.headObject({
- Bucket: bucketName,
- Key: blobName
- }).promise().then(function(data) {
- if (data.ETag !== ('"' + hash + '"') ||
- data.CacheControl !== cacheControl ||
- data.ContentType !== contentType ||
- data.ContentEncoding !== contentEncoding) {
- return content;
- }
-
- // We don't need to upload this file again
- skipped++;
- return undefined;
- })
- .catch(function(error) {
- errors.push(error);
- });
+ .promise()
+ .then(function (data) {
+ if (
+ data.ETag !== '"' + hash + '"' ||
+ data.CacheControl !== cacheControl ||
+ data.ContentType !== contentType ||
+ data.ContentEncoding !== contentEncoding
+ ) {
+ return content;
+ }
+
+ // We don't need to upload this file again
+ skipped++;
+ return undefined;
})
- .then(function(content) {
- if (!content) {
- return;
- }
-
- if (verbose) {
- console.log('Uploading ' + blobName + '...');
- }
- var params = {
- Bucket : bucketName,
- Key : blobName,
- Body : content,
- ContentMD5 : etag,
- ContentType : contentType,
- ContentEncoding : contentEncoding,
- CacheControl : cacheControl
- };
-
- return s3.putObject(params).promise()
- .then(function() {
- uploaded++;
- })
- .catch(function(error) {
- errors.push(error);
- });
+ .catch(function (error) {
+ errors.push(error);
});
- }, {concurrency : concurrencyLimit});
- }).then(function() {
- console.log('Skipped ' + skipped + ' files and successfully uploaded ' + uploaded + ' files of ' + (totalFiles - skipped) + ' files.');
- if (existingBlobs.length === 0) {
+ })
+ .then(function (content) {
+ if (!content) {
return;
- }
-
- var objectsToDelete = [];
- existingBlobs.forEach(function(file) {
- //Don't delete generate zip files.
- if (!/\.(zip|tgz)$/.test(file)) {
- objectsToDelete.push({Key : file});
- }
+ }
+
+ if (verbose) {
+ console.log("Uploading " + blobName + "...");
+ }
+ var params = {
+ Bucket: bucketName,
+ Key: blobName,
+ Body: content,
+ ContentMD5: etag,
+ ContentType: contentType,
+ ContentEncoding: contentEncoding,
+ CacheControl: cacheControl,
+ };
+
+ return s3
+ .putObject(params)
+ .promise()
+ .then(function () {
+ uploaded++;
+ })
+ .catch(function (error) {
+ errors.push(error);
+ });
});
+ },
+ { concurrency: concurrencyLimit }
+ );
+ })
+ .then(function () {
+ console.log(
+ "Skipped " +
+ skipped +
+ " files and successfully uploaded " +
+ uploaded +
+ " files of " +
+ (totalFiles - skipped) +
+ " files."
+ );
+ if (existingBlobs.length === 0) {
+ return;
+ }
+
+ var objectsToDelete = [];
+ existingBlobs.forEach(function (file) {
+ //Don't delete generate zip files.
+ if (!/\.(zip|tgz)$/.test(file)) {
+ objectsToDelete.push({ Key: file });
+ }
+ });
- if (objectsToDelete.length > 0) {
- console.log('Cleaning ' + objectsToDelete.length + ' files...');
+ if (objectsToDelete.length > 0) {
+ console.log("Cleaning " + objectsToDelete.length + " files...");
- // If more than 1000 files, we must issue multiple requests
- var batches = [];
- while (objectsToDelete.length > 1000) {
- batches.push(objectsToDelete.splice(0, 1000));
+ // If more than 1000 files, we must issue multiple requests
+ var batches = [];
+ while (objectsToDelete.length > 1000) {
+ batches.push(objectsToDelete.splice(0, 1000));
+ }
+ batches.push(objectsToDelete);
+
+ return Promise.map(
+ batches,
+ function (objects) {
+ return s3
+ .deleteObjects({
+ Bucket: bucketName,
+ Delete: {
+ Objects: objects,
+ },
+ })
+ .promise()
+ .then(function () {
+ if (verbose) {
+ console.log("Cleaned " + objects.length + " files.");
}
- batches.push(objectsToDelete);
-
- return Promise.map(batches, function(objects) {
- return s3.deleteObjects({
- Bucket: bucketName,
- Delete: {
- Objects: objects
- }
- }).promise().then(function() {
- if (verbose) {
- console.log('Cleaned ' + objects.length + ' files.');
- }
- });
- }, {concurrency : concurrency});
- }
- }).catch(function(error) {
- errors.push(error);
- }).then(function() {
- if (errors.length === 0) {
- done();
- return;
- }
+ });
+ },
+ { concurrency: concurrency }
+ );
+ }
+ })
+ .catch(function (error) {
+ errors.push(error);
+ })
+ .then(function () {
+ if (errors.length === 0) {
+ done();
+ return;
+ }
- console.log('Errors: ');
- errors.map(function(e) {
- console.log(e);
- });
- done(1);
- });
+ console.log("Errors: ");
+ errors.map(function (e) {
+ console.log(e);
+ });
+ done(1);
+ });
}
function getMimeType(filename) {
- var mimeType = mime.getType(filename);
- if (mimeType) {
- //Compress everything except zipfiles, binary images, and video
- var compress = !/^(image\/|video\/|application\/zip|application\/gzip)/i.test(mimeType);
- if (mimeType === 'image/svg+xml') {
- compress = true;
- }
- return { type: mimeType, compress: compress };
- }
-
- //Non-standard mime types not handled by mime
- if (/\.(glsl|LICENSE|config|state)$/i.test(filename)) {
- return { type: 'text/plain', compress: true };
- } else if (/\.(czml|topojson)$/i.test(filename)) {
- return { type: 'application/json', compress: true };
- } else if (/\.(crn|tgz)$/i.test(filename)) {
- return { type: 'application/octet-stream', compress: false };
- }
-
- // Handle dotfiles, such as .jshintrc
- var baseName = path.basename(filename);
- if (baseName[0] === '.' || baseName.indexOf('.') === -1) {
- return { type: 'text/plain', compress: true };
- }
-
- // Everything else can be octet-stream compressed but print a warning
- // if we introduce a type we aren't specifically handling.
- if (!/\.(terrain|b3dm|geom|pnts|vctr|cmpt|i3dm|metadata)$/i.test(filename)) {
- console.log('Unknown mime type for ' + filename);
+ var mimeType = mime.getType(filename);
+ if (mimeType) {
+ //Compress everything except zipfiles, binary images, and video
+ var compress = !/^(image\/|video\/|application\/zip|application\/gzip)/i.test(
+ mimeType
+ );
+ if (mimeType === "image/svg+xml") {
+ compress = true;
}
-
- return { type: 'application/octet-stream', compress: true };
+ return { type: mimeType, compress: compress };
+ }
+
+ //Non-standard mime types not handled by mime
+ if (/\.(glsl|LICENSE|config|state)$/i.test(filename)) {
+ return { type: "text/plain", compress: true };
+ } else if (/\.(czml|topojson)$/i.test(filename)) {
+ return { type: "application/json", compress: true };
+ } else if (/\.(crn|tgz)$/i.test(filename)) {
+ return { type: "application/octet-stream", compress: false };
+ }
+
+ // Handle dotfiles, such as .jshintrc
+ var baseName = path.basename(filename);
+ if (baseName[0] === "." || baseName.indexOf(".") === -1) {
+ return { type: "text/plain", compress: true };
+ }
+
+ // Everything else can be octet-stream compressed but print a warning
+ // if we introduce a type we aren't specifically handling.
+ if (!/\.(terrain|b3dm|geom|pnts|vctr|cmpt|i3dm|metadata)$/i.test(filename)) {
+ console.log("Unknown mime type for " + filename);
+ }
+
+ return { type: "application/octet-stream", compress: true };
}
// get all files currently in bucket asynchronously
function listAll(s3, bucketName, prefix, files, marker) {
- return s3.listObjects({
- Bucket: bucketName,
- MaxKeys: 1000,
- Prefix: prefix,
- Marker: marker
- }).promise().then(function(data) {
- var items = data.Contents;
- for (var i = 0; i < items.length; i++) {
- files.push(items[i].Key);
- }
+ return s3
+ .listObjects({
+ Bucket: bucketName,
+ MaxKeys: 1000,
+ Prefix: prefix,
+ Marker: marker,
+ })
+ .promise()
+ .then(function (data) {
+ var items = data.Contents;
+ for (var i = 0; i < items.length; i++) {
+ files.push(items[i].Key);
+ }
- if (data.IsTruncated) {
- // get next page of results
- return listAll(s3, bucketName, prefix, files, files[files.length - 1]);
- }
+ if (data.IsTruncated) {
+ // get next page of results
+ return listAll(s3, bucketName, prefix, files, files[files.length - 1]);
+ }
});
}
-gulp.task('deploy-set-version', function(done) {
- var buildVersion = yargs.argv.buildVersion;
- if (buildVersion) {
- // NPM versions can only contain alphanumeric and hyphen characters
- packageJson.version += '-' + buildVersion.replace(/[^[0-9A-Za-z-]/g, '');
- fs.writeFileSync('package.json', JSON.stringify(packageJson, undefined, 2));
- }
- done();
+gulp.task("deploy-set-version", function (done) {
+ var buildVersion = yargs.argv.buildVersion;
+ if (buildVersion) {
+ // NPM versions can only contain alphanumeric and hyphen characters
+ packageJson.version += "-" + buildVersion.replace(/[^[0-9A-Za-z-]/g, "");
+ fs.writeFileSync("package.json", JSON.stringify(packageJson, undefined, 2));
+ }
+ done();
});
-gulp.task('deploy-status', function() {
- if (isTravisPullRequest()) {
- console.log('Skipping deployment status for non-pull request.');
- return Promise.resolve();
- }
-
- var status = yargs.argv.status;
- var message = yargs.argv.message;
-
- var deployUrl = travisDeployUrl + process.env.TRAVIS_BRANCH + '/';
- var zipUrl = deployUrl + 'Cesium-' + packageJson.version + '.zip';
- var npmUrl = deployUrl + 'cesium-' + packageJson.version + '.tgz';
- var coverageUrl = travisDeployUrl + process.env.TRAVIS_BRANCH + '/Build/Coverage/index.html';
-
- return Promise.join(
- setStatus(status, deployUrl, message, 'deployment'),
- setStatus(status, zipUrl, message, 'zip file'),
- setStatus(status, npmUrl, message, 'npm package'),
- setStatus(status, coverageUrl, message, 'coverage results')
- );
+gulp.task("deploy-status", function () {
+ if (isTravisPullRequest()) {
+ console.log("Skipping deployment status for non-pull request.");
+ return Promise.resolve();
+ }
+
+ var status = yargs.argv.status;
+ var message = yargs.argv.message;
+
+ var deployUrl = travisDeployUrl + process.env.TRAVIS_BRANCH + "/";
+ var zipUrl = deployUrl + "Cesium-" + packageJson.version + ".zip";
+ var npmUrl = deployUrl + "cesium-" + packageJson.version + ".tgz";
+ var coverageUrl =
+ travisDeployUrl + process.env.TRAVIS_BRANCH + "/Build/Coverage/index.html";
+
+ return Promise.join(
+ setStatus(status, deployUrl, message, "deployment"),
+ setStatus(status, zipUrl, message, "zip file"),
+ setStatus(status, npmUrl, message, "npm package"),
+ setStatus(status, coverageUrl, message, "coverage results")
+ );
});
function setStatus(state, targetUrl, description, context) {
- // skip if the environment does not have the token
- if (!process.env.TOKEN) {
- return;
- }
-
- var requestPost = Promise.promisify(request.post);
- return requestPost({
- url: 'https://api.github.com/repos/' + process.env.TRAVIS_REPO_SLUG + '/statuses/' + process.env.TRAVIS_COMMIT,
- json: true,
- headers: {
- 'Authorization': 'token ' + process.env.TOKEN,
- 'User-Agent': 'Cesium'
- },
- body: {
- state: state,
- target_url: targetUrl,
- description: description,
- context: context
- }
- });
+ // skip if the environment does not have the token
+ if (!process.env.TOKEN) {
+ return;
+ }
+
+ var requestPost = Promise.promisify(request.post);
+ return requestPost({
+ url:
+ "https://api.github.com/repos/" +
+ process.env.TRAVIS_REPO_SLUG +
+ "/statuses/" +
+ process.env.TRAVIS_COMMIT,
+ json: true,
+ headers: {
+ Authorization: "token " + process.env.TOKEN,
+ "User-Agent": "Cesium",
+ },
+ body: {
+ state: state,
+ target_url: targetUrl,
+ description: description,
+ context: context,
+ },
+ });
}
-gulp.task('coverage', function(done) {
- var argv = yargs.argv;
- var webglStub = argv.webglStub ? argv.webglStub : false;
- var suppressPassed = argv.suppressPassed ? argv.suppressPassed : false;
- var failTaskOnError = argv.failTaskOnError ? argv.failTaskOnError : false;
-
- var folders = [];
- var browsers = ['Chrome'];
- if (argv.browsers) {
- browsers = argv.browsers.split(',');
- }
-
- var karma = new Karma.Server({
- configFile: karmaConfigFile,
- browsers: browsers,
- specReporter: {
- suppressErrorSummary: false,
- suppressFailed: false,
- suppressPassed: suppressPassed,
- suppressSkipped: true
- },
- preprocessors: {
- 'Source/Core/**/*.js': ['karma-coverage-istanbul-instrumenter'],
- 'Source/DataSources/**/*.js': ['karma-coverage-istanbul-instrumenter'],
- 'Source/Renderer/**/*.js': ['karma-coverage-istanbul-instrumenter'],
- 'Source/Scene/**/*.js': ['karma-coverage-istanbul-instrumenter'],
- 'Source/Shaders/**/*.js': ['karma-coverage-istanbul-instrumenter'],
- 'Source/Widgets/**/*.js': ['karma-coverage-istanbul-instrumenter'],
- 'Source/Workers/**/*.js': ['karma-coverage-istanbul-instrumenter']
+gulp.task("coverage", function (done) {
+ var argv = yargs.argv;
+ var webglStub = argv.webglStub ? argv.webglStub : false;
+ var suppressPassed = argv.suppressPassed ? argv.suppressPassed : false;
+ var failTaskOnError = argv.failTaskOnError ? argv.failTaskOnError : false;
+
+ var folders = [];
+ var browsers = ["Chrome"];
+ if (argv.browsers) {
+ browsers = argv.browsers.split(",");
+ }
+
+ var karma = new Karma.Server(
+ {
+ configFile: karmaConfigFile,
+ browsers: browsers,
+ specReporter: {
+ suppressErrorSummary: false,
+ suppressFailed: false,
+ suppressPassed: suppressPassed,
+ suppressSkipped: true,
+ },
+ preprocessors: {
+ "Source/Core/**/*.js": ["karma-coverage-istanbul-instrumenter"],
+ "Source/DataSources/**/*.js": ["karma-coverage-istanbul-instrumenter"],
+ "Source/Renderer/**/*.js": ["karma-coverage-istanbul-instrumenter"],
+ "Source/Scene/**/*.js": ["karma-coverage-istanbul-instrumenter"],
+ "Source/Shaders/**/*.js": ["karma-coverage-istanbul-instrumenter"],
+ "Source/Widgets/**/*.js": ["karma-coverage-istanbul-instrumenter"],
+ "Source/Workers/**/*.js": ["karma-coverage-istanbul-instrumenter"],
+ },
+ coverageIstanbulInstrumenter: {
+ esModules: true,
+ },
+ reporters: ["spec", "coverage"],
+ coverageReporter: {
+ dir: "Build/Coverage",
+ subdir: function (browserName) {
+ folders.push(browserName);
+ return browserName;
},
- coverageIstanbulInstrumenter: {
- esModules: true
- },
- reporters: ['spec', 'coverage'],
- coverageReporter: {
- dir: 'Build/Coverage',
- subdir: function(browserName) {
- folders.push(browserName);
- return browserName;
- },
- includeAllSources: true
- },
- client: {
- captureConsole: verbose,
- args: [undefined, undefined, undefined, webglStub, undefined]
- }
- }, function(e) {
- var html = '';
- folders.forEach(function(folder) {
- html += '' + folder + ' ';
+ includeAllSources: true,
+ },
+ client: {
+ captureConsole: verbose,
+ args: [undefined, undefined, undefined, webglStub, undefined],
+ },
+ },
+ function (e) {
+ var html = "";
+ folders.forEach(function (folder) {
+ html +=
+ '' +
+ folder +
+ " ";
+ });
+ html += " ";
+ fs.writeFileSync("Build/Coverage/index.html", html);
+
+ if (!process.env.TRAVIS) {
+ folders.forEach(function (dir) {
+ open("Build/Coverage/" + dir + "/index.html");
});
- html += ' ';
- fs.writeFileSync('Build/Coverage/index.html', html);
-
- if (!process.env.TRAVIS) {
- folders.forEach(function(dir) {
- open('Build/Coverage/' + dir + '/index.html');
- });
- }
- return done(failTaskOnError ? e : undefined);
- });
- karma.start();
-});
-
-gulp.task('test', function(done) {
- var argv = yargs.argv;
-
- var enableAllBrowsers = argv.all ? true : false;
- var includeCategory = argv.include ? argv.include : '';
- var excludeCategory = argv.exclude ? argv.exclude : '';
- var webglValidation = argv.webglValidation ? argv.webglValidation : false;
- var webglStub = argv.webglStub ? argv.webglStub : false;
- var release = argv.release ? argv.release : false;
- var failTaskOnError = argv.failTaskOnError ? argv.failTaskOnError : false;
- var suppressPassed = argv.suppressPassed ? argv.suppressPassed : false;
-
- var browsers = ['Chrome'];
- if (argv.browsers) {
- browsers = argv.browsers.split(',');
+ }
+ return done(failTaskOnError ? e : undefined);
}
+ );
+ karma.start();
+});
- var files = [
- { pattern: 'Specs/karma-main.js', included: true, type: 'module' },
- { pattern: 'Source/**', included: false, type: 'module' },
- { pattern: 'Specs/*.js', included: true, type: 'module' },
- { pattern: 'Specs/Core/**', included: true, type: 'module' },
- { pattern: 'Specs/Data/**', included: false },
- { pattern: 'Specs/DataSources/**', included: true, type: 'module' },
- { pattern: 'Specs/Renderer/**', included: true, type: 'module' },
- { pattern: 'Specs/Scene/**', included: true, type: 'module' },
- { pattern: 'Specs/ThirdParty/**', included: true, type: 'module' },
- { pattern: 'Specs/Widgets/**', included: true, type: 'module' },
- { pattern: 'Specs/TestWorkers/**', included: false }
+gulp.task("test", function (done) {
+ var argv = yargs.argv;
+
+ var enableAllBrowsers = argv.all ? true : false;
+ var includeCategory = argv.include ? argv.include : "";
+ var excludeCategory = argv.exclude ? argv.exclude : "";
+ var webglValidation = argv.webglValidation ? argv.webglValidation : false;
+ var webglStub = argv.webglStub ? argv.webglStub : false;
+ var release = argv.release ? argv.release : false;
+ var failTaskOnError = argv.failTaskOnError ? argv.failTaskOnError : false;
+ var suppressPassed = argv.suppressPassed ? argv.suppressPassed : false;
+
+ var browsers = ["Chrome"];
+ if (argv.browsers) {
+ browsers = argv.browsers.split(",");
+ }
+
+ var files = [
+ { pattern: "Specs/karma-main.js", included: true, type: "module" },
+ { pattern: "Source/**", included: false, type: "module" },
+ { pattern: "Specs/*.js", included: true, type: "module" },
+ { pattern: "Specs/Core/**", included: true, type: "module" },
+ { pattern: "Specs/Data/**", included: false },
+ { pattern: "Specs/DataSources/**", included: true, type: "module" },
+ { pattern: "Specs/Renderer/**", included: true, type: "module" },
+ { pattern: "Specs/Scene/**", included: true, type: "module" },
+ { pattern: "Specs/ThirdParty/**", included: true, type: "module" },
+ { pattern: "Specs/Widgets/**", included: true, type: "module" },
+ { pattern: "Specs/TestWorkers/**", included: false },
+ ];
+
+ if (release) {
+ files = [
+ { pattern: "Specs/Data/**", included: false },
+ { pattern: "Specs/ThirdParty/**", included: true, type: "module" },
+ { pattern: "Specs/TestWorkers/**", included: false },
+ { pattern: "Build/Cesium/Cesium.js", included: true },
+ { pattern: "Build/Cesium/**", included: false },
+ { pattern: "Build/Specs/karma-main.js", included: true },
+ { pattern: "Build/Specs/Specs.js", included: true },
];
-
- if (release) {
- files = [
- { pattern: 'Specs/Data/**', included: false },
- { pattern: 'Specs/ThirdParty/**', included: true, type: 'module' },
- { pattern: 'Specs/TestWorkers/**', included: false },
- { pattern: 'Build/Cesium/Cesium.js', included: true },
- { pattern: 'Build/Cesium/**', included: false },
- { pattern: 'Build/Specs/karma-main.js', included: true },
- { pattern: 'Build/Specs/Specs.js', included: true }
- ];
+ }
+
+ var karma = new Karma.Server(
+ {
+ configFile: karmaConfigFile,
+ browsers: browsers,
+ specReporter: {
+ suppressErrorSummary: false,
+ suppressFailed: false,
+ suppressPassed: suppressPassed,
+ suppressSkipped: true,
+ },
+ detectBrowsers: {
+ enabled: enableAllBrowsers,
+ },
+ logLevel: verbose ? Karma.constants.LOG_INFO : Karma.constants.LOG_ERROR,
+ files: files,
+ client: {
+ captureConsole: verbose,
+ args: [
+ includeCategory,
+ excludeCategory,
+ webglValidation,
+ webglStub,
+ release,
+ ],
+ },
+ },
+ function (e) {
+ return done(failTaskOnError ? e : undefined);
}
-
- var karma = new Karma.Server({
- configFile: karmaConfigFile,
- browsers: browsers,
- specReporter: {
- suppressErrorSummary: false,
- suppressFailed: false,
- suppressPassed: suppressPassed,
- suppressSkipped: true
- },
- detectBrowsers: {
- enabled: enableAllBrowsers
- },
- logLevel: verbose ? Karma.constants.LOG_INFO : Karma.constants.LOG_ERROR,
- files: files,
- client: {
- captureConsole: verbose,
- args: [includeCategory, excludeCategory, webglValidation, webglStub, release]
- }
- }, function(e) {
- return done(failTaskOnError ? e : undefined);
- });
- karma.start();
+ );
+ karma.start();
});
-gulp.task('convertToModules', function() {
- var requiresRegex = /([\s\S]*?(define|defineSuite|require)\((?:{[\s\S]*}, )?\[)([\S\s]*?)]([\s\S]*?function\s*)\(([\S\s]*?)\) {([\s\S]*)/;
- var noModulesRegex = /([\s\S]*?(define|defineSuite|require)\((?:{[\s\S]*}, )?\[?)([\S\s]*?)]?([\s\S]*?function\s*)\(([\S\s]*?)\) {([\s\S]*)/;
- var splitRegex = /,\s*/;
+gulp.task("convertToModules", function () {
+ var requiresRegex = /([\s\S]*?(define|defineSuite|require)\((?:{[\s\S]*}, )?\[)([\S\s]*?)]([\s\S]*?function\s*)\(([\S\s]*?)\) {([\s\S]*)/;
+ var noModulesRegex = /([\s\S]*?(define|defineSuite|require)\((?:{[\s\S]*}, )?\[?)([\S\s]*?)]?([\s\S]*?function\s*)\(([\S\s]*?)\) {([\s\S]*)/;
+ var splitRegex = /,\s*/;
- var fsReadFile = Promise.promisify(fs.readFile);
- var fsWriteFile = Promise.promisify(fs.writeFile);
+ var fsReadFile = Promise.promisify(fs.readFile);
+ var fsWriteFile = Promise.promisify(fs.writeFile);
- var files = globby.sync(filesToConvertES6);
+ var files = globby.sync(filesToConvertES6);
- return Promise.map(files, function(file) {
- return fsReadFile(file).then(function(contents) {
- contents = contents.toString();
- if (contents.startsWith('import')) {
- return;
- }
+ return Promise.map(files, function (file) {
+ return fsReadFile(file).then(function (contents) {
+ contents = contents.toString();
+ if (contents.startsWith("import")) {
+ return;
+ }
- var result = requiresRegex.exec(contents);
+ var result = requiresRegex.exec(contents);
- if (result === null) {
- result = noModulesRegex.exec(contents);
- if (result === null) {
- return;
- }
- }
+ if (result === null) {
+ result = noModulesRegex.exec(contents);
+ if (result === null) {
+ return;
+ }
+ }
- var names = result[3].split(splitRegex);
- if (names.length === 1 && names[0].trim() === '') {
- names.length = 0;
- }
+ var names = result[3].split(splitRegex);
+ if (names.length === 1 && names[0].trim() === "") {
+ names.length = 0;
+ }
- var i;
- for (i = 0; i < names.length; ++i) {
- if (names[i].indexOf('//') >= 0 || names[i].indexOf('/*') >= 0) {
- console.log(file + ' contains comments in the require list. Skipping so nothing gets broken.');
- return;
- }
- }
+ var i;
+ for (i = 0; i < names.length; ++i) {
+ if (names[i].indexOf("//") >= 0 || names[i].indexOf("/*") >= 0) {
+ console.log(
+ file +
+ " contains comments in the require list. Skipping so nothing gets broken."
+ );
+ return;
+ }
+ }
- var identifiers = result[5].split(splitRegex);
- if (identifiers.length === 1 && identifiers[0].trim() === '') {
- identifiers.length = 0;
- }
+ var identifiers = result[5].split(splitRegex);
+ if (identifiers.length === 1 && identifiers[0].trim() === "") {
+ identifiers.length = 0;
+ }
- for (i = 0; i < identifiers.length; ++i) {
- if (identifiers[i].indexOf('//') >= 0 || identifiers[i].indexOf('/*') >= 0) {
- console.log(file + ' contains comments in the require list. Skipping so nothing gets broken.');
- return;
- }
- }
+ for (i = 0; i < identifiers.length; ++i) {
+ if (
+ identifiers[i].indexOf("//") >= 0 ||
+ identifiers[i].indexOf("/*") >= 0
+ ) {
+ console.log(
+ file +
+ " contains comments in the require list. Skipping so nothing gets broken."
+ );
+ return;
+ }
+ }
- var requires = [];
+ var requires = [];
- for (i = 0; i < names.length && i < identifiers.length; ++i) {
- requires.push({
- name : names[i].trim(),
- identifier : identifiers[i].trim()
- });
- }
+ for (i = 0; i < names.length && i < identifiers.length; ++i) {
+ requires.push({
+ name: names[i].trim(),
+ identifier: identifiers[i].trim(),
+ });
+ }
- // Convert back to separate lists for the names and identifiers, and add
- // any additional names or identifiers that don't have a corresponding pair.
- var sortedNames = requires.map(function(item) {
- return item.name.slice(0, -1) + '.js\'';
- });
- for (i = sortedNames.length; i < names.length; ++i) {
- sortedNames.push(names[i].trim());
- }
+ // Convert back to separate lists for the names and identifiers, and add
+ // any additional names or identifiers that don't have a corresponding pair.
+ var sortedNames = requires.map(function (item) {
+ return item.name.slice(0, -1) + ".js'";
+ });
+ for (i = sortedNames.length; i < names.length; ++i) {
+ sortedNames.push(names[i].trim());
+ }
- var sortedIdentifiers = requires.map(function(item) {
- return item.identifier;
- });
- for (i = sortedIdentifiers.length; i < identifiers.length; ++i) {
- sortedIdentifiers.push(identifiers[i].trim());
- }
+ var sortedIdentifiers = requires.map(function (item) {
+ return item.identifier;
+ });
+ for (i = sortedIdentifiers.length; i < identifiers.length; ++i) {
+ sortedIdentifiers.push(identifiers[i].trim());
+ }
- contents = '';
- if (sortedNames.length > 0) {
- for (var q = 0; q < sortedNames.length; q++) {
- var modulePath = sortedNames[q];
- if (file.startsWith('Specs')) {
- modulePath = modulePath.substring(1, modulePath.length - 1);
- var sourceDir = path.dirname(file);
-
- if (modulePath.startsWith('Specs') || modulePath.startsWith('.')) {
- var importPath = modulePath;
- if (modulePath.startsWith('Specs')) {
- importPath = path.relative(sourceDir, modulePath);
- if (importPath[0] !== '.') {
- importPath = './' + importPath;
- }
- }
- modulePath = '\'' + importPath + '\'';
- contents += 'import ' + sortedIdentifiers[q] + ' from ' + modulePath + ';' + os.EOL;
- } else {
- modulePath = '\'' + path.relative(sourceDir, 'Source') + '/Cesium.js' + '\'';
- if (sortedIdentifiers[q] === 'CesiumMath') {
- contents += 'import { Math as CesiumMath } from ' + modulePath + ';' + os.EOL;
- } else {
- contents += 'import { ' + sortedIdentifiers[q] + ' } from ' + modulePath + ';' + os.EOL;
- }
- }
- } else {
- contents += 'import ' + sortedIdentifiers[q] + ' from ' + modulePath + ';' + os.EOL;
- }
+ contents = "";
+ if (sortedNames.length > 0) {
+ for (var q = 0; q < sortedNames.length; q++) {
+ var modulePath = sortedNames[q];
+ if (file.startsWith("Specs")) {
+ modulePath = modulePath.substring(1, modulePath.length - 1);
+ var sourceDir = path.dirname(file);
+
+ if (modulePath.startsWith("Specs") || modulePath.startsWith(".")) {
+ var importPath = modulePath;
+ if (modulePath.startsWith("Specs")) {
+ importPath = path.relative(sourceDir, modulePath);
+ if (importPath[0] !== ".") {
+ importPath = "./" + importPath;
}
- }
-
- var code;
- var codeAndReturn = result[6];
- if (file.endsWith('Spec.js')) {
- var indi = codeAndReturn.lastIndexOf('});');
- code = codeAndReturn.slice(0, indi);
- code = code.trim().replace("'use strict';" + os.EOL, '');
- contents += code + os.EOL;
+ }
+ modulePath = "'" + importPath + "'";
+ contents +=
+ "import " +
+ sortedIdentifiers[q] +
+ " from " +
+ modulePath +
+ ";" +
+ os.EOL;
} else {
- var returnIndex = codeAndReturn.lastIndexOf('return');
-
- code = codeAndReturn.slice(0, returnIndex);
- code = code.trim().replace("'use strict';" + os.EOL, '');
- contents += code + os.EOL;
-
- var returnStatement = codeAndReturn.slice(returnIndex);
- contents += returnStatement.split(';')[0].replace('return ', 'export default ') + ';' + os.EOL;
+ modulePath =
+ "'" + path.relative(sourceDir, "Source") + "/Cesium.js" + "'";
+ if (sortedIdentifiers[q] === "CesiumMath") {
+ contents +=
+ "import { Math as CesiumMath } from " +
+ modulePath +
+ ";" +
+ os.EOL;
+ } else {
+ contents +=
+ "import { " +
+ sortedIdentifiers[q] +
+ " } from " +
+ modulePath +
+ ";" +
+ os.EOL;
+ }
}
+ } else {
+ contents +=
+ "import " +
+ sortedIdentifiers[q] +
+ " from " +
+ modulePath +
+ ";" +
+ os.EOL;
+ }
+ }
+ }
- return fsWriteFile(file, contents);
- });
+ var code;
+ var codeAndReturn = result[6];
+ if (file.endsWith("Spec.js")) {
+ var indi = codeAndReturn.lastIndexOf("});");
+ code = codeAndReturn.slice(0, indi);
+ code = code.trim().replace("'use strict';" + os.EOL, "");
+ contents += code + os.EOL;
+ } else {
+ var returnIndex = codeAndReturn.lastIndexOf("return");
+
+ code = codeAndReturn.slice(0, returnIndex);
+ code = code.trim().replace("'use strict';" + os.EOL, "");
+ contents += code + os.EOL;
+
+ var returnStatement = codeAndReturn.slice(returnIndex);
+ contents +=
+ returnStatement.split(";")[0].replace("return ", "export default ") +
+ ";" +
+ os.EOL;
+ }
+
+ return fsWriteFile(file, contents);
});
+ });
});
function combineCesium(debug, optimizer, combineOutput) {
- var plugins = [];
+ var plugins = [];
- if (!debug) {
- plugins.push(rollupPluginStripPragma({
- pragmas: ['debug']
- }));
- }
- if (optimizer === 'uglify2') {
- plugins.push(rollupPluginUglify.uglify());
- }
-
- return rollup.rollup({
- input: 'Source/Cesium.js',
- plugins: plugins,
- onwarn: rollupWarning
- }).then(function(bundle) {
- return bundle.write({
- format: 'umd',
- name: 'Cesium',
- file: path.join(combineOutput, 'Cesium.js'),
- sourcemap: debug,
- banner: copyrightHeader
- });
+ if (!debug) {
+ plugins.push(
+ rollupPluginStripPragma({
+ pragmas: ["debug"],
+ })
+ );
+ }
+ if (optimizer === "uglify2") {
+ plugins.push(rollupPluginUglify.uglify());
+ }
+
+ return rollup
+ .rollup({
+ input: "Source/Cesium.js",
+ plugins: plugins,
+ onwarn: rollupWarning,
+ })
+ .then(function (bundle) {
+ return bundle.write({
+ format: "umd",
+ name: "Cesium",
+ file: path.join(combineOutput, "Cesium.js"),
+ sourcemap: debug,
+ banner: copyrightHeader,
+ });
});
}
function combineWorkers(debug, optimizer, combineOutput) {
- //This is done waterfall style for concurrency reasons.
- // Copy files that are already minified
- return globby(['Source/ThirdParty/Workers/draco*.js'])
- .then(function(files) {
- var stream = gulp.src(files, { base: 'Source' })
- .pipe(gulp.dest(combineOutput));
- return streamToPromise(stream);
- })
- .then(function () {
- return globby(['Source/Workers/cesiumWorkerBootstrapper.js',
- 'Source/Workers/transferTypedArrayTest.js',
- 'Source/ThirdParty/Workers/*.js',
- // Files are already minified, don't optimize
- '!Source/ThirdParty/Workers/draco*.js']);
- })
- .then(function(files) {
- return Promise.map(files, function(file) {
- return streamToPromise(gulp.src(file)
- .pipe(gulpUglify())
- .pipe(gulp.dest(path.dirname(path.join(combineOutput, path.relative('Source', file))))));
- }, {concurrency : concurrency});
- })
- .then(function() {
- return globby(['Source/WorkersES6/*.js']);
- })
- .then(function(files) {
- var plugins = [];
-
- if (!debug) {
- plugins.push(rollupPluginStripPragma({
- pragmas: ['debug']
- }));
- }
- if (optimizer === 'uglify2') {
- plugins.push(rollupPluginUglify.uglify());
- }
+ //This is done waterfall style for concurrency reasons.
+ // Copy files that are already minified
+ return globby(["Source/ThirdParty/Workers/draco*.js"])
+ .then(function (files) {
+ var stream = gulp
+ .src(files, { base: "Source" })
+ .pipe(gulp.dest(combineOutput));
+ return streamToPromise(stream);
+ })
+ .then(function () {
+ return globby([
+ "Source/Workers/cesiumWorkerBootstrapper.js",
+ "Source/Workers/transferTypedArrayTest.js",
+ "Source/ThirdParty/Workers/*.js",
+ // Files are already minified, don't optimize
+ "!Source/ThirdParty/Workers/draco*.js",
+ ]);
+ })
+ .then(function (files) {
+ return Promise.map(
+ files,
+ function (file) {
+ return streamToPromise(
+ gulp
+ .src(file)
+ .pipe(gulpUglify())
+ .pipe(
+ gulp.dest(
+ path.dirname(
+ path.join(combineOutput, path.relative("Source", file))
+ )
+ )
+ )
+ );
+ },
+ { concurrency: concurrency }
+ );
+ })
+ .then(function () {
+ return globby(["Source/WorkersES6/*.js"]);
+ })
+ .then(function (files) {
+ var plugins = [];
+
+ if (!debug) {
+ plugins.push(
+ rollupPluginStripPragma({
+ pragmas: ["debug"],
+ })
+ );
+ }
+ if (optimizer === "uglify2") {
+ plugins.push(rollupPluginUglify.uglify());
+ }
- return rollup.rollup({
- input: files,
- plugins: plugins,
- onwarn: rollupWarning
- }).then(function(bundle) {
- return bundle.write({
- dir: path.join(combineOutput, 'Workers'),
- format: 'amd',
- sourcemap: debug,
- banner: copyrightHeader
- });
- });
+ return rollup
+ .rollup({
+ input: files,
+ plugins: plugins,
+ onwarn: rollupWarning,
+ })
+ .then(function (bundle) {
+ return bundle.write({
+ dir: path.join(combineOutput, "Workers"),
+ format: "amd",
+ sourcemap: debug,
+ banner: copyrightHeader,
+ });
});
+ });
}
function minifyCSS(outputDirectory) {
- streamToPromise(
- gulp.src('Source/**/*.css')
- .pipe(cleanCSS())
- .pipe(gulp.dest(outputDirectory))
- );
+ streamToPromise(
+ gulp
+ .src("Source/**/*.css")
+ .pipe(cleanCSS())
+ .pipe(gulp.dest(outputDirectory))
+ );
}
function minifyModules(outputDirectory) {
- return streamToPromise(gulp.src('Source/ThirdParty/google-earth-dbroot-parser.js')
- .pipe(gulpUglify())
- .pipe(gulp.dest(outputDirectory + '/ThirdParty/')));
+ return streamToPromise(
+ gulp
+ .src("Source/ThirdParty/google-earth-dbroot-parser.js")
+ .pipe(gulpUglify())
+ .pipe(gulp.dest(outputDirectory + "/ThirdParty/"))
+ );
}
function combineJavaScript(options) {
- var optimizer = options.optimizer;
- var outputDirectory = options.outputDirectory;
- var removePragmas = options.removePragmas;
+ var optimizer = options.optimizer;
+ var outputDirectory = options.outputDirectory;
+ var removePragmas = options.removePragmas;
- var combineOutput = path.join('Build', 'combineOutput', optimizer);
+ var combineOutput = path.join("Build", "combineOutput", optimizer);
- var promise = Promise.join(
- combineCesium(!removePragmas, optimizer, combineOutput),
- combineWorkers(!removePragmas, optimizer, combineOutput),
- minifyModules(outputDirectory)
- );
+ var promise = Promise.join(
+ combineCesium(!removePragmas, optimizer, combineOutput),
+ combineWorkers(!removePragmas, optimizer, combineOutput),
+ minifyModules(outputDirectory)
+ );
- return promise.then(function() {
- var promises = [];
+ return promise.then(function () {
+ var promises = [];
- //copy to build folder with copyright header added at the top
- var stream = gulp.src([combineOutput + '/**'])
- .pipe(gulp.dest(outputDirectory));
+ //copy to build folder with copyright header added at the top
+ var stream = gulp
+ .src([combineOutput + "/**"])
+ .pipe(gulp.dest(outputDirectory));
- promises.push(streamToPromise(stream));
+ promises.push(streamToPromise(stream));
- var everythingElse = ['Source/**', '!**/*.js', '!**/*.glsl'];
- if (optimizer === 'uglify2') {
- promises.push(minifyCSS(outputDirectory));
- everythingElse.push('!**/*.css');
- }
+ var everythingElse = ["Source/**", "!**/*.js", "!**/*.glsl"];
+ if (optimizer === "uglify2") {
+ promises.push(minifyCSS(outputDirectory));
+ everythingElse.push("!**/*.css");
+ }
- stream = gulp.src(everythingElse, { nodir: true }).pipe(gulp.dest(outputDirectory));
- promises.push(streamToPromise(stream));
+ stream = gulp
+ .src(everythingElse, { nodir: true })
+ .pipe(gulp.dest(outputDirectory));
+ promises.push(streamToPromise(stream));
- return Promise.all(promises).then(function() {
- rimraf.sync(combineOutput);
- });
+ return Promise.all(promises).then(function () {
+ rimraf.sync(combineOutput);
});
+ });
}
function glslToJavaScript(minify, minifyStateFilePath) {
- fs.writeFileSync(minifyStateFilePath, minify);
- var minifyStateFileLastModified = fs.existsSync(minifyStateFilePath) ? fs.statSync(minifyStateFilePath).mtime.getTime() : 0;
+ fs.writeFileSync(minifyStateFilePath, minify.toString());
+ var minifyStateFileLastModified = fs.existsSync(minifyStateFilePath)
+ ? fs.statSync(minifyStateFilePath).mtime.getTime()
+ : 0;
+
+ // collect all currently existing JS files into a set, later we will remove the ones
+ // we still are using from the set, then delete any files remaining in the set.
+ var leftOverJsFiles = {};
+
+ globby
+ .sync(["Source/Shaders/**/*.js", "Source/ThirdParty/Shaders/*.js"])
+ .forEach(function (file) {
+ leftOverJsFiles[path.normalize(file)] = true;
+ });
-// collect all currently existing JS files into a set, later we will remove the ones
-// we still are using from the set, then delete any files remaining in the set.
- var leftOverJsFiles = {};
+ var builtinFunctions = [];
+ var builtinConstants = [];
+ var builtinStructs = [];
+
+ var glslFiles = globby.sync([
+ "Source/Shaders/**/*.glsl",
+ "Source/ThirdParty/Shaders/*.glsl",
+ ]);
+ glslFiles.forEach(function (glslFile) {
+ glslFile = path.normalize(glslFile);
+ var baseName = path.basename(glslFile, ".glsl");
+ var jsFile = path.join(path.dirname(glslFile), baseName) + ".js";
+
+ // identify built in functions, structs, and constants
+ var baseDir = path.join("Source", "Shaders", "Builtin");
+ if (
+ glslFile.indexOf(path.normalize(path.join(baseDir, "Functions"))) === 0
+ ) {
+ builtinFunctions.push(baseName);
+ } else if (
+ glslFile.indexOf(path.normalize(path.join(baseDir, "Constants"))) === 0
+ ) {
+ builtinConstants.push(baseName);
+ } else if (
+ glslFile.indexOf(path.normalize(path.join(baseDir, "Structs"))) === 0
+ ) {
+ builtinStructs.push(baseName);
+ }
- globby.sync(['Source/Shaders/**/*.js', 'Source/ThirdParty/Shaders/*.js']).forEach(function(file) {
- leftOverJsFiles[path.normalize(file)] = true;
- });
+ delete leftOverJsFiles[jsFile];
- var builtinFunctions = [];
- var builtinConstants = [];
- var builtinStructs = [];
+ var jsFileExists = fs.existsSync(jsFile);
+ var jsFileModified = jsFileExists ? fs.statSync(jsFile).mtime.getTime() : 0;
+ var glslFileModified = fs.statSync(glslFile).mtime.getTime();
- var glslFiles = globby.sync(['Source/Shaders/**/*.glsl', 'Source/ThirdParty/Shaders/*.glsl']);
- glslFiles.forEach(function(glslFile) {
- glslFile = path.normalize(glslFile);
- var baseName = path.basename(glslFile, '.glsl');
- var jsFile = path.join(path.dirname(glslFile), baseName) + '.js';
+ if (
+ jsFileExists &&
+ jsFileModified > glslFileModified &&
+ jsFileModified > minifyStateFileLastModified
+ ) {
+ return;
+ }
- // identify built in functions, structs, and constants
- var baseDir = path.join('Source', 'Shaders', 'Builtin');
- if (glslFile.indexOf(path.normalize(path.join(baseDir, 'Functions'))) === 0) {
- builtinFunctions.push(baseName);
- }
- else if (glslFile.indexOf(path.normalize(path.join(baseDir, 'Constants'))) === 0) {
- builtinConstants.push(baseName);
- }
- else if (glslFile.indexOf(path.normalize(path.join(baseDir, 'Structs'))) === 0) {
- builtinStructs.push(baseName);
- }
+ var contents = fs.readFileSync(glslFile, "utf8");
+ contents = contents.replace(/\r\n/gm, "\n");
- delete leftOverJsFiles[jsFile];
+ var copyrightComments = "";
+ var extractedCopyrightComments = contents.match(
+ /\/\*\*(?:[^*\/]|\*(?!\/)|\n)*?@license(?:.|\n)*?\*\//gm
+ );
+ if (extractedCopyrightComments) {
+ copyrightComments = extractedCopyrightComments.join("\n") + "\n";
+ }
- var jsFileExists = fs.existsSync(jsFile);
- var jsFileModified = jsFileExists ? fs.statSync(jsFile).mtime.getTime() : 0;
- var glslFileModified = fs.statSync(glslFile).mtime.getTime();
+ if (minify) {
+ contents = glslStripComments(contents);
+ contents = contents
+ .replace(/\s+$/gm, "")
+ .replace(/^\s+/gm, "")
+ .replace(/\n+/gm, "\n");
+ contents += "\n";
+ }
- if (jsFileExists && jsFileModified > glslFileModified && jsFileModified > minifyStateFileLastModified) {
- return;
- }
+ contents = contents.split('"').join('\\"').replace(/\n/gm, "\\n\\\n");
+ contents =
+ copyrightComments +
+ '\
+//This file is automatically rebuilt by the Cesium build process.\n\
+export default "' +
+ contents +
+ '";\n';
+
+ fs.writeFileSync(jsFile, contents);
+ });
+
+ // delete any left over JS files from old shaders
+ Object.keys(leftOverJsFiles).forEach(function (filepath) {
+ rimraf.sync(filepath);
+ });
+
+ var generateBuiltinContents = function (contents, builtins, path) {
+ for (var i = 0; i < builtins.length; i++) {
+ var builtin = builtins[i];
+ contents.imports.push(
+ "import czm_" + builtin + " from './" + path + "/" + builtin + ".js'"
+ );
+ contents.builtinLookup.push("czm_" + builtin + " : " + "czm_" + builtin);
+ }
+ };
+
+ //generate the JS file for Built-in GLSL Functions, Structs, and Constants
+ var contents = {
+ imports: [],
+ builtinLookup: [],
+ };
+ generateBuiltinContents(contents, builtinConstants, "Constants");
+ generateBuiltinContents(contents, builtinStructs, "Structs");
+ generateBuiltinContents(contents, builtinFunctions, "Functions");
+
+ var fileContents =
+ "//This file is automatically rebuilt by the Cesium build process.\n" +
+ contents.imports.join("\n") +
+ "\n\nexport default {\n " +
+ contents.builtinLookup.join(",\n ") +
+ "\n};\n";
+
+ fs.writeFileSync(
+ path.join("Source", "Shaders", "Builtin", "CzmBuiltins.js"),
+ fileContents
+ );
+}
- var contents = fs.readFileSync(glslFile, 'utf8');
- contents = contents.replace(/\r\n/gm, '\n');
+function createCesiumJs() {
+ var contents = `export var VERSION = '${version}';\n`;
+ globby.sync(sourceFiles).forEach(function (file) {
+ file = path.relative("Source", file);
- var copyrightComments = '';
- var extractedCopyrightComments = contents.match(/\/\*\*(?:[^*\/]|\*(?!\/)|\n)*?@license(?:.|\n)*?\*\//gm);
- if (extractedCopyrightComments) {
- copyrightComments = extractedCopyrightComments.join('\n') + '\n';
- }
+ var moduleId = file;
+ moduleId = filePathToModuleId(moduleId);
- if (minify) {
- contents = glslStripComments(contents);
- contents = contents.replace(/\s+$/gm, '').replace(/^\s+/gm, '').replace(/\n+/gm, '\n');
- contents += '\n';
- }
+ var assignmentName = path.basename(file, path.extname(file));
+ if (moduleId.indexOf("Shaders/") === 0) {
+ assignmentName = "_shaders" + assignmentName;
+ }
+ assignmentName = assignmentName.replace(/(\.|-)/g, "_");
+ contents +=
+ "export { default as " +
+ assignmentName +
+ " } from './" +
+ moduleId +
+ ".js';" +
+ os.EOL;
+ });
+
+ fs.writeFileSync("Source/Cesium.js", contents);
+}
- contents = contents.split('"').join('\\"').replace(/\n/gm, '\\n\\\n');
- contents = copyrightComments + '\
-//This file is automatically rebuilt by the Cesium build process.\n\
-export default "' + contents + '";\n';
+function createTypeScriptDefinitions() {
+ // Run jsdoc with tsd-jsdoc to generate an initial Cesium.d.ts file.
+ child_process.execSync("npx jsdoc --configure Tools/jsdoc/ts-conf.json", {
+ stdio: "inherit",
+ });
+
+ var source = fs.readFileSync("Source/Cesium.d.ts").toString();
+
+ // All of our enum assignments that alias to WebGLConstants, such as PixelDatatype.js
+ // end up as enum strings instead of actually mapping values to WebGLConstants.
+ // We fix this with a simple regex replace later on, but it means the
+ // WebGLConstants constants enum needs to be defined in the file before it can
+ // be used. This block of code reads in the TS file, finds the WebGLConstants
+ // declaration, and then writes the file back out (in memory to source) with
+ // WebGLConstants being the first module.
+ const node = typescript.createSourceFile(
+ "Source/Cesium.d.ts",
+ source,
+ typescript.ScriptTarget.Latest
+ );
+ let firstNode;
+ node.forEachChild((child) => {
+ if (
+ typescript.SyntaxKind[child.kind] === "EnumDeclaration" &&
+ child.name.escapedText === "WebGLConstants"
+ ) {
+ firstNode = child;
+ }
+ });
+
+ const printer = typescript.createPrinter({
+ removeComments: false,
+ newLine: typescript.NewLineKind.LineFeed,
+ });
+
+ let newSource = "";
+ newSource += printer.printNode(
+ typescript.EmitHint.Unspecified,
+ firstNode,
+ node
+ );
+ node.forEachChild((child) => {
+ if (
+ typescript.SyntaxKind[child.kind] !== "EnumDeclaration" ||
+ child.name.escapedText !== "WebGLConstants"
+ ) {
+ newSource += printer.printNode(
+ typescript.EmitHint.Unspecified,
+ child,
+ node
+ );
+ newSource += "\n\n";
+ }
+ });
+ source = newSource;
+
+ // The next step is to find the list of Cesium modules exported by the Cesium API
+ // So that we can map these modules with a link back to their original source file.
+
+ var regex = /^declare (function|class|namespace|enum) (.+)/gm;
+ var matches;
+ var publicModules = new Set();
+ //eslint-disable-next-line no-cond-assign
+ while ((matches = regex.exec(source))) {
+ const moduleName = matches[2].match(/([^\s|\(]+)/);
+ publicModules.add(moduleName[1]);
+ }
+
+ // Math shows up as "Math" because of it's aliasing from CesiumMath and namespace collision with actual Math
+ // It fails the above regex so just add it directly here.
+ publicModules.add("Math");
+
+ // Fix up the output to match what we need
+ // declare => export since we are wrapping everything in a namespace
+ // CesiumMath => Math (because no CesiumJS build step would be complete without special logic for the Math class)
+ // Fix up the WebGLConstants aliasing we mentioned above by simply unquoting the strings.
+ source = source
+ .replace(/^declare /gm, "export ")
+ .replace(/module "Math"/gm, "namespace Math")
+ .replace(/CesiumMath/gm, "Math")
+ .replace(/Number\[]/gm, "number[]") // Workaround https://github.com/englercj/tsd-jsdoc/issues/117
+ .replace(/String\[]/gm, "string[]")
+ .replace(/Boolean\[]/gm, "boolean[]")
+ .replace(/Object\[]/gm, "object[]")
+ .replace(//gm, "")
+ .replace(//gm, "")
+ .replace(//gm, "")
+ .replace(//gm, "")
+ .replace(
+ /= "WebGLConstants\.(.+)"/gm,
+ (match, p1) => `= WebGLConstants.${p1}`
+ );
- fs.writeFileSync(jsFile, contents);
- });
+ // Wrap the source to actually be inside of a declared cesium module
+ // and add any workaround and private utility types.
+ source = `declare module "cesium" {
- // delete any left over JS files from old shaders
- Object.keys(leftOverJsFiles).forEach(function(filepath) {
- rimraf.sync(filepath);
- });
+/**
+ * Private interfaces to support PropertyBag being a dictionary-like object.
+ */
+interface DictionaryLike {
+ [index: string]: any;
+}
- var generateBuiltinContents = function(contents, builtins, path) {
- for (var i = 0; i < builtins.length; i++) {
- var builtin = builtins[i];
- contents.imports.push('import czm_' + builtin + ' from \'./' + path + '/' + builtin + '.js\'');
- contents.builtinLookup.push('czm_' + builtin + ' : ' + 'czm_' + builtin);
- }
- };
+${source}
+}
- //generate the JS file for Built-in GLSL Functions, Structs, and Constants
- var contents = {
- imports : [],
- builtinLookup: []
- };
- generateBuiltinContents(contents, builtinConstants, 'Constants');
- generateBuiltinContents(contents, builtinStructs, 'Structs');
- generateBuiltinContents(contents, builtinFunctions, 'Functions');
+`;
- var fileContents = '//This file is automatically rebuilt by the Cesium build process.\n' +
- contents.imports.join('\n') +
- '\n\nexport default {\n ' + contents.builtinLookup.join(',\n ') + '\n};\n';
+ // Map individual modules back to their source file so that TS still works
+ // when importing individual files instead of the entire cesium module.
+ globby.sync(sourceFiles).forEach(function (file) {
+ file = path.relative("Source", file);
- fs.writeFileSync(path.join('Source', 'Shaders', 'Builtin', 'CzmBuiltins.js'), fileContents);
-}
+ var moduleId = file;
+ moduleId = filePathToModuleId(moduleId);
-function createCesiumJs() {
- var contents = `export var VERSION = '${version}';\n`;
- globby.sync(sourceFiles).forEach(function(file) {
- file = path.relative('Source', file);
+ var assignmentName = path.basename(file, path.extname(file));
+ if (publicModules.has(assignmentName)) {
+ publicModules.delete(assignmentName);
+ source += `declare module "cesium/Source/${moduleId}" { import { ${assignmentName} } from 'cesium'; export default ${assignmentName}; }\n`;
+ }
+ });
- var moduleId = file;
- moduleId = filePathToModuleId(moduleId);
+ // Write the final source file back out
+ fs.writeFileSync("Source/Cesium.d.ts", source);
- var assignmentName = path.basename(file, path.extname(file));
- if (moduleId.indexOf('Shaders/') === 0) {
- assignmentName = '_shaders' + assignmentName;
- }
- assignmentName = assignmentName.replace(/(\.|-)/g, '_');
- contents += 'export { default as ' + assignmentName + " } from './" + moduleId + ".js';" + os.EOL;
- });
+ // Use tsc to compile it and make sure it is valid
+ child_process.execSync("npx tsc -p Tools/jsdoc/tsconfig.json", {
+ stdio: "inherit",
+ });
+
+ // Also compile our smokescreen to make sure interfaces work as expected.
+ child_process.execSync("npx tsc -p Specs/TypeScript/tsconfig.json", {
+ stdio: "inherit",
+ });
- fs.writeFileSync('Source/Cesium.js', contents);
+ // Below is a sanity check to make sure we didn't leave anything out that
+ // we don't already know about
+
+ // Intentionally ignored nested items
+ publicModules.delete("KmlFeatureData");
+ publicModules.delete("MaterialAppearance");
+
+ if (publicModules.size !== 0) {
+ throw new Error(
+ "Unexpected unexposed modules: " +
+ Array.from(publicModules.values()).join(", ")
+ );
+ }
}
function createSpecList() {
- var specFiles = globby.sync(['Specs/**/*Spec.js']);
+ var specFiles = globby.sync(["Specs/**/*Spec.js"]);
- var contents = '';
- specFiles.forEach(function(file) {
- contents += "import './" + filePathToModuleId(file).replace('Specs/', '') + ".js';\n";
- });
+ var contents = "";
+ specFiles.forEach(function (file) {
+ contents +=
+ "import './" + filePathToModuleId(file).replace("Specs/", "") + ".js';\n";
+ });
- fs.writeFileSync(path.join('Specs', 'SpecList.js'), contents);
+ fs.writeFileSync(path.join("Specs", "SpecList.js"), contents);
}
function createGalleryList() {
- var demoObjects = [];
- var demoJSONs = [];
- var output = path.join('Apps', 'Sandcastle', 'gallery', 'gallery-index.js');
+ var demoObjects = [];
+ var demoJSONs = [];
+ var output = path.join("Apps", "Sandcastle", "gallery", "gallery-index.js");
+
+ var fileList = ["Apps/Sandcastle/gallery/**/*.html"];
+ if (noDevelopmentGallery) {
+ fileList.push("!Apps/Sandcastle/gallery/development/**/*.html");
+ }
+
+ // On travis, the version is set to something like '1.43.0-branch-name-travisBuildNumber'
+ // We need to extract just the Major.Minor version
+ var majorMinor = packageJson.version.match(/^(.*)\.(.*)\./);
+ var major = majorMinor[1];
+ var minor = Number(majorMinor[2]) - 1; // We want the last release, not current release
+ var tagVersion = major + "." + minor;
+
+ // Get an array of demos that were added since the last release.
+ // This includes newly staged local demos as well.
+ var newDemos = [];
+ try {
+ newDemos = child_process
+ .execSync(
+ "git diff --name-only --diff-filter=A " +
+ tagVersion +
+ " Apps/Sandcastle/gallery/*.html",
+ { stdio: ["pipe", "pipe", "ignore"] }
+ )
+ .toString()
+ .trim()
+ .split("\n");
+ } catch (e) {
+ // On a Cesium fork, tags don't exist so we can't generate the list.
+ }
+
+ var helloWorld;
+ globby.sync(fileList).forEach(function (file) {
+ var demo = filePathToModuleId(
+ path.relative("Apps/Sandcastle/gallery", file)
+ );
- var fileList = ['Apps/Sandcastle/gallery/**/*.html'];
- if (noDevelopmentGallery) {
- fileList.push('!Apps/Sandcastle/gallery/development/**/*.html');
- }
+ var demoObject = {
+ name: demo,
+ isNew: newDemos.includes(file),
+ };
- // On travis, the version is set to something like '1.43.0-branch-name-travisBuildNumber'
- // We need to extract just the Major.Minor version
- var majorMinor = packageJson.version.match(/^(.*)\.(.*)\./);
- var major = majorMinor[1];
- var minor = Number(majorMinor[2]) - 1; // We want the last release, not current release
- var tagVersion = major + '.' + minor;
-
- // Get an array of demos that were added since the last release.
- // This includes newly staged local demos as well.
- var newDemos = [];
- try {
- newDemos = child_process.execSync('git diff --name-only --diff-filter=A ' + tagVersion + ' Apps/Sandcastle/gallery/*.html', { stdio: ['pipe', 'pipe', 'ignore'] }).toString().trim().split('\n');
- } catch (e) {
- // On a Cesium fork, tags don't exist so we can't generate the list.
+ if (fs.existsSync(file.replace(".html", "") + ".jpg")) {
+ demoObject.img = demo + ".jpg";
}
- var helloWorld;
- globby.sync(fileList).forEach(function(file) {
- var demo = filePathToModuleId(path.relative('Apps/Sandcastle/gallery', file));
+ demoObjects.push(demoObject);
- var demoObject = {
- name : demo,
- isNew: newDemos.includes(file)
- };
-
- if (fs.existsSync(file.replace('.html', '') + '.jpg')) {
- demoObject.img = demo + '.jpg';
- }
-
- demoObjects.push(demoObject);
-
- if (demo === 'Hello World') {
- helloWorld = demoObject;
- }
- });
-
- demoObjects.sort(function(a, b) {
- if (a.name < b.name) {
- return -1;
- } else if (a.name > b.name) {
- return 1;
- }
- return 0;
- });
-
- var helloWorldIndex = Math.max(demoObjects.indexOf(helloWorld), 0);
+ if (demo === "Hello World") {
+ helloWorld = demoObject;
+ }
+ });
- var i;
- for (i = 0; i < demoObjects.length; ++i) {
- demoJSONs[i] = JSON.stringify(demoObjects[i], null, 2);
+ demoObjects.sort(function (a, b) {
+ if (a.name < b.name) {
+ return -1;
+ } else if (a.name > b.name) {
+ return 1;
}
+ return 0;
+ });
- var contents = '\
-// This file is automatically rebuilt by the Cesium build process.\n\
-var hello_world_index = ' + helloWorldIndex + ';\n\
-var VERSION = \'' + version + '\';\n\
-var gallery_demos = [' + demoJSONs.join(', ') + '];\n\
-var has_new_gallery_demos = ' + (newDemos.length > 0 ? 'true;' : 'false;') + '\n';
+ var helloWorldIndex = Math.max(demoObjects.indexOf(helloWorld), 0);
- fs.writeFileSync(output, contents);
+ var i;
+ for (i = 0; i < demoObjects.length; ++i) {
+ demoJSONs[i] = JSON.stringify(demoObjects[i], null, 2);
+ }
- // Compile CSS for Sandcastle
- return streamToPromise(gulp.src(path.join('Apps', 'Sandcastle', 'templates', 'bucketRaw.css'))
- .pipe(cleanCSS())
- .pipe(gulpRename('bucket.css'))
- .pipe(gulpInsert.prepend('/* This file is automatically rebuilt by the Cesium build process. */\n'))
- .pipe(gulp.dest(path.join('Apps', 'Sandcastle', 'templates'))));
+ var contents =
+ "\
+// This file is automatically rebuilt by the Cesium build process.\n\
+var hello_world_index = " +
+ helloWorldIndex +
+ ";\n\
+var VERSION = '" +
+ version +
+ "';\n\
+var gallery_demos = [" +
+ demoJSONs.join(", ") +
+ "];\n\
+var has_new_gallery_demos = " +
+ (newDemos.length > 0 ? "true;" : "false;") +
+ "\n";
+
+ fs.writeFileSync(output, contents);
+
+ // Compile CSS for Sandcastle
+ return streamToPromise(
+ gulp
+ .src(path.join("Apps", "Sandcastle", "templates", "bucketRaw.css"))
+ .pipe(cleanCSS())
+ .pipe(gulpRename("bucket.css"))
+ .pipe(
+ gulpInsert.prepend(
+ "/* This file is automatically rebuilt by the Cesium build process. */\n"
+ )
+ )
+ .pipe(gulp.dest(path.join("Apps", "Sandcastle", "templates")))
+ );
}
function createJsHintOptions() {
- var primary = JSON.parse(fs.readFileSync(path.join('Apps', '.jshintrc'), 'utf8'));
- var gallery = JSON.parse(fs.readFileSync(path.join('Apps', 'Sandcastle', '.jshintrc'), 'utf8'));
- primary.jasmine = false;
- primary.predef = gallery.predef;
- primary.unused = gallery.unused;
- primary.esversion = gallery.esversion;
-
- var contents = '\
+ var primary = JSON.parse(
+ fs.readFileSync(path.join("Apps", ".jshintrc"), "utf8")
+ );
+ var gallery = JSON.parse(
+ fs.readFileSync(path.join("Apps", "Sandcastle", ".jshintrc"), "utf8")
+ );
+ primary.jasmine = false;
+ primary.predef = gallery.predef;
+ primary.unused = gallery.unused;
+ primary.esversion = gallery.esversion;
+
+ var contents =
+ "\
// This file is automatically rebuilt by the Cesium build process.\n\
-var sandcastleJsHintOptions = ' + JSON.stringify(primary, null, 4) + ';\n';
-
- fs.writeFileSync(path.join('Apps', 'Sandcastle', 'jsHintOptions.js'), contents);
+var sandcastleJsHintOptions = " +
+ JSON.stringify(primary, null, 4) +
+ ";\n";
+
+ fs.writeFileSync(
+ path.join("Apps", "Sandcastle", "jsHintOptions.js"),
+ contents
+ );
}
function buildSandcastle() {
- var appStream = gulp.src([
- 'Apps/Sandcastle/**',
- '!Apps/Sandcastle/load-cesium-es6.js',
- '!Apps/Sandcastle/standalone.html',
- '!Apps/Sandcastle/images/**',
- '!Apps/Sandcastle/gallery/**.jpg'
- ])
- // Remove dev-only ES6 module loading for unbuilt Cesium
- .pipe(gulpReplace(' ', ''))
- .pipe(gulpReplace('nomodule', ''))
- // Fix relative paths for new location
- .pipe(gulpReplace('../../../Build', '../../..'))
- .pipe(gulpReplace('../../Source', '../../../Source'))
- .pipe(gulpReplace('../../ThirdParty', '../../../ThirdParty'))
- .pipe(gulpReplace('../../SampleData', '../../../../Apps/SampleData'))
- .pipe(gulpReplace('Build/Documentation', 'Documentation'))
- .pipe(gulp.dest('Build/Apps/Sandcastle'));
-
- var imageStream = gulp.src([
- 'Apps/Sandcastle/gallery/**.jpg',
- 'Apps/Sandcastle/images/**'
- ], {
- base: 'Apps/Sandcastle',
- buffer: false
- })
- .pipe(gulp.dest('Build/Apps/Sandcastle'));
-
- var standaloneStream = gulp.src([
- 'Apps/Sandcastle/standalone.html'
- ])
- .pipe(gulpReplace(' ', ''))
- .pipe(gulpReplace('nomodule', ''))
- .pipe(gulpReplace('../../Build', '../..'))
- .pipe(gulp.dest('Build/Apps/Sandcastle'));
-
- return streamToPromise(mergeStream(appStream, imageStream, standaloneStream));
+ var appStream = gulp
+ .src([
+ "Apps/Sandcastle/**",
+ "!Apps/Sandcastle/load-cesium-es6.js",
+ "!Apps/Sandcastle/standalone.html",
+ "!Apps/Sandcastle/images/**",
+ "!Apps/Sandcastle/gallery/**.jpg",
+ ])
+ // Remove dev-only ES6 module loading for unbuilt Cesium
+ .pipe(
+ gulpReplace(
+ ' ',
+ ""
+ )
+ )
+ .pipe(gulpReplace("nomodule", ""))
+ // Fix relative paths for new location
+ .pipe(gulpReplace("../../../Build", "../../.."))
+ .pipe(gulpReplace("../../Source", "../../../Source"))
+ .pipe(gulpReplace("../../ThirdParty", "../../../ThirdParty"))
+ .pipe(gulpReplace("../../SampleData", "../../../../Apps/SampleData"))
+ .pipe(gulpReplace("Build/Documentation", "Documentation"))
+ .pipe(gulp.dest("Build/Apps/Sandcastle"));
+
+ var imageStream = gulp
+ .src(["Apps/Sandcastle/gallery/**.jpg", "Apps/Sandcastle/images/**"], {
+ base: "Apps/Sandcastle",
+ buffer: false,
+ })
+ .pipe(gulp.dest("Build/Apps/Sandcastle"));
+
+ var standaloneStream = gulp
+ .src(["Apps/Sandcastle/standalone.html"])
+ .pipe(
+ gulpReplace(
+ ' ',
+ ""
+ )
+ )
+ .pipe(gulpReplace("nomodule", ""))
+ .pipe(gulpReplace("../../Build", "../.."))
+ .pipe(gulp.dest("Build/Apps/Sandcastle"));
+
+ return streamToPromise(mergeStream(appStream, imageStream, standaloneStream));
}
function buildCesiumViewer() {
- var cesiumViewerOutputDirectory = 'Build/Apps/CesiumViewer';
- mkdirp.sync(cesiumViewerOutputDirectory);
-
- var promise = Promise.join(
- rollup.rollup({
- input: 'Apps/CesiumViewer/CesiumViewer.js',
- treeshake: {
- moduleSideEffects: false
- },
- plugins: [
- rollupPluginStripPragma({
- pragmas: ['debug']
- }),
- rollupPluginUglify.uglify()
- ],
- onwarn: rollupWarning
- }).then(function(bundle) {
- return bundle.write({
- file: 'Build/Apps/CesiumViewer/CesiumViewer.js',
- format: 'iife'
- });
- })
- );
+ var cesiumViewerOutputDirectory = "Build/Apps/CesiumViewer";
+ mkdirp.sync(cesiumViewerOutputDirectory);
+
+ var promise = Promise.join(
+ rollup
+ .rollup({
+ input: "Apps/CesiumViewer/CesiumViewer.js",
+ treeshake: {
+ moduleSideEffects: false,
+ },
+ plugins: [
+ rollupPluginStripPragma({
+ pragmas: ["debug"],
+ }),
+ rollupPluginUglify.uglify(),
+ ],
+ onwarn: rollupWarning,
+ })
+ .then(function (bundle) {
+ return bundle.write({
+ file: "Build/Apps/CesiumViewer/CesiumViewer.js",
+ format: "iife",
+ });
+ })
+ );
+
+ promise = promise.then(function () {
+ var stream = mergeStream(
+ gulp
+ .src("Build/Apps/CesiumViewer/CesiumViewer.js")
+ .pipe(gulpInsert.prepend(copyrightHeader))
+ .pipe(gulpReplace("../../Source", "."))
+ .pipe(gulp.dest(cesiumViewerOutputDirectory)),
+
+ gulp
+ .src("Apps/CesiumViewer/CesiumViewer.css")
+ .pipe(cleanCSS())
+ .pipe(gulpReplace("../../Source", "."))
+ .pipe(gulp.dest(cesiumViewerOutputDirectory)),
+
+ gulp
+ .src("Apps/CesiumViewer/index.html")
+ .pipe(gulpReplace('type="module"', ""))
+ .pipe(gulp.dest(cesiumViewerOutputDirectory)),
+
+ gulp.src([
+ "Apps/CesiumViewer/**",
+ "!Apps/CesiumViewer/index.html",
+ "!Apps/CesiumViewer/**/*.js",
+ "!Apps/CesiumViewer/**/*.css",
+ ]),
+
+ gulp.src(
+ [
+ "Build/Cesium/Assets/**",
+ "Build/Cesium/Workers/**",
+ "Build/Cesium/ThirdParty/**",
+ "Build/Cesium/Widgets/**",
+ "!Build/Cesium/Widgets/**/*.css",
+ ],
+ {
+ base: "Build/Cesium",
+ nodir: true,
+ }
+ ),
- promise = promise.then(function() {
- var stream = mergeStream(
- gulp.src('Build/Apps/CesiumViewer/CesiumViewer.js')
- .pipe(gulpInsert.prepend(copyrightHeader))
- .pipe(gulpReplace('../../Source', '.'))
- .pipe(gulp.dest(cesiumViewerOutputDirectory)),
-
- gulp.src('Apps/CesiumViewer/CesiumViewer.css')
- .pipe(cleanCSS())
- .pipe(gulpReplace('../../Source', '.'))
- .pipe(gulp.dest(cesiumViewerOutputDirectory)),
-
- gulp.src('Apps/CesiumViewer/index.html')
- .pipe(gulpReplace('type="module"', ''))
- .pipe(gulp.dest(cesiumViewerOutputDirectory)),
-
- gulp.src(['Apps/CesiumViewer/**',
- '!Apps/CesiumViewer/index.html',
- '!Apps/CesiumViewer/**/*.js',
- '!Apps/CesiumViewer/**/*.css']),
-
- gulp.src(['Build/Cesium/Assets/**',
- 'Build/Cesium/Workers/**',
- 'Build/Cesium/ThirdParty/**',
- 'Build/Cesium/Widgets/**',
- '!Build/Cesium/Widgets/**/*.css'],
- {
- base : 'Build/Cesium',
- nodir : true
- }),
-
- gulp.src(['Build/Cesium/Widgets/InfoBox/InfoBoxDescription.css'], {
- base : 'Build/Cesium'
- }),
-
- gulp.src(['web.config'])
- );
+ gulp.src(["Build/Cesium/Widgets/InfoBox/InfoBoxDescription.css"], {
+ base: "Build/Cesium",
+ }),
- return streamToPromise(stream.pipe(gulp.dest(cesiumViewerOutputDirectory)));
- });
+ gulp.src(["web.config"])
+ );
+
+ return streamToPromise(stream.pipe(gulp.dest(cesiumViewerOutputDirectory)));
+ });
- return promise;
+ return promise;
}
function filePathToModuleId(moduleId) {
- return moduleId.substring(0, moduleId.lastIndexOf('.')).replace(/\\/g, '/');
+ return moduleId.substring(0, moduleId.lastIndexOf(".")).replace(/\\/g, "/");
}
diff --git a/index.cjs b/index.cjs
index fcae39adb52a..0fcc8a7a5513 100644
--- a/index.cjs
+++ b/index.cjs
@@ -1,12 +1,12 @@
/*eslint-env node*/
-'use strict';
+"use strict";
-var path = require('path');
+var path = require("path");
// If in 'production' mode, use the combined/minified/optimized version of Cesium
-if (process.env.NODE_ENV === 'production') {
- module.exports = require(path.join(__dirname, 'Build/Cesium/Cesium'));
- return;
+if (process.env.NODE_ENV === "production") {
+ module.exports = require(path.join(__dirname, "Build/Cesium/Cesium"));
+ return;
}
-module.exports = require(path.join(__dirname, 'Build/CesiumUnminified/Cesium'));
+module.exports = require(path.join(__dirname, "Build/CesiumUnminified/Cesium"));
diff --git a/package.json b/package.json
index 2b1ec9a26936..da71fe951649 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cesium",
- "version": "1.69.0",
+ "version": "1.70.1",
"description": "CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.",
"homepage": "http://cesium.com/cesiumjs/",
"license": "Apache-2.0",
@@ -31,6 +31,7 @@
},
"main": "index.cjs",
"module": "./Source/Cesium.js",
+ "types": "./Source/Cesium.d.ts",
"exports": {
"require": "./index.cjs",
"import": "./Source/Cesium.js"
@@ -83,6 +84,8 @@
"rollup-plugin-strip-pragma": "^1.0.0",
"rollup-plugin-uglify": "^6.0.3",
"stream-to-promise": "^2.2.0",
+ "tsd-jsdoc": "^2.5.0",
+ "typescript": "^3.9.2",
"yargs": "^15.0.1"
},
"husky": {
@@ -96,6 +99,7 @@
"startPublic": "node server.cjs --public",
"build": "gulp build",
"build-watch": "gulp build-watch",
+ "build-ts": "gulp build-ts",
"buildApps": "gulp buildApps",
"clean": "gulp clean",
"cloc": "gulp cloc",
diff --git a/server.cjs b/server.cjs
index 59fa98628478..2c48004c1d44 100644
--- a/server.cjs
+++ b/server.cjs
@@ -1,202 +1,244 @@
/*eslint-env node*/
-'use strict';
-(function() {
- var express = require('express');
- var compression = require('compression');
- var fs = require('fs');
- var url = require('url');
- var request = require('request');
-
- var gzipHeader = Buffer.from('1F8B08', 'hex');
-
- var yargs = require('yargs').options({
- 'port' : {
- 'default' : 8080,
- 'description' : 'Port to listen on.'
- },
- 'public' : {
- 'type' : 'boolean',
- 'description' : 'Run a public server that listens on all interfaces.'
- },
- 'upstream-proxy' : {
- 'description' : 'A standard proxy server that will be used to retrieve data. Specify a URL including port, e.g. "http://proxy:8000".'
- },
- 'bypass-upstream-proxy-hosts' : {
- 'description' : 'A comma separated list of hosts that will bypass the specified upstream_proxy, e.g. "lanhost1,lanhost2"'
- },
- 'help' : {
- 'alias' : 'h',
- 'type' : 'boolean',
- 'description' : 'Show this help.'
- }
+"use strict";
+(function () {
+ var express = require("express");
+ var compression = require("compression");
+ var fs = require("fs");
+ var url = require("url");
+ var request = require("request");
+
+ var gzipHeader = Buffer.from("1F8B08", "hex");
+
+ var yargs = require("yargs").options({
+ port: {
+ default: 8080,
+ description: "Port to listen on.",
+ },
+ public: {
+ type: "boolean",
+ description: "Run a public server that listens on all interfaces.",
+ },
+ "upstream-proxy": {
+ description:
+ 'A standard proxy server that will be used to retrieve data. Specify a URL including port, e.g. "http://proxy:8000".',
+ },
+ "bypass-upstream-proxy-hosts": {
+ description:
+ 'A comma separated list of hosts that will bypass the specified upstream_proxy, e.g. "lanhost1,lanhost2"',
+ },
+ help: {
+ alias: "h",
+ type: "boolean",
+ description: "Show this help.",
+ },
+ });
+ var argv = yargs.argv;
+
+ if (argv.help) {
+ return yargs.showHelp();
+ }
+
+ // eventually this mime type configuration will need to change
+ // https://github.com/visionmedia/send/commit/d2cb54658ce65948b0ed6e5fb5de69d022bef941
+ // *NOTE* Any changes you make here must be mirrored in web.config.
+ var mime = express.static.mime;
+ mime.define(
+ {
+ "application/json": ["czml", "json", "geojson", "topojson"],
+ "application/wasm": ["wasm"],
+ "image/crn": ["crn"],
+ "image/ktx": ["ktx"],
+ "model/gltf+json": ["gltf"],
+ "model/gltf-binary": ["bgltf", "glb"],
+ "application/octet-stream": [
+ "b3dm",
+ "pnts",
+ "i3dm",
+ "cmpt",
+ "geom",
+ "vctr",
+ ],
+ "text/plain": ["glsl"],
+ },
+ true
+ );
+
+ var app = express();
+ app.use(compression());
+ app.use(function (req, res, next) {
+ res.header("Access-Control-Allow-Origin", "*");
+ res.header(
+ "Access-Control-Allow-Headers",
+ "Origin, X-Requested-With, Content-Type, Accept"
+ );
+ next();
+ });
+
+ function checkGzipAndNext(req, res, next) {
+ var reqUrl = url.parse(req.url, true);
+ var filePath = reqUrl.pathname.substring(1);
+
+ var readStream = fs.createReadStream(filePath, { start: 0, end: 2 });
+ readStream.on("error", function (err) {
+ next();
});
- var argv = yargs.argv;
- if (argv.help) {
- return yargs.showHelp();
+ readStream.on("data", function (chunk) {
+ if (chunk.equals(gzipHeader)) {
+ res.header("Content-Encoding", "gzip");
+ }
+ next();
+ });
+ }
+
+ var knownTilesetFormats = [
+ /\.b3dm/,
+ /\.pnts/,
+ /\.i3dm/,
+ /\.cmpt/,
+ /\.glb/,
+ /\.geom/,
+ /\.vctr/,
+ /tileset.*\.json$/,
+ ];
+ app.get(knownTilesetFormats, checkGzipAndNext);
+
+ app.use(express.static(__dirname));
+
+ function getRemoteUrlFromParam(req) {
+ var remoteUrl = req.params[0];
+ if (remoteUrl) {
+ // add http:// to the URL if no protocol is present
+ if (!/^https?:\/\//.test(remoteUrl)) {
+ remoteUrl = "http://" + remoteUrl;
+ }
+ remoteUrl = url.parse(remoteUrl);
+ // copy query string
+ remoteUrl.search = url.parse(req.url).search;
}
-
- // eventually this mime type configuration will need to change
- // https://github.com/visionmedia/send/commit/d2cb54658ce65948b0ed6e5fb5de69d022bef941
- // *NOTE* Any changes you make here must be mirrored in web.config.
- var mime = express.static.mime;
- mime.define({
- 'application/json' : ['czml', 'json', 'geojson', 'topojson'],
- 'application/wasm' : ['wasm'],
- 'image/crn' : ['crn'],
- 'image/ktx' : ['ktx'],
- 'model/gltf+json' : ['gltf'],
- 'model/gltf-binary' : ['bgltf', 'glb'],
- 'application/octet-stream' : ['b3dm', 'pnts', 'i3dm', 'cmpt', 'geom', 'vctr'],
- 'text/plain' : ['glsl']
- }, true);
-
- var app = express();
- app.use(compression());
- app.use(function(req, res, next) {
- res.header('Access-Control-Allow-Origin', '*');
- res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
- next();
+ return remoteUrl;
+ }
+
+ var dontProxyHeaderRegex = /^(?:Host|Proxy-Connection|Connection|Keep-Alive|Transfer-Encoding|TE|Trailer|Proxy-Authorization|Proxy-Authenticate|Upgrade)$/i;
+
+ function filterHeaders(req, headers) {
+ var result = {};
+ // filter out headers that are listed in the regex above
+ Object.keys(headers).forEach(function (name) {
+ if (!dontProxyHeaderRegex.test(name)) {
+ result[name] = headers[name];
+ }
});
-
- function checkGzipAndNext(req, res, next) {
- var reqUrl = url.parse(req.url, true);
- var filePath = reqUrl.pathname.substring(1);
-
- var readStream = fs.createReadStream(filePath, { start: 0, end: 2 });
- readStream.on('error', function(err) {
- next();
- });
-
- readStream.on('data', function(chunk) {
- if (chunk.equals(gzipHeader)) {
- res.header('Content-Encoding', 'gzip');
- }
- next();
- });
+ return result;
+ }
+
+ var upstreamProxy = argv["upstream-proxy"];
+ var bypassUpstreamProxyHosts = {};
+ if (argv["bypass-upstream-proxy-hosts"]) {
+ argv["bypass-upstream-proxy-hosts"].split(",").forEach(function (host) {
+ bypassUpstreamProxyHosts[host.toLowerCase()] = true;
+ });
+ }
+
+ app.get("/proxy/*", function (req, res, next) {
+ // look for request like http://localhost:8080/proxy/http://example.com/file?query=1
+ var remoteUrl = getRemoteUrlFromParam(req);
+ if (!remoteUrl) {
+ // look for request like http://localhost:8080/proxy/?http%3A%2F%2Fexample.com%2Ffile%3Fquery%3D1
+ remoteUrl = Object.keys(req.query)[0];
+ if (remoteUrl) {
+ remoteUrl = url.parse(remoteUrl);
+ }
}
- var knownTilesetFormats = [/\.b3dm/, /\.pnts/, /\.i3dm/, /\.cmpt/, /\.glb/, /\.geom/, /\.vctr/, /tileset.*\.json$/];
- app.get(knownTilesetFormats, checkGzipAndNext);
-
- app.use(express.static(__dirname));
-
- function getRemoteUrlFromParam(req) {
- var remoteUrl = req.params[0];
- if (remoteUrl) {
- // add http:// to the URL if no protocol is present
- if (!/^https?:\/\//.test(remoteUrl)) {
- remoteUrl = 'http://' + remoteUrl;
- }
- remoteUrl = url.parse(remoteUrl);
- // copy query string
- remoteUrl.search = url.parse(req.url).search;
- }
- return remoteUrl;
+ if (!remoteUrl) {
+ return res.status(400).send("No url specified.");
}
- var dontProxyHeaderRegex = /^(?:Host|Proxy-Connection|Connection|Keep-Alive|Transfer-Encoding|TE|Trailer|Proxy-Authorization|Proxy-Authenticate|Upgrade)$/i;
-
- function filterHeaders(req, headers) {
- var result = {};
- // filter out headers that are listed in the regex above
- Object.keys(headers).forEach(function(name) {
- if (!dontProxyHeaderRegex.test(name)) {
- result[name] = headers[name];
- }
- });
- return result;
+ if (!remoteUrl.protocol) {
+ remoteUrl.protocol = "http:";
}
- var upstreamProxy = argv['upstream-proxy'];
- var bypassUpstreamProxyHosts = {};
- if (argv['bypass-upstream-proxy-hosts']) {
- argv['bypass-upstream-proxy-hosts'].split(',').forEach(function(host) {
- bypassUpstreamProxyHosts[host.toLowerCase()] = true;
- });
+ var proxy;
+ if (upstreamProxy && !(remoteUrl.host in bypassUpstreamProxyHosts)) {
+ proxy = upstreamProxy;
}
- app.get('/proxy/*', function(req, res, next) {
- // look for request like http://localhost:8080/proxy/http://example.com/file?query=1
- var remoteUrl = getRemoteUrlFromParam(req);
- if (!remoteUrl) {
- // look for request like http://localhost:8080/proxy/?http%3A%2F%2Fexample.com%2Ffile%3Fquery%3D1
- remoteUrl = Object.keys(req.query)[0];
- if (remoteUrl) {
- remoteUrl = url.parse(remoteUrl);
- }
- }
-
- if (!remoteUrl) {
- return res.status(400).send('No url specified.');
+ // encoding : null means "body" passed to the callback will be raw bytes
+
+ request.get(
+ {
+ url: url.format(remoteUrl),
+ headers: filterHeaders(req, req.headers),
+ encoding: null,
+ proxy: proxy,
+ },
+ function (error, response, body) {
+ var code = 500;
+
+ if (response) {
+ code = response.statusCode;
+ res.header(filterHeaders(req, response.headers));
}
- if (!remoteUrl.protocol) {
- remoteUrl.protocol = 'http:';
- }
-
- var proxy;
- if (upstreamProxy && !(remoteUrl.host in bypassUpstreamProxyHosts)) {
- proxy = upstreamProxy;
- }
-
- // encoding : null means "body" passed to the callback will be raw bytes
-
- request.get({
- url : url.format(remoteUrl),
- headers : filterHeaders(req, req.headers),
- encoding : null,
- proxy : proxy
- }, function(error, response, body) {
- var code = 500;
-
- if (response) {
- code = response.statusCode;
- res.header(filterHeaders(req, response.headers));
- }
-
- res.status(code).send(body);
- });
- });
-
- var server = app.listen(argv.port, argv.public ? undefined : 'localhost', function() {
- if (argv.public) {
- console.log('Cesium development server running publicly. Connect to http://localhost:%d/', server.address().port);
- } else {
- console.log('Cesium development server running locally. Connect to http://localhost:%d/', server.address().port);
- }
- });
-
- server.on('error', function (e) {
- if (e.code === 'EADDRINUSE') {
- console.log('Error: Port %d is already in use, select a different port.', argv.port);
- console.log('Example: node server.cjs --port %d', argv.port + 1);
- } else if (e.code === 'EACCES') {
- console.log('Error: This process does not have permission to listen on port %d.', argv.port);
- if (argv.port < 1024) {
- console.log('Try a port number higher than 1024.');
- }
- }
- console.log(e);
- process.exit(1);
- });
-
- server.on('close', function() {
- console.log('Cesium development server stopped.');
- });
-
- var isFirstSig = true;
- process.on('SIGINT', function() {
- if (isFirstSig) {
- console.log('Cesium development server shutting down.');
- server.close(function() {
- process.exit(0);
- });
- isFirstSig = false;
- } else {
- console.log('Cesium development server force kill.');
- process.exit(1);
- }
- });
-
+ res.status(code).send(body);
+ }
+ );
+ });
+
+ var server = app.listen(
+ argv.port,
+ argv.public ? undefined : "localhost",
+ function () {
+ if (argv.public) {
+ console.log(
+ "Cesium development server running publicly. Connect to http://localhost:%d/",
+ server.address().port
+ );
+ } else {
+ console.log(
+ "Cesium development server running locally. Connect to http://localhost:%d/",
+ server.address().port
+ );
+ }
+ }
+ );
+
+ server.on("error", function (e) {
+ if (e.code === "EADDRINUSE") {
+ console.log(
+ "Error: Port %d is already in use, select a different port.",
+ argv.port
+ );
+ console.log("Example: node server.cjs --port %d", argv.port + 1);
+ } else if (e.code === "EACCES") {
+ console.log(
+ "Error: This process does not have permission to listen on port %d.",
+ argv.port
+ );
+ if (argv.port < 1024) {
+ console.log("Try a port number higher than 1024.");
+ }
+ }
+ console.log(e);
+ process.exit(1);
+ });
+
+ server.on("close", function () {
+ console.log("Cesium development server stopped.");
+ });
+
+ var isFirstSig = true;
+ process.on("SIGINT", function () {
+ if (isFirstSig) {
+ console.log("Cesium development server shutting down.");
+ server.close(function () {
+ process.exit(0);
+ });
+ isFirstSig = false;
+ } else {
+ console.log("Cesium development server force kill.");
+ process.exit(1);
+ }
+ });
})();