diff --git a/.idea/cesium.iml b/.idea/cesium.iml
index 9d1caefa1f83..5ecdb1a3e790 100644
--- a/.idea/cesium.iml
+++ b/.idea/cesium.iml
@@ -8,6 +8,5 @@
+
+
+
+
+
+
+
+
+
diff --git a/Source/Core/BingMapsApi.js b/Source/Core/BingMapsApi.js
index bd2f03290bc0..2018caa68dc4 100644
--- a/Source/Core/BingMapsApi.js
+++ b/Source/Core/BingMapsApi.js
@@ -42,7 +42,7 @@ define([
console.log(errorString);
printedBingWarning = true;
}
- return 'AnjT_wAj_juA_MsD8NhcEAVSjCYpV-e50lUypkWm1JPxVu0XyVqabsvD3r2DQpX-';
+ return 'AhiQlDaPOwKbStA_3nJIdimUj4PRYkp0yHwcNpvxVlLNPRo5ZJWY5oX_h6B_dMbm';
}
return BingMapsApi.defaultKey;
diff --git a/Source/Core/ComponentDatatype.js b/Source/Core/ComponentDatatype.js
index 5c1a58dc54fe..9d9d94ba08d2 100644
--- a/Source/Core/ComponentDatatype.js
+++ b/Source/Core/ComponentDatatype.js
@@ -64,6 +64,28 @@ define([
*/
UNSIGNED_SHORT : WebGLConstants.UNSIGNED_SHORT,
+ /**
+ * 32-bit signed int corresponding to INT
and the type
+ * of an element in Int32Array
.
+ *
+ * @memberOf ComponentDatatype
+ *
+ * @type {Number}
+ * @constant
+ */
+ INT : WebGLConstants.INT,
+
+ /**
+ * 32-bit unsigned int corresponding to UNSIGNED_INT
and the type
+ * of an element in Uint32Array
.
+ *
+ * @memberOf ComponentDatatype
+ *
+ * @type {Number}
+ * @constant
+ */
+ UNSIGNED_INT : WebGLConstants.UNSIGNED_INT,
+
/**
* 32-bit floating-point corresponding to FLOAT
and the type
* of an element in Float32Array
.
@@ -115,6 +137,10 @@ define([
return Int16Array.BYTES_PER_ELEMENT;
case ComponentDatatype.UNSIGNED_SHORT:
return Uint16Array.BYTES_PER_ELEMENT;
+ case ComponentDatatype.INT:
+ return Int32Array.BYTES_PER_ELEMENT;
+ case ComponentDatatype.UNSIGNED_INT:
+ return Uint32Array.BYTES_PER_ELEMENT;
case ComponentDatatype.FLOAT:
return Float32Array.BYTES_PER_ELEMENT;
case ComponentDatatype.DOUBLE:
@@ -125,7 +151,7 @@ define([
};
/**
- * Gets the ComponentDatatype for the provided TypedArray instance.
+ * Gets the {@link ComponentDatatype} for the provided TypedArray instance.
*
* @param {TypedArray} array The typed array.
* @returns {ComponentDatatype} The ComponentDatatype for the provided array, or undefined if the array is not a TypedArray.
@@ -143,6 +169,12 @@ define([
if (array instanceof Uint16Array) {
return ComponentDatatype.UNSIGNED_SHORT;
}
+ if (array instanceof Int32Array) {
+ return ComponentDatatype.INT;
+ }
+ if (array instanceof Uint32Array) {
+ return ComponentDatatype.UNSIGNED_INT;
+ }
if (array instanceof Float32Array) {
return ComponentDatatype.FLOAT;
}
@@ -168,6 +200,8 @@ define([
componentDatatype === ComponentDatatype.UNSIGNED_BYTE ||
componentDatatype === ComponentDatatype.SHORT ||
componentDatatype === ComponentDatatype.UNSIGNED_SHORT ||
+ componentDatatype === ComponentDatatype.INT ||
+ componentDatatype === ComponentDatatype.UNSIGNED_INT ||
componentDatatype === ComponentDatatype.FLOAT ||
componentDatatype === ComponentDatatype.DOUBLE);
};
@@ -177,7 +211,7 @@ define([
*
* @param {ComponentDatatype} componentDatatype The component data type.
* @param {Number|Array} valuesOrLength The length of the array to create or an array.
- * @returns {Int8Array|Uint8Array|Int16Array|Uint16Array|Float32Array|Float64Array} A typed array.
+ * @returns {Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} A typed array.
*
* @exception {DeveloperError} componentDatatype is not a valid value.
*
@@ -204,6 +238,10 @@ define([
return new Int16Array(valuesOrLength);
case ComponentDatatype.UNSIGNED_SHORT:
return new Uint16Array(valuesOrLength);
+ case ComponentDatatype.INT:
+ return new Int32Array(valuesOrLength);
+ case ComponentDatatype.UNSIGNED_INT:
+ return new Uint32Array(valuesOrLength);
case ComponentDatatype.FLOAT:
return new Float32Array(valuesOrLength);
case ComponentDatatype.DOUBLE:
@@ -220,7 +258,7 @@ define([
* @param {ArrayBuffer} buffer The buffer storage to use for the view.
* @param {Number} [byteOffset] The offset, in bytes, to the first element in the view.
* @param {Number} [length] The number of elements in the view.
- * @returns {Int8Array|Uint8Array|Int16Array|Uint16Array|Float32Array|Float64Array} A typed array view of the buffer.
+ * @returns {Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array|Float64Array} A typed array view of the buffer.
*
* @exception {DeveloperError} componentDatatype is not a valid value.
*/
@@ -246,6 +284,10 @@ define([
return new Int16Array(buffer, byteOffset, length);
case ComponentDatatype.UNSIGNED_SHORT:
return new Uint16Array(buffer, byteOffset, length);
+ case ComponentDatatype.INT:
+ return new Int32Array(buffer, byteOffset, length);
+ case ComponentDatatype.UNSIGNED_INT:
+ return new Uint32Array(buffer, byteOffset, length);
case ComponentDatatype.FLOAT:
return new Float32Array(buffer, byteOffset, length);
case ComponentDatatype.DOUBLE:
@@ -255,5 +297,36 @@ define([
}
};
+ /**
+ * Get the ComponentDatatype from its name.
+ *
+ * @param {String} name The name of the ComponentDatatype.
+ * @returns {ComponentDatatype} The ComponentDatatype.
+ *
+ * @exception {DeveloperError} name is not a valid value.
+ */
+ ComponentDatatype.fromName = function(name) {
+ switch (name) {
+ case 'BYTE':
+ return ComponentDatatype.BYTE;
+ case 'UNSIGNED_BYTE':
+ return ComponentDatatype.UNSIGNED_BYTE;
+ case 'SHORT':
+ return ComponentDatatype.SHORT;
+ case 'UNSIGNED_SHORT':
+ return ComponentDatatype.UNSIGNED_SHORT;
+ case 'INT':
+ return ComponentDatatype.INT;
+ case 'UNSIGNED_INT':
+ return ComponentDatatype.UNSIGNED_INT;
+ case 'FLOAT':
+ return ComponentDatatype.FLOAT;
+ case 'DOUBLE':
+ return ComponentDatatype.DOUBLE;
+ default:
+ throw new DeveloperError('name is not a valid value.');
+ }
+ };
+
return freezeObject(ComponentDatatype);
});
diff --git a/Source/Core/RectangleGeometryLibrary.js b/Source/Core/RectangleGeometryLibrary.js
index 1dd8a01ac4d0..34ac3cbbb40a 100644
--- a/Source/Core/RectangleGeometryLibrary.js
+++ b/Source/Core/RectangleGeometryLibrary.js
@@ -112,7 +112,7 @@ define([
var granYSin = 0.0;
var granXSin = 0.0;
- if (defined(rotation)) { // rotation doesn't work when center is on/near IDL
+ if (defined(rotation) && rotation !== 0) { // rotation doesn't work when center is on/near IDL
var cosRotation = Math.cos(rotation);
granYCos *= cosRotation;
granXCos *= cosRotation;
diff --git a/Source/Core/loadWithXhr.js b/Source/Core/loadWithXhr.js
index 415093c27601..fe2d42c85846 100644
--- a/Source/Core/loadWithXhr.js
+++ b/Source/Core/loadWithXhr.js
@@ -43,7 +43,7 @@ define([
* }).otherwise(function(error) {
* // an error occurred
* });
- *
+ *
* @see loadArrayBuffer
* @see loadBlob
* @see loadJson
@@ -102,23 +102,23 @@ define([
var data = dataUriRegexResult[3];
switch (responseType) {
- case '':
- case 'text':
- return decodeDataUriText(isBase64, data);
- case 'arraybuffer':
- return decodeDataUriArrayBuffer(isBase64, data);
- case 'blob':
- var buffer = decodeDataUriArrayBuffer(isBase64, data);
- return new Blob([buffer], {
- type : mimeType
- });
- case 'document':
- var parser = new DOMParser();
- return parser.parseFromString(decodeDataUriText(isBase64, data), mimeType);
- case 'json':
- return JSON.parse(decodeDataUriText(isBase64, data));
- default:
- throw new DeveloperError('Unhandled responseType: ' + responseType);
+ case '':
+ case 'text':
+ return decodeDataUriText(isBase64, data);
+ case 'arraybuffer':
+ return decodeDataUriArrayBuffer(isBase64, data);
+ case 'blob':
+ var buffer = decodeDataUriArrayBuffer(isBase64, data);
+ return new Blob([buffer], {
+ type : mimeType
+ });
+ case 'document':
+ var parser = new DOMParser();
+ return parser.parseFromString(decodeDataUriText(isBase64, data), mimeType);
+ case 'json':
+ return JSON.parse(decodeDataUriText(isBase64, data));
+ default:
+ throw new DeveloperError('Unhandled responseType: ' + responseType);
}
}
@@ -139,7 +139,7 @@ define([
xhr.open(method, url, true);
if (defined(headers)) {
- for ( var key in headers) {
+ for (var key in headers) {
if (headers.hasOwnProperty(key)) {
xhr.setRequestHeader(key, headers[key]);
}
@@ -151,21 +151,31 @@ define([
}
xhr.onload = function() {
- if (xhr.status >= 200 && xhr.status < 300) {
- if (defined(xhr.response)) {
- deferred.resolve(xhr.response);
- } else {
- // busted old browsers.
- if (defined(xhr.responseXML) && xhr.responseXML.hasChildNodes()) {
- deferred.resolve(xhr.responseXML);
- } else if (defined(xhr.responseText)) {
- deferred.resolve(xhr.responseText);
- } else {
- deferred.reject(new RuntimeError('unknown XMLHttpRequest response type.'));
- }
+ if (xhr.status < 200 || xhr.status >= 300) {
+ deferred.reject(new RequestErrorEvent(xhr.status, xhr.response, xhr.getAllResponseHeaders()));
+ return;
+ }
+
+ var response = xhr.response;
+ var browserResponseType = xhr.responseType;
+
+ //All modern browsers will go into either the first if block or last else block.
+ //Other code paths support older browsers that either do not support the supplied responseType
+ //or do not support the xhr.response property.
+ if (defined(response) && (!defined(responseType) || (browserResponseType === responseType))) {
+ deferred.resolve(response);
+ } else if ((responseType === 'json') && typeof response === 'string') {
+ try {
+ deferred.resolve(JSON.parse(response));
+ } catch (e) {
+ deferred.reject(e);
}
+ } else if ((browserResponseType === '' || browserResponseType === 'document') && defined(xhr.responseXML) && xhr.responseXML.hasChildNodes()) {
+ deferred.resolve(xhr.responseXML);
+ } else if ((browserResponseType === '' || browserResponseType === 'text') && defined(xhr.responseText)) {
+ deferred.resolve(xhr.responseText);
} else {
- deferred.reject(new RequestErrorEvent(xhr.status, xhr.response, xhr.getAllResponseHeaders()));
+ deferred.reject(new RuntimeError('Invalid XMLHttpRequest response type.'));
}
};
diff --git a/Source/DataSources/BoxGeometryUpdater.js b/Source/DataSources/BoxGeometryUpdater.js
index 40bc2b9f4ce7..63d3a9e8e5a1 100644
--- a/Source/DataSources/BoxGeometryUpdater.js
+++ b/Source/DataSources/BoxGeometryUpdater.js
@@ -16,6 +16,7 @@ define([
'../Scene/MaterialAppearance',
'../Scene/PerInstanceColorAppearance',
'../Scene/Primitive',
+ '../Scene/ShadowMode',
'./ColorMaterialProperty',
'./ConstantProperty',
'./dynamicGeometryGetBoundingSphere',
@@ -38,6 +39,7 @@ define([
MaterialAppearance,
PerInstanceColorAppearance,
Primitive,
+ ShadowMode,
ColorMaterialProperty,
ConstantProperty,
dynamicGeometryGetBoundingSphere,
@@ -50,6 +52,7 @@ define([
var defaultFill = new ConstantProperty(true);
var defaultOutline = new ConstantProperty(false);
var defaultOutlineColor = new ConstantProperty(Color.BLACK);
+ var defaultShadows = new ConstantProperty(ShadowMode.DISABLED);
var scratchColor = new Color();
function GeometryOptions(entity) {
@@ -90,6 +93,7 @@ define([
this._showOutlineProperty = undefined;
this._outlineColorProperty = undefined;
this._outlineWidth = 1.0;
+ this._shadowsProperty = undefined;
this._options = new GeometryOptions(entity);
this._onEntityPropertyChanged(entity, 'box', entity.box, undefined);
}
@@ -217,6 +221,19 @@ define([
return this._outlineWidth;
}
},
+ /**
+ * Gets the property specifying whether the geometry
+ * casts or receives shadows from each light source.
+ * @memberof BoxGeometryUpdater.prototype
+ *
+ * @type {Property}
+ * @readonly
+ */
+ shadowsProperty : {
+ get : function() {
+ return this._shadowsProperty;
+ }
+ },
/**
* Gets a value indicating if the geometry is time-varying.
* If true, all visualization is delegated to the {@link DynamicGeometryUpdater}
@@ -436,6 +453,7 @@ define([
this._showProperty = defaultValue(show, defaultShow);
this._showOutlineProperty = defaultValue(box.outline, defaultOutline);
this._outlineColorProperty = outlineEnabled ? defaultValue(box.outlineColor, defaultOutlineColor) : undefined;
+ this._shadowsProperty = defaultValue(box.shadows, defaultShadows);
var outlineWidth = box.outlineWidth;
@@ -521,6 +539,8 @@ define([
options.dimensions = dimensions;
+ var shadows = this._geometryUpdater.shadowsProperty.getValue(time);
+
if (Property.getValueOrDefault(box.fill, time, true)) {
var material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material);
this._material = material;
@@ -539,7 +559,8 @@ define([
modelMatrix : modelMatrix
}),
appearance : appearance,
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
}
@@ -566,7 +587,8 @@ define([
lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth)
}
}),
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
}
};
diff --git a/Source/DataSources/BoxGraphics.js b/Source/DataSources/BoxGraphics.js
index c2a7d11ed423..a9e4be26f6eb 100644
--- a/Source/DataSources/BoxGraphics.js
+++ b/Source/DataSources/BoxGraphics.js
@@ -31,6 +31,7 @@ define([
* @param {Property} [options.outline=false] A boolean Property specifying whether the box 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 box casts or receives shadows from each light source.
*
* @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Box.html|Cesium Sandcastle Box Demo}
*/
@@ -49,6 +50,8 @@ define([
this._outlineColorSubscription = undefined;
this._outlineWidth = undefined;
this._outlineWidthSubscription = undefined;
+ this._shadows = undefined;
+ this._shadowsSubscription = undefined;
this._definitionChanged = new Event();
this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT));
@@ -120,7 +123,16 @@ define([
* @type {Property}
* @default 1.0
*/
- outlineWidth : createPropertyDescriptor('outlineWidth')
+ outlineWidth : createPropertyDescriptor('outlineWidth'),
+
+ /**
+ * Get or sets the enum Property specifying whether the box
+ * casts or receives shadows from each light source.
+ * @memberof BoxGraphics.prototype
+ * @type {Property}
+ * @default ShadowMode.DISABLED
+ */
+ shadows : createPropertyDescriptor('shadows')
});
/**
@@ -140,6 +152,7 @@ define([
result.outline = this.outline;
result.outlineColor = this.outlineColor;
result.outlineWidth = this.outlineWidth;
+ result.shadows = this.shadows;
return result;
};
@@ -163,6 +176,7 @@ define([
this.outline = defaultValue(this.outline, source.outline);
this.outlineColor = defaultValue(this.outlineColor, source.outlineColor);
this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth);
+ this.shadows = defaultValue(this.shadows, source.shadows);
};
return BoxGraphics;
diff --git a/Source/DataSources/CorridorGeometryUpdater.js b/Source/DataSources/CorridorGeometryUpdater.js
index f1b071a14ba8..29f9374f73e7 100644
--- a/Source/DataSources/CorridorGeometryUpdater.js
+++ b/Source/DataSources/CorridorGeometryUpdater.js
@@ -18,6 +18,7 @@ define([
'../Scene/MaterialAppearance',
'../Scene/PerInstanceColorAppearance',
'../Scene/Primitive',
+ '../Scene/ShadowMode',
'./ColorMaterialProperty',
'./ConstantProperty',
'./dynamicGeometryGetBoundingSphere',
@@ -42,6 +43,7 @@ define([
MaterialAppearance,
PerInstanceColorAppearance,
Primitive,
+ ShadowMode,
ColorMaterialProperty,
ConstantProperty,
dynamicGeometryGetBoundingSphere,
@@ -54,6 +56,7 @@ define([
var defaultFill = new ConstantProperty(true);
var defaultOutline = new ConstantProperty(false);
var defaultOutlineColor = new ConstantProperty(Color.BLACK);
+ var defaultShadows = new ConstantProperty(ShadowMode.DISABLED);
var scratchColor = new Color();
function GeometryOptions(entity) {
@@ -100,6 +103,7 @@ define([
this._showOutlineProperty = undefined;
this._outlineColorProperty = undefined;
this._outlineWidth = 1.0;
+ this._shadowsProperty = undefined;
this._onTerrain = false;
this._options = new GeometryOptions(entity);
@@ -229,6 +233,19 @@ define([
return this._outlineWidth;
}
},
+ /**
+ * Gets the property specifying whether the geometry
+ * casts or receives shadows from each light source.
+ * @memberof CorridorGeometryUpdater.prototype
+ *
+ * @type {Property}
+ * @readonly
+ */
+ shadowsProperty : {
+ get : function() {
+ return this._shadowsProperty;
+ }
+ },
/**
* Gets a value indicating if the geometry is time-varying.
* If true, all visualization is delegated to the {@link DynamicGeometryUpdater}
@@ -460,6 +477,7 @@ define([
this._showProperty = defaultValue(show, defaultShow);
this._showOutlineProperty = defaultValue(corridor.outline, defaultOutline);
this._outlineColorProperty = outlineEnabled ? defaultValue(corridor.outlineColor, defaultOutlineColor) : undefined;
+ this._shadowsProperty = defaultValue(corridor.shadows, defaultShadows);
var height = corridor.height;
var extrudedHeight = corridor.extrudedHeight;
@@ -580,6 +598,8 @@ define([
options.granularity = Property.getValueOrUndefined(corridor.granularity, time);
options.cornerType = Property.getValueOrUndefined(corridor.cornerType, time);
+ var shadows = this._geometryUpdater.shadowsProperty.getValue(time);
+
if (!defined(corridor.fill) || corridor.fill.getValue(time)) {
var fillMaterialProperty = geometryUpdater.fillMaterialProperty;
var material = MaterialProperty.getValue(time, fillMaterialProperty, this._material);
@@ -592,14 +612,15 @@ define([
}
this._primitive = groundPrimitives.add(new GroundPrimitive({
- geometryInstance : new GeometryInstance({
+ geometryInstances : new GeometryInstance({
id : entity,
geometry : new CorridorGeometry(options),
attributes: {
color: ColorGeometryInstanceAttribute.fromColor(currentColor)
}
}),
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
} else {
var appearance = new MaterialAppearance({
@@ -615,7 +636,8 @@ define([
geometry : new CorridorGeometry(options)
}),
appearance : appearance,
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
}
}
@@ -642,7 +664,8 @@ define([
lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth)
}
}),
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
}
};
diff --git a/Source/DataSources/CorridorGraphics.js b/Source/DataSources/CorridorGraphics.js
index e15ab9b6347a..98161c48e343 100644
--- a/Source/DataSources/CorridorGraphics.js
+++ b/Source/DataSources/CorridorGraphics.js
@@ -38,6 +38,7 @@ define([
* @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.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the distance between each latitude and longitude.
+ * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the corridor casts or receives shadows from each light source.
*
* @see Entity
* @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Corridor.html|Cesium Sandcastle Corridor Demo}
@@ -67,6 +68,8 @@ define([
this._outlineColorSubscription = undefined;
this._outlineWidth = undefined;
this._outlineWidthSubscription = undefined;
+ this._shadows = undefined;
+ this._shadowsSubscription = undefined;
this._definitionChanged = new Event();
this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT));
@@ -178,7 +181,16 @@ define([
* @type {Property}
* @default CornerType.ROUNDED
*/
- cornerType : createPropertyDescriptor('cornerType')
+ cornerType : createPropertyDescriptor('cornerType'),
+
+ /**
+ * Get or sets the enum Property specifying whether the corridor
+ * casts or receives shadows from each light source.
+ * @memberof CorridorGraphics.prototype
+ * @type {Property}
+ * @default ShadowMode.DISABLED
+ */
+ shadows : createPropertyDescriptor('shadows')
});
/**
@@ -203,6 +215,7 @@ define([
result.outlineColor = this.outlineColor;
result.outlineWidth = this.outlineWidth;
result.cornerType = this.cornerType;
+ result.shadows = this.shadows;
return result;
};
@@ -231,6 +244,7 @@ define([
this.outlineColor = defaultValue(this.outlineColor, source.outlineColor);
this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth);
this.cornerType = defaultValue(this.cornerType, source.cornerType);
+ this.shadows = defaultValue(this.shadows, source.shadows);
};
return CorridorGraphics;
diff --git a/Source/DataSources/CylinderGeometryUpdater.js b/Source/DataSources/CylinderGeometryUpdater.js
index bd5f7ba199f4..86881bb9eec7 100644
--- a/Source/DataSources/CylinderGeometryUpdater.js
+++ b/Source/DataSources/CylinderGeometryUpdater.js
@@ -17,6 +17,7 @@ define([
'../Scene/MaterialAppearance',
'../Scene/PerInstanceColorAppearance',
'../Scene/Primitive',
+ '../Scene/ShadowMode',
'./ColorMaterialProperty',
'./ConstantProperty',
'./dynamicGeometryGetBoundingSphere',
@@ -40,6 +41,7 @@ define([
MaterialAppearance,
PerInstanceColorAppearance,
Primitive,
+ ShadowMode,
ColorMaterialProperty,
ConstantProperty,
dynamicGeometryGetBoundingSphere,
@@ -52,6 +54,7 @@ define([
var defaultFill = new ConstantProperty(true);
var defaultOutline = new ConstantProperty(false);
var defaultOutlineColor = new ConstantProperty(Color.BLACK);
+ var defaultShadows = new ConstantProperty(ShadowMode.DISABLED);
var scratchColor = new Color();
@@ -97,6 +100,7 @@ define([
this._showOutlineProperty = undefined;
this._outlineColorProperty = undefined;
this._outlineWidth = 1.0;
+ this._shadowsProperty = undefined;
this._options = new GeometryOptions(entity);
this._onEntityPropertyChanged(entity, 'cylinder', entity.cylinder, undefined);
}
@@ -224,6 +228,19 @@ define([
return this._outlineWidth;
}
},
+ /**
+ * Gets the property specifying whether the geometry
+ * casts or receives shadows from each light source.
+ * @memberof CylinderGeometryUpdater.prototype
+ *
+ * @type {Property}
+ * @readonly
+ */
+ shadowsProperty : {
+ get : function() {
+ return this._shadowsProperty;
+ }
+ },
/**
* Gets a value indicating if the geometry is time-varying.
* If true, all visualization is delegated to the {@link DynamicGeometryUpdater}
@@ -446,6 +463,7 @@ define([
this._showProperty = defaultValue(show, defaultShow);
this._showOutlineProperty = defaultValue(cylinder.outline, defaultOutline);
this._outlineColorProperty = outlineEnabled ? defaultValue(cylinder.outlineColor, defaultOutlineColor) : undefined;
+ this._shadowsProperty = defaultValue(cylinder.shadows, defaultShadows);
var slices = cylinder.slices;
var outlineWidth = cylinder.outlineWidth;
@@ -547,6 +565,8 @@ define([
options.slices = Property.getValueOrUndefined(cylinder.slices, time);
options.numberOfVerticalLines = Property.getValueOrUndefined(cylinder.numberOfVerticalLines, time);
+ var shadows = this._geometryUpdater.shadowsProperty.getValue(time);
+
if (Property.getValueOrDefault(cylinder.fill, time, true)) {
var material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material);
this._material = material;
@@ -565,7 +585,8 @@ define([
modelMatrix : modelMatrix
}),
appearance : appearance,
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
}
@@ -592,7 +613,8 @@ define([
lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth)
}
}),
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
}
};
diff --git a/Source/DataSources/CylinderGraphics.js b/Source/DataSources/CylinderGraphics.js
index 0640971e8593..d2f4196519d9 100644
--- a/Source/DataSources/CylinderGraphics.js
+++ b/Source/DataSources/CylinderGraphics.js
@@ -36,6 +36,7 @@ define([
* @param {Property} [options.outlineWidth=1.0] A numeric Property specifying the width of the outline.
* @param {Property} [options.numberOfVerticalLines=16] A numeric Property specifying the number of vertical lines to draw along the perimeter for the outline.
* @param {Property} [options.slices=128] The number of edges around the perimeter of the cylinder.
+ * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the cylinder casts or receives shadows from each light source.
*/
function CylinderGraphics(options) {
this._length = undefined;
@@ -60,6 +61,8 @@ define([
this._outlineColorSubscription = undefined;
this._outlineWidth = undefined;
this._outlineWidthSubscription = undefined;
+ this._shadows = undefined;
+ this._shadowsSubscription = undefined;
this._definitionChanged = new Event();
this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT));
@@ -162,7 +165,16 @@ define([
* @type {Property}
* @default 1.0
*/
- outlineWidth : createPropertyDescriptor('outlineWidth')
+ outlineWidth : createPropertyDescriptor('outlineWidth'),
+
+ /**
+ * Get or sets the enum Property specifying whether the cylinder
+ * casts or receives shadows from each light source.
+ * @memberof CylinderGraphics.prototype
+ * @type {Property}
+ * @default ShadowMode.DISABLED
+ */
+ shadows : createPropertyDescriptor('shadows')
});
/**
@@ -186,6 +198,7 @@ define([
result.outline = this.outline;
result.outlineColor = this.outlineColor;
result.outlineWidth = this.outlineWidth;
+ result.shadows = this.shadows;
return result;
};
@@ -213,6 +226,7 @@ define([
this.outline = defaultValue(this.outline, source.outline);
this.outlineColor = defaultValue(this.outlineColor, source.outlineColor);
this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth);
+ this.shadows = defaultValue(this.shadows, source.shadows);
};
return CylinderGraphics;
diff --git a/Source/DataSources/CzmlDataSource.js b/Source/DataSources/CzmlDataSource.js
index 00c9b989ce03..706049c9fc25 100644
--- a/Source/DataSources/CzmlDataSource.js
+++ b/Source/DataSources/CzmlDataSource.js
@@ -37,6 +37,7 @@ define([
'../Scene/HeightReference',
'../Scene/HorizontalOrigin',
'../Scene/LabelStyle',
+ '../Scene/ShadowMode',
'../Scene/VerticalOrigin',
'../ThirdParty/Uri',
'../ThirdParty/when',
@@ -119,6 +120,7 @@ define([
HeightReference,
HorizontalOrigin,
LabelStyle,
+ ShadowMode,
VerticalOrigin,
Uri,
when,
@@ -446,6 +448,8 @@ define([
return unwrapQuaternionInterval(czmlInterval);
case Rotation:
return defaultValue(czmlInterval.number, czmlInterval);
+ case ShadowMode:
+ return ShadowMode[defaultValue(czmlInterval.shadows, czmlInterval)];
case String:
return defaultValue(czmlInterval.string, czmlInterval);
case StripeOrientation:
@@ -1166,6 +1170,7 @@ define([
processPacketData(Boolean, box, 'outline', boxData.outline, interval, sourceUri, entityCollection);
processPacketData(Color, box, 'outlineColor', boxData.outlineColor, interval, sourceUri, entityCollection);
processPacketData(Number, box, 'outlineWidth', boxData.outlineWidth, interval, sourceUri, entityCollection);
+ processPacketData(ShadowMode, box, 'shadows', boxData.shadows, interval, sourceUri, entityCollection);
}
function processCorridor(entity, packet, entityCollection, sourceUri) {
@@ -1198,6 +1203,7 @@ define([
processPacketData(Boolean, corridor, 'outline', corridorData.outline, interval, sourceUri, entityCollection);
processPacketData(Color, corridor, 'outlineColor', corridorData.outlineColor, interval, sourceUri, entityCollection);
processPacketData(Number, corridor, 'outlineWidth', corridorData.outlineWidth, interval, sourceUri, entityCollection);
+ processPacketData(ShadowMode, corridor, 'shadows', corridorData.shadows, interval, sourceUri, entityCollection);
}
function processCylinder(entity, packet, entityCollection, sourceUri) {
@@ -1229,6 +1235,7 @@ define([
processPacketData(Number, cylinder, 'outlineWidth', cylinderData.outlineWidth, interval, sourceUri, entityCollection);
processPacketData(Number, cylinder, 'numberOfVerticalLines', cylinderData.numberOfVerticalLines, interval, sourceUri, entityCollection);
processPacketData(Number, cylinder, 'slices', cylinderData.slices, interval, sourceUri, entityCollection);
+ processPacketData(ShadowMode, cylinder, 'shadows', cylinderData.shadows, interval, sourceUri, entityCollection);
}
function processDocument(packet, dataSource) {
@@ -1308,6 +1315,7 @@ define([
processPacketData(Color, ellipse, 'outlineColor', ellipseData.outlineColor, interval, sourceUri, entityCollection);
processPacketData(Number, ellipse, 'outlineWidth', ellipseData.outlineWidth, interval, sourceUri, entityCollection);
processPacketData(Number, ellipse, 'numberOfVerticalLines', ellipseData.numberOfVerticalLines, interval, sourceUri, entityCollection);
+ processPacketData(ShadowMode, ellipse, 'shadows', ellipseData.shadows, interval, sourceUri, entityCollection);
}
function processEllipsoid(entity, packet, entityCollection, sourceUri) {
@@ -1338,6 +1346,7 @@ define([
processPacketData(Number, ellipsoid, 'stackPartitions', ellipsoidData.stackPartitions, interval, sourceUri, entityCollection);
processPacketData(Number, ellipsoid, 'slicePartitions', ellipsoidData.slicePartitions, interval, sourceUri, entityCollection);
processPacketData(Number, ellipsoid, 'subdivisions', ellipsoidData.subdivisions, interval, sourceUri, entityCollection);
+ processPacketData(ShadowMode, ellipsoid, 'shadows', ellipsoidData.shadows, interval, sourceUri, entityCollection);
}
function processLabel(entity, packet, entityCollection, sourceUri) {
@@ -1399,9 +1408,10 @@ define([
processPacketData(Number, model, 'minimumPixelSize', modelData.minimumPixelSize, interval, sourceUri, entityCollection);
processPacketData(Number, model, 'maximumScale', modelData.maximumScale, interval, sourceUri, entityCollection);
processPacketData(Boolean, model, 'incrementallyLoadTextures', modelData.incrementallyLoadTextures, interval, sourceUri, entityCollection);
+ processPacketData(Boolean, model, 'runAnimations', modelData.runAnimations, interval, sourceUri, entityCollection);
processPacketData(Boolean, model, 'castShadows', modelData.castShadows, interval, sourceUri, entityCollection);
processPacketData(Boolean, model, 'receiveShadows', modelData.receiveShadows, interval, sourceUri, entityCollection);
- processPacketData(Boolean, model, 'runAnimations', modelData.runAnimations, interval, sourceUri, entityCollection);
+ processPacketData(ShadowMode, model, 'shadows', modelData.shadows, interval, sourceUri, entityCollection);
processPacketData(HeightReference, model, 'heightReference', modelData.heightReference, interval, sourceUri, entityCollection);
var nodeTransformationsData = modelData.nodeTransformations;
@@ -1549,6 +1559,7 @@ define([
processPacketData(Boolean, polygon, 'perPositionHeight', polygonData.perPositionHeight, interval, sourceUri, entityCollection);
processPacketData(Boolean, polygon, 'closeTop', polygonData.closeTop, interval, sourceUri, entityCollection);
processPacketData(Boolean, polygon, 'closeBottom', polygonData.closeBottom, interval, sourceUri, entityCollection);
+ processPacketData(ShadowMode, polygon, 'shadows', polygonData.shadows, interval, sourceUri, entityCollection);
}
function processPolyline(entity, packet, entityCollection, sourceUri) {
@@ -1575,6 +1586,7 @@ define([
processPacketData(Number, polyline, 'granularity', polylineData.granularity, interval, sourceUri, entityCollection);
processMaterialPacketData(polyline, 'material', polylineData.material, interval, sourceUri, entityCollection);
processPacketData(Boolean, polyline, 'followSurface', polylineData.followSurface, interval, sourceUri, entityCollection);
+ processPacketData(ShadowMode, polyline, 'shadows', polylineData.shadows, interval, sourceUri, entityCollection);
}
function processRectangle(entity, packet, entityCollection, sourceUri) {
@@ -1609,6 +1621,7 @@ define([
processPacketData(Number, rectangle, 'outlineWidth', rectangleData.outlineWidth, interval, sourceUri, entityCollection);
processPacketData(Boolean, rectangle, 'closeTop', rectangleData.closeTop, interval, sourceUri, entityCollection);
processPacketData(Boolean, rectangle, 'closeBottom', rectangleData.closeBottom, interval, sourceUri, entityCollection);
+ processPacketData(ShadowMode, rectangle, 'shadows', rectangleData.shadows, interval, sourceUri, entityCollection);
}
function processWall(entity, packet, entityCollection, sourceUri) {
@@ -1639,6 +1652,7 @@ define([
processPacketData(Boolean, wall, 'outline', wallData.outline, interval, sourceUri, entityCollection);
processPacketData(Color, wall, 'outlineColor', wallData.outlineColor, interval, sourceUri, entityCollection);
processPacketData(Number, wall, 'outlineWidth', wallData.outlineWidth, interval, sourceUri, entityCollection);
+ processPacketData(ShadowMode, wall, 'shadows', wallData.shadows, interval, sourceUri, entityCollection);
}
function processCzmlPacket(packet, entityCollection, updaterFunctions, sourceUri, dataSource) {
diff --git a/Source/DataSources/DataSourceDisplay.js b/Source/DataSources/DataSourceDisplay.js
index c7f48feb1255..c5ae516e6ac1 100644
--- a/Source/DataSources/DataSourceDisplay.js
+++ b/Source/DataSources/DataSourceDisplay.js
@@ -7,6 +7,7 @@ define([
'../Core/destroyObject',
'../Core/DeveloperError',
'../Core/EventHelper',
+ '../Scene/GroundPrimitive',
'./BillboardVisualizer',
'./BoundingSphereState',
'./BoxGeometryUpdater',
@@ -33,6 +34,7 @@ define([
destroyObject,
DeveloperError,
EventHelper,
+ GroundPrimitive,
BillboardVisualizer,
BoundingSphereState,
BoxGeometryUpdater,
@@ -77,6 +79,8 @@ define([
throw new DeveloperError('dataSourceCollection is required.');
}
//>>includeEnd('debug');
+
+ GroundPrimitive.initializeTerrainHeights();
var scene = options.scene;
var dataSourceCollection = options.dataSourceCollection;
@@ -231,6 +235,11 @@ define([
}
//>>includeEnd('debug');
+ if (!GroundPrimitive._initialized) {
+ this._ready = false;
+ return false;
+ }
+
var result = true;
var i;
@@ -292,6 +301,10 @@ define([
}
//>>includeEnd('debug');
+ if (!this._ready) {
+ return BoundingSphereState.PENDING;
+ }
+
var i;
var length;
var dataSource = this._defaultDataSource;
diff --git a/Source/DataSources/EllipseGeometryUpdater.js b/Source/DataSources/EllipseGeometryUpdater.js
index 7f204a09a7a8..a9e13c630672 100644
--- a/Source/DataSources/EllipseGeometryUpdater.js
+++ b/Source/DataSources/EllipseGeometryUpdater.js
@@ -18,6 +18,7 @@ define([
'../Scene/MaterialAppearance',
'../Scene/PerInstanceColorAppearance',
'../Scene/Primitive',
+ '../Scene/ShadowMode',
'./ColorMaterialProperty',
'./ConstantProperty',
'./dynamicGeometryGetBoundingSphere',
@@ -42,6 +43,7 @@ define([
MaterialAppearance,
PerInstanceColorAppearance,
Primitive,
+ ShadowMode,
ColorMaterialProperty,
ConstantProperty,
dynamicGeometryGetBoundingSphere,
@@ -54,6 +56,7 @@ define([
var defaultFill = new ConstantProperty(true);
var defaultOutline = new ConstantProperty(false);
var defaultOutlineColor = new ConstantProperty(Color.BLACK);
+ var defaultShadows = new ConstantProperty(ShadowMode.DISABLED);
var scratchColor = new Color();
function GeometryOptions(entity) {
@@ -103,6 +106,7 @@ define([
this._showOutlineProperty = undefined;
this._outlineColorProperty = undefined;
this._outlineWidth = 1.0;
+ this._shadowsProperty = undefined;
this._onTerrain = false;
this._options = new GeometryOptions(entity);
@@ -232,6 +236,19 @@ define([
return this._outlineWidth;
}
},
+ /**
+ * Gets the property specifying whether the geometry
+ * casts or receives shadows from each light source.
+ * @memberof EllipseGeometryUpdater.prototype
+ *
+ * @type {Property}
+ * @readonly
+ */
+ shadowsProperty : {
+ get : function() {
+ return this._shadowsProperty;
+ }
+ },
/**
* Gets a value indicating if the geometry is time-varying.
* If true, all visualization is delegated to the {@link DynamicGeometryUpdater}
@@ -465,6 +482,7 @@ define([
this._showProperty = defaultValue(show, defaultShow);
this._showOutlineProperty = defaultValue(ellipse.outline, defaultOutline);
this._outlineColorProperty = outlineEnabled ? defaultValue(ellipse.outlineColor, defaultOutlineColor) : undefined;
+ this._shadowsProperty = defaultValue(ellipse.shadows, defaultShadows);
var rotation = ellipse.rotation;
var height = ellipse.height;
@@ -597,6 +615,8 @@ define([
options.stRotation = Property.getValueOrUndefined(ellipse.stRotation, time);
options.numberOfVerticalLines = Property.getValueOrUndefined(ellipse.numberOfVerticalLines, time);
+ var shadows = this._geometryUpdater.shadowsProperty.getValue(time);
+
if (Property.getValueOrDefault(ellipse.fill, time, true)) {
var fillMaterialProperty = geometryUpdater.fillMaterialProperty;
var material = MaterialProperty.getValue(time, fillMaterialProperty, this._material);
@@ -609,14 +629,15 @@ define([
}
this._primitive = groundPrimitives.add(new GroundPrimitive({
- geometryInstance : new GeometryInstance({
+ geometryInstances : new GeometryInstance({
id : entity,
geometry : new EllipseGeometry(options),
attributes: {
color: ColorGeometryInstanceAttribute.fromColor(currentColor)
}
}),
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
} else {
var appearance = new MaterialAppearance({
@@ -632,7 +653,8 @@ define([
geometry : new EllipseGeometry(options)
}),
appearance : appearance,
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
}
}
@@ -659,7 +681,8 @@ define([
lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth)
}
}),
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
}
};
diff --git a/Source/DataSources/EllipseGraphics.js b/Source/DataSources/EllipseGraphics.js
index 10a365b2a1d4..39e64d17671d 100644
--- a/Source/DataSources/EllipseGraphics.js
+++ b/Source/DataSources/EllipseGraphics.js
@@ -41,6 +41,7 @@ define([
* @param {Property} [options.rotation=0.0] A numeric property specifying the rotation of the ellipse counter-clockwise from north.
* @param {Property} [options.stRotation=0.0] A numeric property specifying the rotation of the ellipse 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 ellipse.
+ * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the ellipse casts or receives shadows from each light source.
*
* @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Circles and Ellipses.html|Cesium Sandcastle Circles and Ellipses Demo}
*/
@@ -73,6 +74,8 @@ define([
this._outlineWidthSubscription = undefined;
this._numberOfVerticalLines = undefined;
this._numberOfVerticalLinesSubscription = undefined;
+ this._shadows = undefined;
+ this._shadowsSubscription = undefined;
this._definitionChanged = new Event();
this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT));
@@ -200,7 +203,16 @@ define([
* @type {Property}
* @default 16
*/
- numberOfVerticalLines : createPropertyDescriptor('numberOfVerticalLines')
+ numberOfVerticalLines : createPropertyDescriptor('numberOfVerticalLines'),
+
+ /**
+ * Get or sets the enum Property specifying whether the ellipse
+ * casts or receives shadows from each light source.
+ * @memberof EllipseGraphics.prototype
+ * @type {Property}
+ * @default ShadowMode.DISABLED
+ */
+ shadows : createPropertyDescriptor('shadows')
});
/**
@@ -227,6 +239,7 @@ define([
result.outlineColor = this.outlineColor;
result.outlineWidth = this.outlineWidth;
result.numberOfVerticalLines = this.numberOfVerticalLines;
+ result.shadows = this.shadows;
return result;
};
@@ -257,6 +270,7 @@ define([
this.outlineColor = defaultValue(this.outlineColor, source.outlineColor);
this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth);
this.numberOfVerticalLines = defaultValue(this.numberOfVerticalLines, source.numberOfVerticalLines);
+ this.shadows = defaultValue(this.shadows, source.shadows);
};
return EllipseGraphics;
diff --git a/Source/DataSources/EllipsoidGeometryUpdater.js b/Source/DataSources/EllipsoidGeometryUpdater.js
index 373c3f1ed7bc..04662eb305ff 100644
--- a/Source/DataSources/EllipsoidGeometryUpdater.js
+++ b/Source/DataSources/EllipsoidGeometryUpdater.js
@@ -19,6 +19,7 @@ define([
'../Scene/PerInstanceColorAppearance',
'../Scene/Primitive',
'../Scene/SceneMode',
+ '../Scene/ShadowMode',
'./ColorMaterialProperty',
'./ConstantProperty',
'./dynamicGeometryGetBoundingSphere',
@@ -44,6 +45,7 @@ define([
PerInstanceColorAppearance,
Primitive,
SceneMode,
+ ShadowMode,
ColorMaterialProperty,
ConstantProperty,
dynamicGeometryGetBoundingSphere,
@@ -56,6 +58,7 @@ define([
var defaultFill = new ConstantProperty(true);
var defaultOutline = new ConstantProperty(false);
var defaultOutlineColor = new ConstantProperty(Color.BLACK);
+ var defaultShadows = new ConstantProperty(ShadowMode.DISABLED);
var radiiScratch = new Cartesian3();
var scratchColor = new Color();
@@ -102,6 +105,7 @@ define([
this._showOutlineProperty = undefined;
this._outlineColorProperty = undefined;
this._outlineWidth = 1.0;
+ this._shadowsProperty = undefined;
this._options = new GeometryOptions(entity);
this._onEntityPropertyChanged(entity, 'ellipsoid', entity.ellipsoid, undefined);
}
@@ -229,6 +233,19 @@ define([
return this._outlineWidth;
}
},
+ /**
+ * Gets the property specifying whether the geometry
+ * casts or receives shadows from each light source.
+ * @memberof EllipsoidGeometryUpdater.prototype
+ *
+ * @type {Property}
+ * @readonly
+ */
+ shadowsProperty : {
+ get : function() {
+ return this._shadowsProperty;
+ }
+ },
/**
* Gets a value indicating if the geometry is time-varying.
* If true, all visualization is delegated to the {@link DynamicGeometryUpdater}
@@ -450,6 +467,8 @@ define([
this._showProperty = defaultValue(show, defaultShow);
this._showOutlineProperty = defaultValue(ellipsoid.outline, defaultOutline);
this._outlineColorProperty = outlineEnabled ? defaultValue(ellipsoid.outlineColor, defaultOutlineColor) : undefined;
+ this._shadowsProperty = defaultValue(ellipsoid.shadows, defaultShadows);
+
this._fillEnabled = fillEnabled;
this._outlineEnabled = outlineEnabled;
@@ -577,6 +596,9 @@ define([
var in3D = sceneMode === SceneMode.SCENE3D;
var options = this._options;
+
+ var shadows = this._geometryUpdater.shadowsProperty.getValue(time);
+
//We only rebuild the primitive if something other than the radii has changed
//For the radii, we use unit sphere and then deform it with a scale matrix.
var rebuildPrimitives = !in3D || this._lastSceneMode !== sceneMode || !defined(this._primitive) || //
@@ -614,7 +636,8 @@ define([
}
}),
appearance : appearance,
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
options.vertexFormat = PerInstanceColorAppearance.VERTEX_FORMAT;
@@ -636,7 +659,8 @@ define([
lineWidth : this._geometryUpdater._scene.clampLineWidth(outlineWidth)
}
}),
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
this._lastShow = showFill;
diff --git a/Source/DataSources/EllipsoidGraphics.js b/Source/DataSources/EllipsoidGraphics.js
index 58f03b6f0b76..efa7d92247cb 100644
--- a/Source/DataSources/EllipsoidGraphics.js
+++ b/Source/DataSources/EllipsoidGraphics.js
@@ -34,6 +34,7 @@ define([
* @param {Property} [options.subdivisions=128] A Property specifying the number of samples per outline ring, determining the granularity of the curvature.
* @param {Property} [options.stackPartitions=64] A Property specifying the number of stacks.
* @param {Property} [options.slicePartitions=64] A Property specifying the number of radial slices.
+ * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the ellipsoid casts or receives shadows from each light source.
*
* @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Spheres%20and%20Ellipsoids.html|Cesium Sandcastle Spheres and Ellipsoids Demo}
*/
@@ -58,6 +59,7 @@ define([
this._outlineColorSubscription = undefined;
this._outlineWidth = undefined;
this._outlineWidthSubscription = undefined;
+ this._shadows = undefined;
this._definitionChanged = new Event();
this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT));
@@ -154,7 +156,16 @@ define([
* @type {Property}
* @default 128
*/
- subdivisions : createPropertyDescriptor('subdivisions')
+ subdivisions : createPropertyDescriptor('subdivisions'),
+
+ /**
+ * Get or sets the enum Property specifying whether the ellipsoid
+ * casts or receives shadows from each light source.
+ * @memberof EllipsoidGraphics.prototype
+ * @type {Property}
+ * @default ShadowMode.DISABLED
+ */
+ shadows : createPropertyDescriptor('shadows')
});
/**
@@ -177,6 +188,7 @@ define([
result.stackPartitions = this.stackPartitions;
result.slicePartitions = this.slicePartitions;
result.subdivisions = this.subdivisions;
+ result.shadows = this.shadows;
return result;
};
@@ -204,6 +216,7 @@ define([
this.stackPartitions = defaultValue(this.stackPartitions, source.stackPartitions);
this.slicePartitions = defaultValue(this.slicePartitions, source.slicePartitions);
this.subdivisions = defaultValue(this.subdivisions, source.subdivisions);
+ this.shadows = defaultValue(this.shadows, source.shadows);
};
return EllipsoidGraphics;
diff --git a/Source/DataSources/GeometryVisualizer.js b/Source/DataSources/GeometryVisualizer.js
index bf17f32af4cb..df3cc9e6f5e0 100644
--- a/Source/DataSources/GeometryVisualizer.js
+++ b/Source/DataSources/GeometryVisualizer.js
@@ -5,6 +5,7 @@ define([
'../Core/defined',
'../Core/destroyObject',
'../Core/DeveloperError',
+ '../Scene/ShadowMode',
'./BoundingSphereState',
'./ColorMaterialProperty',
'./StaticGeometryColorBatch',
@@ -17,6 +18,7 @@ define([
defined,
destroyObject,
DeveloperError,
+ ShadowMode,
BoundingSphereState,
ColorMaterialProperty,
StaticGeometryColorBatch,
@@ -84,8 +86,13 @@ define([
return;
}
+ var shadows;
+ if (updater.outlineEnabled || updater.fillEnabled) {
+ shadows = updater.shadowsProperty.getValue(time);
+ }
+
if (updater.outlineEnabled) {
- that._outlineBatch.add(time, updater);
+ that._outlineBatches[shadows].add(time, updater);
}
if (updater.fillEnabled) {
@@ -94,15 +101,15 @@ define([
} else {
if (updater.isClosed) {
if (updater.fillMaterialProperty instanceof ColorMaterialProperty) {
- that._closedColorBatch.add(time, updater);
+ that._closedColorBatches[shadows].add(time, updater);
} else {
- that._closedMaterialBatch.add(time, updater);
+ that._closedMaterialBatches[shadows].add(time, updater);
}
} else {
if (updater.fillMaterialProperty instanceof ColorMaterialProperty) {
- that._openColorBatch.add(time, updater);
+ that._openColorBatches[shadows].add(time, updater);
} else {
- that._openMaterialBatch.add(time, updater);
+ that._openMaterialBatches[shadows].add(time, updater);
}
}
}
@@ -143,15 +150,25 @@ define([
this._removedObjects = new AssociativeArray();
this._changedObjects = new AssociativeArray();
- this._outlineBatch = new StaticOutlineGeometryBatch(primitives, scene);
- this._closedColorBatch = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, true);
- this._closedMaterialBatch = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, true);
- this._openColorBatch = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, false);
- this._openMaterialBatch = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, false);
+ var numberOfShadowModes = ShadowMode.NUMBER_OF_SHADOW_MODES;
+ this._outlineBatches = new Array(numberOfShadowModes);
+ this._closedColorBatches = new Array(numberOfShadowModes);
+ this._closedMaterialBatches = new Array(numberOfShadowModes);
+ this._openColorBatches = new Array(numberOfShadowModes);
+ this._openMaterialBatches = new Array(numberOfShadowModes);
+
+ for (var i = 0; i < numberOfShadowModes; ++i) {
+ this._outlineBatches[i] = new StaticOutlineGeometryBatch(primitives, scene, i);
+ this._closedColorBatches[i] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, true, i);
+ this._closedMaterialBatches[i] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, true, i);
+ this._openColorBatches[i] = new StaticGeometryColorBatch(primitives, type.perInstanceColorAppearanceType, false, i);
+ this._openMaterialBatches[i] = new StaticGeometryPerMaterialBatch(primitives, type.materialAppearanceType, false, i);
+ }
+
this._groundColorBatch = new StaticGroundGeometryColorBatch(groundPrimitives);
this._dynamicBatch = new DynamicGeometryBatch(primitives, groundPrimitives);
- this._batches = [this._closedColorBatch, this._closedMaterialBatch, this._openColorBatch, this._openMaterialBatch,
- this._groundColorBatch, this._dynamicBatch, this._outlineBatch];
+
+ this._batches = this._outlineBatches.concat(this._closedColorBatches, this._closedMaterialBatches, this._openColorBatches, this._openMaterialBatches, this._groundColorBatch, this._dynamicBatch);
this._subscriptions = new AssociativeArray();
this._updaters = new AssociativeArray();
diff --git a/Source/DataSources/KmlDataSource.js b/Source/DataSources/KmlDataSource.js
index 8fa6fe0187ff..88dec7dc5868 100644
--- a/Source/DataSources/KmlDataSource.js
+++ b/Source/DataSources/KmlDataSource.js
@@ -649,7 +649,6 @@ define([
var heading = queryNumericValue(node, 'heading', namespaces.kml);
var color = queryColorValue(node, 'color', namespaces.kml);
-
var iconNode = queryFirstNode(node, 'Icon', namespaces.kml);
var icon = getIconHref(iconNode, dataSource, sourceUri, uriResolver, false);
var x = queryNumericValue(iconNode, 'x', namespaces.gx);
@@ -698,19 +697,20 @@ define([
} else if (hotSpotXUnit === 'insetPixels') {
xOffset = (hotSpotX - BILLBOARD_SIZE) * scale;
} else if (hotSpotXUnit === 'fraction') {
- xOffset = -BILLBOARD_SIZE * scale * hotSpotX;
+ xOffset = -hotSpotX * BILLBOARD_SIZE * scale;
}
xOffset += BILLBOARD_SIZE * 0.5 * scale;
}
if (defined(hotSpotY)) {
if (hotSpotYUnit === 'pixels') {
- yOffset = hotSpotY;
+ yOffset = hotSpotY * scale;
} else if (hotSpotYUnit === 'insetPixels') {
- yOffset = -hotSpotY;
+ yOffset = (-hotSpotY + BILLBOARD_SIZE) * scale;
} else if (hotSpotYUnit === 'fraction') {
- yOffset = hotSpotY * BILLBOARD_SIZE;
+ yOffset = hotSpotY * BILLBOARD_SIZE * scale;
}
+
yOffset -= BILLBOARD_SIZE * 0.5 * scale;
}
@@ -1064,8 +1064,9 @@ define([
billboard.image = dataSource._pinBuilder.fromColor(Color.YELLOW, 64);
}
+ var scale = 1.0;
if (defined(billboard.scale)) {
- var scale = billboard.scale.getValue();
+ scale = billboard.scale.getValue();
if (scale !== 0) {
label.pixelOffset = new Cartesian2((scale * 16) + 1, 0);
} else {
@@ -1150,7 +1151,7 @@ define([
entity.corridor = corridor;
corridor.positions = coordinates;
if (defined(polyline)) {
- corridor.material = defined(polyline.material) ? polyline.material.color : Color.WHITE;
+ corridor.material = defined(polyline.material) ? polyline.material.color.getValue(Iso8601.MINIMUM_VALUE) : Color.WHITE;
corridor.width = defaultValue(polyline.width, 1.0);
} else {
corridor.material = Color.WHITE;
@@ -1525,8 +1526,16 @@ define([
}
entity.availability = availability;
+ // Per KML spec "A Feature is visible only if it and all its ancestors are visible."
+ function ancestryIsVisible(parentEntity) {
+ if (!parentEntity) {
+ return true;
+ }
+ return parentEntity.show && ancestryIsVisible(parentEntity.parent);
+ }
+
var visibility = queryBooleanValue(featureNode, 'visibility', namespaces.kml);
- entity.show = defaultValue(visibility, true);
+ entity.show = ancestryIsVisible(parent) && defaultValue(visibility, true);
//var open = queryBooleanValue(featureNode, 'open', namespaces.kml);
var authorNode = queryFirstNode(featureNode, 'author', namespaces.atom);
@@ -1717,8 +1726,8 @@ define([
}
}
- function processUnsupported(dataSource, parent, node, entityCollection, styleCollection, sourceUri, uriResolver) {
- dataSource._unsupportedNode.raiseEvent(dataSource, node, uriResolver);
+ function processUnsupportedFeature(dataSource, parent, node, entityCollection, styleCollection, sourceUri, uriResolver) {
+ dataSource._unsupportedNode.raiseEvent(dataSource, parent, node, entityCollection, styleCollection, sourceUri, uriResolver);
console.log('KML - Unsupported feature: ' + node.localName);
}
@@ -2008,9 +2017,9 @@ define([
Placemark : processPlacemark,
NetworkLink : processNetworkLink,
GroundOverlay : processGroundOverlay,
- PhotoOverlay : processUnsupported,
- ScreenOverlay : processUnsupported,
- Tour : processUnsupported
+ PhotoOverlay : processUnsupportedFeature,
+ ScreenOverlay : processUnsupportedFeature,
+ Tour : processUnsupportedFeature
};
function processFeatureNode(dataSource, node, parent, entityCollection, styleCollection, sourceUri, uriResolver) {
@@ -2018,8 +2027,7 @@ define([
if (defined(featureProcessor)) {
featureProcessor(dataSource, parent, node, entityCollection, styleCollection, sourceUri, uriResolver);
} else {
- dataSource._unsupportedNode.raiseEvent(dataSource, node, uriResolver);
- console.log('KML - Unsupported feature node: ' + node.localName);
+ processUnsupportedFeature(dataSource, parent, node, entityCollection, styleCollection, sourceUri, uriResolver);
}
}
diff --git a/Source/DataSources/ModelGraphics.js b/Source/DataSources/ModelGraphics.js
index fc947f4fa7e6..e0b5ceb10794 100644
--- a/Source/DataSources/ModelGraphics.js
+++ b/Source/DataSources/ModelGraphics.js
@@ -45,10 +45,11 @@ define([
* @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.castShadows=true] A boolean Property specifying whether the model casts shadows from each light source.
- * @param {Property} [options.receiveShadows=true] A boolean Property specifying whether the model receives shadows from shadow casters in the scene.
* @param {Property} [options.runAnimations=true] A boolean Property specifying if glTF animations specified in the model should be started.
* @param {Property} [options.nodeTransformations] An object, where keys are names of nodes, and values are {@link TranslationRotationScale} Properties describing the transformation to apply to that node.
+ * @param {Property} [options.castShadows=true] Deprecated, use options.shadows instead. A boolean Property specifying whether the model casts shadows from each light source.
+ * @param {Property} [options.receiveShadows=true] Deprecated, use options.shadows instead. A boolean Property specifying whether the model receives shadows from shadow casters in the scene.
+ * @param {Property} [options.shadows=ShadowMode.ENABLED] An enum Property specifying whether the model casts or receives shadows from each light source.
* @param {Property} [options.heightReference=HeightReference.NONE] A Property specifying what the height is relative to.
*
* @see {@link http://cesiumjs.org/2014/03/03/Cesium-3D-Models-Tutorial/|3D Models Tutorial}
@@ -69,6 +70,8 @@ define([
this._castShadowsSubscription = undefined;
this._receiveShadows = undefined;
this._receiveShadowsSubscription = undefined;
+ this._shadows = undefined;
+ this._shadowsSubscription = undefined;
this._uri = undefined;
this._uriSubscription = undefined;
this._runAnimations = undefined;
@@ -146,6 +149,7 @@ define([
* casts shadows from each light source.
* @memberof ModelGraphics.prototype
* @type {Property}
+ * @deprecated
*/
castShadows : createPropertyDescriptor('castShadows'),
@@ -154,9 +158,19 @@ define([
* receives shadows from shadow casters in the scene.
* @memberof ModelGraphics.prototype
* @type {Property}
+ * @deprecated
*/
receiveShadows : createPropertyDescriptor('receiveShadows'),
+ /**
+ * Get or sets the enum Property specifying whether the model
+ * casts or receives shadows from each light source.
+ * @memberof ModelGraphics.prototype
+ * @type {Property}
+ * @default ShadowMode.ENABLED
+ */
+ shadows : createPropertyDescriptor('shadows'),
+
/**
* Gets or sets the string Property specifying the URI of the glTF asset.
* @memberof ModelGraphics.prototype
@@ -206,6 +220,7 @@ define([
result.incrementallyLoadTextures = this.incrementallyLoadTextures;
result.castShadows = this.castShadows;
result.receiveShadows = this.receiveShadows;
+ result.shadows = this.shadows;
result.uri = this.uri;
result.runAnimations = this.runAnimations;
result.nodeTransformations = this.nodeTransformations;
@@ -234,6 +249,7 @@ define([
this.incrementallyLoadTextures = defaultValue(this.incrementallyLoadTextures, source.incrementallyLoadTextures);
this.castShadows = defaultValue(this.castShadows, source.castShadows);
this.receiveShadows = defaultValue(this.receiveShadows, source.receiveShadows);
+ this.shadows = defaultValue(this.shadows, source.shadows);
this.uri = defaultValue(this.uri, source.uri);
this.runAnimations = defaultValue(this.runAnimations, source.runAnimations);
this.heightReference = defaultValue(this.heightReference, source.heightReference);
diff --git a/Source/DataSources/ModelVisualizer.js b/Source/DataSources/ModelVisualizer.js
index a84ddee5e4fd..fde2fedcb7f8 100644
--- a/Source/DataSources/ModelVisualizer.js
+++ b/Source/DataSources/ModelVisualizer.js
@@ -9,6 +9,7 @@ define([
'../Scene/HeightReference',
'../Scene/Model',
'../Scene/ModelAnimationLoop',
+ '../Scene/ShadowMode',
'./BoundingSphereState',
'./Property'
], function(
@@ -21,6 +22,7 @@ define([
HeightReference,
Model,
ModelAnimationLoop,
+ ShadowMode,
BoundingSphereState,
Property) {
'use strict';
@@ -28,9 +30,8 @@ define([
var defaultScale = 1.0;
var defaultMinimumPixelSize = 0.0;
var defaultIncrementallyLoadTextures = true;
+ var defaultShadows = ShadowMode.ENABLED;
var defaultHeightReference = HeightReference.NONE;
- var defaultCastShadows = true;
- var defaultReceiveShadows = true;
var modelMatrixScratch = new Matrix4();
var nodeMatrixScratch = new Matrix4();
@@ -130,13 +131,21 @@ define([
modelHash[entity.id] = modelData;
}
+ var shadows = defaultShadows;
+ if (defined(modelGraphics._shadows)) {
+ shadows = Property.getValueOrDefault(modelGraphics._shadows, time, defaultShadows);
+ } else if (defined(modelGraphics._castShadows) || defined(modelGraphics._receiveShadows)) {
+ var castShadows = Property.getValueOrDefault(modelGraphics._castShadows, time, true);
+ var receiveShadows = Property.getValueOrDefault(modelGraphics.receiveShadows, time, true);
+ shadows = ShadowMode.fromCastReceive(castShadows, receiveShadows);
+ }
+
model.show = true;
model.scale = Property.getValueOrDefault(modelGraphics._scale, time, defaultScale);
model.minimumPixelSize = Property.getValueOrDefault(modelGraphics._minimumPixelSize, time, defaultMinimumPixelSize);
model.maximumScale = Property.getValueOrUndefined(modelGraphics._maximumScale, time);
- model.castShadows = Property.getValueOrDefault(modelGraphics._castShadows, time, defaultCastShadows);
- model.receiveShadows = Property.getValueOrDefault(modelGraphics._receiveShadows, time, defaultReceiveShadows);
model.modelMatrix = Matrix4.clone(modelMatrix, model.modelMatrix);
+ model.shadows = shadows;
model.heightReference = Property.getValueOrDefault(modelGraphics._heightReference, time, defaultHeightReference);
if (model.ready) {
diff --git a/Source/DataSources/PolygonGeometryUpdater.js b/Source/DataSources/PolygonGeometryUpdater.js
index 0d88fef25369..6c2aafd06577 100644
--- a/Source/DataSources/PolygonGeometryUpdater.js
+++ b/Source/DataSources/PolygonGeometryUpdater.js
@@ -20,6 +20,7 @@ define([
'../Scene/MaterialAppearance',
'../Scene/PerInstanceColorAppearance',
'../Scene/Primitive',
+ '../Scene/ShadowMode',
'./ColorMaterialProperty',
'./ConstantProperty',
'./dynamicGeometryGetBoundingSphere',
@@ -46,6 +47,7 @@ define([
MaterialAppearance,
PerInstanceColorAppearance,
Primitive,
+ ShadowMode,
ColorMaterialProperty,
ConstantProperty,
dynamicGeometryGetBoundingSphere,
@@ -58,6 +60,7 @@ define([
var defaultFill = new ConstantProperty(true);
var defaultOutline = new ConstantProperty(false);
var defaultOutlineColor = new ConstantProperty(Color.BLACK);
+ var defaultShadows = new ConstantProperty(ShadowMode.DISABLED);
var scratchColor = new Color();
function GeometryOptions(entity) {
@@ -106,6 +109,7 @@ define([
this._showOutlineProperty = undefined;
this._outlineColorProperty = undefined;
this._outlineWidth = 1.0;
+ this._shadowsProperty = undefined;
this._onTerrain = false;
this._options = new GeometryOptions(entity);
this._onEntityPropertyChanged(entity, 'polygon', entity.polygon, undefined);
@@ -234,6 +238,19 @@ define([
return this._outlineWidth;
}
},
+ /**
+ * Gets the property specifying whether the geometry
+ * casts or receives shadows from each light source.
+ * @memberof PolygonGeometryUpdater.prototype
+ *
+ * @type {Property}
+ * @readonly
+ */
+ shadowsProperty : {
+ get : function() {
+ return this._shadowsProperty;
+ }
+ },
/**
* Gets a value indicating if the geometry is time-varying.
* If true, all visualization is delegated to the {@link DynamicGeometryUpdater}
@@ -468,6 +485,7 @@ define([
this._showProperty = defaultValue(show, defaultShow);
this._showOutlineProperty = defaultValue(polygon.outline, defaultOutline);
this._outlineColorProperty = outlineEnabled ? defaultValue(polygon.outlineColor, defaultOutlineColor) : undefined;
+ this._shadowsProperty = defaultValue(polygon.shadows, defaultShadows);
var height = polygon.height;
var extrudedHeight = polygon.extrudedHeight;
@@ -618,6 +636,8 @@ define([
options.closeTop = closeTopValue;
options.closeBottom = closeBottomValue;
+ var shadows = this._geometryUpdater.shadowsProperty.getValue(time);
+
if (Property.getValueOrDefault(polygon.fill, time, true)) {
var fillMaterialProperty = geometryUpdater.fillMaterialProperty;
var material = MaterialProperty.getValue(time, fillMaterialProperty, this._material);
@@ -630,14 +650,15 @@ define([
}
this._primitive = groundPrimitives.add(new GroundPrimitive({
- geometryInstance : new GeometryInstance({
+ geometryInstances : new GeometryInstance({
id : entity,
geometry : new PolygonGeometry(options),
attributes: {
color: ColorGeometryInstanceAttribute.fromColor(currentColor)
}
}),
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
} else {
var appearance = new MaterialAppearance({
@@ -653,7 +674,8 @@ define([
geometry : new PolygonGeometry(options)
}),
appearance : appearance,
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
}
}
@@ -680,7 +702,8 @@ define([
lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth)
}
}),
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
}
};
diff --git a/Source/DataSources/PolygonGraphics.js b/Source/DataSources/PolygonGraphics.js
index 4676b1905973..cdd0b39f6bfa 100644
--- a/Source/DataSources/PolygonGraphics.js
+++ b/Source/DataSources/PolygonGraphics.js
@@ -40,6 +40,7 @@ define([
* @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.shadows=ShadowMode.DISABLED] An enum Property specifying whether the polygon casts or receives shadows from each light source.
*
* @see Entity
* @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polygon.html|Cesium Sandcastle Polygon Demo}
@@ -74,6 +75,8 @@ define([
this._closeTopSubscription = undefined;
this._closeBottom = undefined;
this._closeBottomSubscription = undefined;
+ this._shadows = undefined;
+ this._shadowsSubscription = undefined;
this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT));
}
@@ -201,7 +204,16 @@ define([
* @memberof PolygonGraphics.prototype
* @type {Property}
*/
- closeBottom : createPropertyDescriptor('closeBottom')
+ closeBottom : createPropertyDescriptor('closeBottom'),
+
+ /**
+ * Get or sets the enum Property specifying whether the polygon
+ * casts or receives shadows from each light source.
+ * @memberof PolygonGraphics.prototype
+ * @type {Property}
+ * @default ShadowMode.DISABLED
+ */
+ shadows : createPropertyDescriptor('shadows')
});
/**
@@ -228,6 +240,7 @@ define([
result.perPositionHeight = this.perPositionHeight;
result.closeTop = this.closeTop;
result.closeBottom = this.closeBottom;
+ result.shadows = this.shadows;
return result;
};
@@ -258,6 +271,7 @@ define([
this.perPositionHeight = defaultValue(this.perPositionHeight, source.perPositionHeight);
this.closeTop = defaultValue(this.closeTop, source.closeTop);
this.closeBottom = defaultValue(this.closeBottom, source.closeBottom);
+ this.shadows = defaultValue(this.shadows, source.shadows);
};
return PolygonGraphics;
diff --git a/Source/DataSources/PolylineGeometryUpdater.js b/Source/DataSources/PolylineGeometryUpdater.js
index 0f6e1c499912..174248e04ba7 100644
--- a/Source/DataSources/PolylineGeometryUpdater.js
+++ b/Source/DataSources/PolylineGeometryUpdater.js
@@ -18,6 +18,7 @@ define([
'../Scene/PolylineCollection',
'../Scene/PolylineColorAppearance',
'../Scene/PolylineMaterialAppearance',
+ '../Scene/ShadowMode',
'./BoundingSphereState',
'./ColorMaterialProperty',
'./ConstantProperty',
@@ -42,6 +43,7 @@ define([
PolylineCollection,
PolylineColorAppearance,
PolylineMaterialAppearance,
+ ShadowMode,
BoundingSphereState,
ColorMaterialProperty,
ConstantProperty,
@@ -54,6 +56,7 @@ define([
var defaultMaterial = new ColorMaterialProperty(Color.WHITE);
var defaultShow = new ConstantProperty(true);
+ var defaultShadows = new ConstantProperty(ShadowMode.DISABLED);
function GeometryOptions(entity) {
this.id = entity;
@@ -91,6 +94,7 @@ define([
this._geometryChanged = new Event();
this._showProperty = undefined;
this._materialProperty = undefined;
+ this._shadowsProperty = undefined;
this._options = new GeometryOptions(entity);
this._onEntityPropertyChanged(entity, 'polyline', entity.polyline, undefined);
}
@@ -193,6 +197,19 @@ define([
outlineColorProperty : {
value : undefined
},
+ /**
+ * Gets the property specifying whether the geometry
+ * casts or receives shadows from each light source.
+ * @memberof PolylineGeometryUpdater.prototype
+ *
+ * @type {Property}
+ * @readonly
+ */
+ shadowsProperty : {
+ get : function() {
+ return this._shadowsProperty;
+ }
+ },
/**
* Gets a value indicating if the geometry is time-varying.
* If true, all visualization is delegated to the {@link DynamicGeometryUpdater}
@@ -366,6 +383,7 @@ define([
var isColorMaterial = material instanceof ColorMaterialProperty;
this._materialProperty = material;
this._showProperty = defaultValue(show, defaultShow);
+ this._shadowsProperty = defaultValue(polyline.shadows, defaultShadows);
this._fillEnabled = true;
var width = polyline.width;
diff --git a/Source/DataSources/PolylineGraphics.js b/Source/DataSources/PolylineGraphics.js
index a4bc4922ea7b..c1416aed104f 100644
--- a/Source/DataSources/PolylineGraphics.js
+++ b/Source/DataSources/PolylineGraphics.js
@@ -32,6 +32,7 @@ define([
* @param {Property} [options.show=true] A boolean Property specifying the visibility of the polyline.
* @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to draw the polyline.
* @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude if followSurface is true.
+ * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the polyline casts or receives shadows from each light source.
*
* @see Entity
* @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polyline.html|Cesium Sandcastle Polyline Demo}
@@ -50,6 +51,8 @@ define([
this._widthSubscription = undefined;
this._width = undefined;
this._widthSubscription = undefined;
+ this._shadows = undefined;
+ this._shadowsSubscription = undefined;
this._definitionChanged = new Event();
this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT));
@@ -116,7 +119,16 @@ define([
* @type {Property}
* @default Cesium.Math.RADIANS_PER_DEGREE
*/
- granularity : createPropertyDescriptor('granularity')
+ granularity : createPropertyDescriptor('granularity'),
+
+ /**
+ * Get or sets the enum Property specifying whether the polyline
+ * casts or receives shadows from each light source.
+ * @memberof PolylineGraphics.prototype
+ * @type {Property}
+ * @default ShadowMode.DISABLED
+ */
+ shadows : createPropertyDescriptor('shadows')
});
/**
@@ -135,6 +147,7 @@ define([
result.width = this.width;
result.followSurface = this.followSurface;
result.granularity = this.granularity;
+ result.shadows = this.shadows;
return result;
};
@@ -157,6 +170,7 @@ define([
this.width = defaultValue(this.width, source.width);
this.followSurface = defaultValue(this.followSurface, source.followSurface);
this.granularity = defaultValue(this.granularity, source.granularity);
+ this.shadows = defaultValue(this.shadows, source.shadows);
};
return PolylineGraphics;
diff --git a/Source/DataSources/PolylineVolumeGeometryUpdater.js b/Source/DataSources/PolylineVolumeGeometryUpdater.js
index 525b036f53a8..9252f9374c6f 100644
--- a/Source/DataSources/PolylineVolumeGeometryUpdater.js
+++ b/Source/DataSources/PolylineVolumeGeometryUpdater.js
@@ -16,6 +16,7 @@ define([
'../Scene/MaterialAppearance',
'../Scene/PerInstanceColorAppearance',
'../Scene/Primitive',
+ '../Scene/ShadowMode',
'./ColorMaterialProperty',
'./ConstantProperty',
'./dynamicGeometryGetBoundingSphere',
@@ -38,6 +39,7 @@ define([
MaterialAppearance,
PerInstanceColorAppearance,
Primitive,
+ ShadowMode,
ColorMaterialProperty,
ConstantProperty,
dynamicGeometryGetBoundingSphere,
@@ -50,6 +52,7 @@ define([
var defaultFill = new ConstantProperty(true);
var defaultOutline = new ConstantProperty(false);
var defaultOutlineColor = new ConstantProperty(Color.BLACK);
+ var defaultShadows = new ConstantProperty(ShadowMode.DISABLED);
var scratchColor = new Color();
function GeometryOptions(entity) {
@@ -93,6 +96,7 @@ define([
this._showOutlineProperty = undefined;
this._outlineColorProperty = undefined;
this._outlineWidth = 1.0;
+ this._shadowsProperty = undefined;
this._options = new GeometryOptions(entity);
this._onEntityPropertyChanged(entity, 'polylineVolume', entity.polylineVolume, undefined);
}
@@ -220,6 +224,19 @@ define([
return this._outlineWidth;
}
},
+ /**
+ * Gets the property specifying whether the geometry
+ * casts or receives shadows from each light source.
+ * @memberof PolylineVolumeGeometryUpdater.prototype
+ *
+ * @type {Property}
+ * @readonly
+ */
+ shadowsProperty : {
+ get : function() {
+ return this._shadowsProperty;
+ }
+ },
/**
* Gets a value indicating if the geometry is time-varying.
* If true, all visualization is delegated to the {@link DynamicGeometryUpdater}
@@ -437,6 +454,7 @@ define([
this._showProperty = defaultValue(show, defaultShow);
this._showOutlineProperty = defaultValue(polylineVolume.outline, defaultOutline);
this._outlineColorProperty = outlineEnabled ? defaultValue(polylineVolume.outlineColor, defaultOutlineColor) : undefined;
+ this._shadowsProperty = defaultValue(polylineVolume.shadows, defaultShadows);
var granularity = polylineVolume.granularity;
var outlineWidth = polylineVolume.outlineWidth;
@@ -531,6 +549,8 @@ define([
options.granularity = Property.getValueOrUndefined(polylineVolume.granularity, time);
options.cornerType = Property.getValueOrUndefined(polylineVolume.cornerType, time);
+ var shadows = this._geometryUpdater.shadowsProperty.getValue(time);
+
if (!defined(polylineVolume.fill) || polylineVolume.fill.getValue(time)) {
var material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material);
this._material = material;
@@ -548,7 +568,8 @@ define([
geometry : new PolylineVolumeGeometry(options)
}),
appearance : appearance,
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
}
@@ -574,7 +595,8 @@ define([
lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth)
}
}),
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
}
};
diff --git a/Source/DataSources/PolylineVolumeGraphics.js b/Source/DataSources/PolylineVolumeGraphics.js
index acf3be4bc9a5..824a97a9b7ea 100644
--- a/Source/DataSources/PolylineVolumeGraphics.js
+++ b/Source/DataSources/PolylineVolumeGraphics.js
@@ -35,6 +35,7 @@ define([
* @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.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude point.
+ * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the volume casts or receives shadows from each light source.
*
* @see Entity
* @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polyline%20Volume.html|Cesium Sandcastle Polyline Volume Demo}
@@ -60,6 +61,8 @@ define([
this._outlineColorSubscription = undefined;
this._outlineWidth = undefined;
this._outlineWidthSubscription = undefined;
+ this._shadows = undefined;
+ this._shadowsSubscription = undefined;
this._definitionChanged = new Event();
this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT));
@@ -155,7 +158,16 @@ define([
* @type {Property}
* @default CornerType.ROUNDED
*/
- cornerType : createPropertyDescriptor('cornerType')
+ cornerType : createPropertyDescriptor('cornerType'),
+
+ /**
+ * Get or sets the enum Property specifying whether the volume
+ * casts or receives shadows from each light source.
+ * @memberof PolylineVolumeGraphics.prototype
+ * @type {Property}
+ * @default ShadowMode.DISABLED
+ */
+ shadows : createPropertyDescriptor('shadows')
});
/**
@@ -178,6 +190,7 @@ define([
result.outlineColor = this.outlineColor;
result.outlineWidth = this.outlineWidth;
result.cornerType = this.cornerType;
+ result.shadows = this.shadows;
return result;
};
@@ -204,6 +217,7 @@ define([
this.outlineColor = defaultValue(this.outlineColor, source.outlineColor);
this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth);
this.cornerType = defaultValue(this.cornerType, source.cornerType);
+ this.shadows = defaultValue(this.shadows, source.shadows);
};
return PolylineVolumeGraphics;
diff --git a/Source/DataSources/RectangleGeometryUpdater.js b/Source/DataSources/RectangleGeometryUpdater.js
index 9a997f42c8c7..27a25798c18c 100644
--- a/Source/DataSources/RectangleGeometryUpdater.js
+++ b/Source/DataSources/RectangleGeometryUpdater.js
@@ -18,6 +18,7 @@ define([
'../Scene/MaterialAppearance',
'../Scene/PerInstanceColorAppearance',
'../Scene/Primitive',
+ '../Scene/ShadowMode',
'./ColorMaterialProperty',
'./ConstantProperty',
'./dynamicGeometryGetBoundingSphere',
@@ -42,6 +43,7 @@ define([
MaterialAppearance,
PerInstanceColorAppearance,
Primitive,
+ ShadowMode,
ColorMaterialProperty,
ConstantProperty,
dynamicGeometryGetBoundingSphere,
@@ -54,6 +56,7 @@ define([
var defaultFill = new ConstantProperty(true);
var defaultOutline = new ConstantProperty(false);
var defaultOutlineColor = new ConstantProperty(Color.BLACK);
+ var defaultShadows = new ConstantProperty(ShadowMode.DISABLED);
var scratchColor = new Color();
function GeometryOptions(entity) {
@@ -102,6 +105,7 @@ define([
this._showOutlineProperty = undefined;
this._outlineColorProperty = undefined;
this._outlineWidth = 1.0;
+ this._shadowsProperty = undefined;
this._onTerrain = false;
this._options = new GeometryOptions(entity);
@@ -231,6 +235,19 @@ define([
return this._outlineWidth;
}
},
+ /**
+ * Gets the property specifying whether the geometry
+ * casts or receives shadows from each light source.
+ * @memberof RectangleGeometryUpdater.prototype
+ *
+ * @type {Property}
+ * @readonly
+ */
+ shadowsProperty : {
+ get : function() {
+ return this._shadowsProperty;
+ }
+ },
/**
* Gets a value indicating if the geometry is time-varying.
* If true, all visualization is delegated to the {@link DynamicGeometryUpdater}
@@ -462,6 +479,7 @@ define([
this._showProperty = defaultValue(show, defaultShow);
this._showOutlineProperty = defaultValue(rectangle.outline, defaultOutline);
this._outlineColorProperty = outlineEnabled ? defaultValue(rectangle.outlineColor, defaultOutlineColor) : undefined;
+ this._shadowsProperty = defaultValue(rectangle.shadows, defaultShadows);
var height = rectangle.height;
var extrudedHeight = rectangle.extrudedHeight;
@@ -590,6 +608,8 @@ define([
options.closeBottom = Property.getValueOrUndefined(rectangle.closeBottom, time);
options.closeTop = Property.getValueOrUndefined(rectangle.closeTop, time);
+ var shadows = this._geometryUpdater.shadowsProperty.getValue(time);
+
if (Property.getValueOrDefault(rectangle.fill, time, true)) {
var fillMaterialProperty = geometryUpdater.fillMaterialProperty;
var material = MaterialProperty.getValue(time, fillMaterialProperty, this._material);
@@ -602,14 +622,15 @@ define([
}
this._primitive = groundPrimitives.add(new GroundPrimitive({
- geometryInstance : new GeometryInstance({
+ geometryInstances : new GeometryInstance({
id : entity,
geometry : new RectangleGeometry(options),
attributes: {
color: ColorGeometryInstanceAttribute.fromColor(currentColor)
}
}),
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
} else {
var appearance = new MaterialAppearance({
@@ -626,10 +647,10 @@ define([
geometry : new RectangleGeometry(options)
}),
appearance : appearance,
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
}
-
}
if (!onTerrain && Property.getValueOrDefault(rectangle.outline, time, false)) {
@@ -654,7 +675,8 @@ define([
lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth)
}
}),
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
}
};
diff --git a/Source/DataSources/RectangleGraphics.js b/Source/DataSources/RectangleGraphics.js
index 124bd9da6f38..f0e22a2029e4 100644
--- a/Source/DataSources/RectangleGraphics.js
+++ b/Source/DataSources/RectangleGraphics.js
@@ -40,6 +40,7 @@ define([
* @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.shadows=ShadowMode.DISABLED] An enum Property specifying whether the rectangle casts or receives shadows from each light source.
*
* @see Entity
* @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Rectangle.html|Cesium Sandcastle Rectangle Demo}
@@ -73,6 +74,8 @@ define([
this._outlineColorSubscription = undefined;
this._outlineWidth = undefined;
this._outlineWidthSubscription = undefined;
+ this._shadows = undefined;
+ this._shadowsSubscription = undefined;
this._definitionChanged = new Event();
this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT));
@@ -201,7 +204,16 @@ define([
* @type {Property}
* @default true
*/
- closeBottom : createPropertyDescriptor('closeBottom')
+ closeBottom : createPropertyDescriptor('closeBottom'),
+
+ /**
+ * Get or sets the enum Property specifying whether the rectangle
+ * casts or receives shadows from each light source.
+ * @memberof RectangleGraphics.prototype
+ * @type {Property}
+ * @default ShadowMode.DISABLED
+ */
+ shadows : createPropertyDescriptor('shadows')
});
/**
@@ -228,6 +240,7 @@ define([
result.outlineWidth = this.outlineWidth;
result.closeTop = this.closeTop;
result.closeBottom = this.closeBottom;
+ result.shadows = this.shadows;
return result;
};
@@ -258,6 +271,7 @@ define([
this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth);
this.closeTop = defaultValue(this.closeTop, source.closeTop);
this.closeBottom = defaultValue(this.closeBottom, source.closeBottom);
+ this.shadows = defaultValue(this.shadows, source.shadows);
};
return RectangleGraphics;
diff --git a/Source/DataSources/StaticGeometryColorBatch.js b/Source/DataSources/StaticGeometryColorBatch.js
index ea56d93ad7d1..e4ce395124b3 100644
--- a/Source/DataSources/StaticGeometryColorBatch.js
+++ b/Source/DataSources/StaticGeometryColorBatch.js
@@ -19,10 +19,11 @@ define([
var colorScratch = new Color();
- function Batch(primitives, translucent, appearanceType, closed) {
+ function Batch(primitives, translucent, appearanceType, closed, shadows) {
this.translucent = translucent;
this.appearanceType = appearanceType;
this.closed = closed;
+ this.shadows = shadows;
this.primitives = primitives;
this.createPrimitive = false;
this.waitingOnCreate = false;
@@ -108,7 +109,8 @@ define([
appearance : new this.appearanceType({
translucent : this.translucent,
closed : this.closed
- })
+ }),
+ shadows : this.shadows
});
primitives.add(primitive);
isUpdated = false;
@@ -235,9 +237,9 @@ define([
/**
* @private
*/
- function StaticGeometryColorBatch(primitives, appearanceType, closed) {
- this._solidBatch = new Batch(primitives, false, appearanceType, closed);
- this._translucentBatch = new Batch(primitives, true, appearanceType, closed);
+ function StaticGeometryColorBatch(primitives, appearanceType, closed, shadows) {
+ this._solidBatch = new Batch(primitives, false, appearanceType, closed, shadows);
+ this._translucentBatch = new Batch(primitives, true, appearanceType, closed, shadows);
}
StaticGeometryColorBatch.prototype.add = function(time, updater) {
diff --git a/Source/DataSources/StaticGeometryPerMaterialBatch.js b/Source/DataSources/StaticGeometryPerMaterialBatch.js
index 817ae04c1421..95d06ab7e421 100644
--- a/Source/DataSources/StaticGeometryPerMaterialBatch.js
+++ b/Source/DataSources/StaticGeometryPerMaterialBatch.js
@@ -15,11 +15,12 @@ define([
MaterialProperty) {
'use strict';
- function Batch(primitives, appearanceType, materialProperty, closed) {
+ function Batch(primitives, appearanceType, materialProperty, closed, shadows) {
this.primitives = primitives;
this.appearanceType = appearanceType;
this.materialProperty = materialProperty;
this.closed = closed;
+ this.shadows = shadows;
this.updaters = new AssociativeArray();
this.createPrimitive = true;
this.primitive = undefined;
@@ -122,7 +123,8 @@ define([
material : this.material,
translucent : this.material.isTranslucent(),
closed : this.closed
- })
+ }),
+ shadows : this.shadows
});
primitives.add(primitive);
@@ -211,7 +213,7 @@ define([
return BoundingSphereState.PENDING;
}
var attributes = primitive.getGeometryInstanceAttributes(entity);
- if (!defined(attributes) || !defined(attributes.boundingSphere) ||//
+ if (!defined(attributes) || !defined(attributes.boundingSphere) ||
(defined(attributes.show) && attributes.show[0] === 0)) {
return BoundingSphereState.FAILED;
}
@@ -235,11 +237,12 @@ define([
/**
* @private
*/
- function StaticGeometryPerMaterialBatch(primitives, appearanceType, closed) {
+ function StaticGeometryPerMaterialBatch(primitives, appearanceType, closed, shadows) {
this._items = [];
this._primitives = primitives;
this._appearanceType = appearanceType;
this._closed = closed;
+ this._shadows = shadows;
}
StaticGeometryPerMaterialBatch.prototype.add = function(time, updater) {
var items = this._items;
@@ -251,7 +254,7 @@ define([
return;
}
}
- var batch = new Batch(this._primitives, this._appearanceType, updater.fillMaterialProperty, this._closed);
+ var batch = new Batch(this._primitives, this._appearanceType, updater.fillMaterialProperty, this._closed, this._shadows);
batch.add(time, updater);
items.push(batch);
};
diff --git a/Source/DataSources/StaticOutlineGeometryBatch.js b/Source/DataSources/StaticOutlineGeometryBatch.js
index fbeff43dff86..8266ad021f7a 100644
--- a/Source/DataSources/StaticOutlineGeometryBatch.js
+++ b/Source/DataSources/StaticOutlineGeometryBatch.js
@@ -19,8 +19,10 @@ define([
BoundingSphereState) {
'use strict';
- function Batch(primitives, translucent, width) {
+ function Batch(primitives, translucent, width, shadows) {
this.translucent = translucent;
+ this.width = width;
+ this.shadows = shadows;
this.primitives = primitives;
this.createPrimitive = false;
this.waitingOnCreate = false;
@@ -31,7 +33,6 @@ define([
this.updatersWithAttributes = new AssociativeArray();
this.attributes = new AssociativeArray();
this.itemsToRemove = [];
- this.width = width;
this.subscriptions = new AssociativeArray();
this.showsUpdated = new AssociativeArray();
}
@@ -110,7 +111,8 @@ define([
renderState : {
lineWidth : this.width
}
- })
+ }),
+ shadows : this.shadows
});
primitives.add(primitive);
@@ -240,9 +242,10 @@ define([
/**
* @private
*/
- function StaticOutlineGeometryBatch(primitives, scene) {
+ function StaticOutlineGeometryBatch(primitives, scene, shadows) {
this._primitives = primitives;
this._scene = scene;
+ this._shadows = shadows;
this._solidBatches = new AssociativeArray();
this._translucentBatches = new AssociativeArray();
}
@@ -255,7 +258,7 @@ define([
batches = this._solidBatches;
batch = batches.get(width);
if (!defined(batch)) {
- batch = new Batch(this._primitives, false, width);
+ batch = new Batch(this._primitives, false, width, this._shadows);
batches.set(width, batch);
}
batch.add(updater, instance);
@@ -263,7 +266,7 @@ define([
batches = this._translucentBatches;
batch = batches.get(width);
if (!defined(batch)) {
- batch = new Batch(this._primitives, true, width);
+ batch = new Batch(this._primitives, true, width, this._shadows);
batches.set(width, batch);
}
batch.add(updater, instance);
diff --git a/Source/DataSources/WallGeometryUpdater.js b/Source/DataSources/WallGeometryUpdater.js
index e1dbb2eff1d0..27cd6ed42d6b 100644
--- a/Source/DataSources/WallGeometryUpdater.js
+++ b/Source/DataSources/WallGeometryUpdater.js
@@ -16,6 +16,7 @@ define([
'../Scene/MaterialAppearance',
'../Scene/PerInstanceColorAppearance',
'../Scene/Primitive',
+ '../Scene/ShadowMode',
'./ColorMaterialProperty',
'./ConstantProperty',
'./dynamicGeometryGetBoundingSphere',
@@ -38,6 +39,7 @@ define([
MaterialAppearance,
PerInstanceColorAppearance,
Primitive,
+ ShadowMode,
ColorMaterialProperty,
ConstantProperty,
dynamicGeometryGetBoundingSphere,
@@ -50,6 +52,7 @@ define([
var defaultFill = new ConstantProperty(true);
var defaultOutline = new ConstantProperty(false);
var defaultOutlineColor = new ConstantProperty(Color.BLACK);
+ var defaultShadows = new ConstantProperty(ShadowMode.DISABLED);
var scratchColor = new Color();
function GeometryOptions(entity) {
@@ -93,6 +96,7 @@ define([
this._showOutlineProperty = undefined;
this._outlineColorProperty = undefined;
this._outlineWidth = 1.0;
+ this._shadowsProperty = undefined;
this._options = new GeometryOptions(entity);
this._onEntityPropertyChanged(entity, 'wall', entity.wall, undefined);
}
@@ -220,6 +224,19 @@ define([
return this._outlineWidth;
}
},
+ /**
+ * Gets the property specifying whether the geometry
+ * casts or receives shadows from each light source.
+ * @memberof WallGeometryUpdater.prototype
+ *
+ * @type {Property}
+ * @readonly
+ */
+ shadowsProperty : {
+ get : function() {
+ return this._shadowsProperty;
+ }
+ },
/**
* Gets a value indicating if the geometry is time-varying.
* If true, all visualization is delegated to the {@link DynamicGeometryUpdater}
@@ -439,6 +456,7 @@ define([
this._showProperty = defaultValue(show, defaultShow);
this._showOutlineProperty = defaultValue(wall.outline, defaultOutline);
this._outlineColorProperty = outlineEnabled ? defaultValue(wall.outlineColor, defaultOutlineColor) : undefined;
+ this._shadowsProperty = defaultValue(wall.shadows, defaultShadows);
var minimumHeights = wall.minimumHeights;
var maximumHeights = wall.maximumHeights;
@@ -533,6 +551,8 @@ define([
options.maximumHeights = Property.getValueOrUndefined(wall.maximumHeights, time, options.maximumHeights);
options.granularity = Property.getValueOrUndefined(wall.granularity, time);
+ var shadows = this._geometryUpdater.shadowsProperty.getValue(time);
+
if (Property.getValueOrDefault(wall.fill, time, true)) {
var material = MaterialProperty.getValue(time, geometryUpdater.fillMaterialProperty, this._material);
this._material = material;
@@ -550,7 +570,8 @@ define([
geometry : new WallGeometry(options)
}),
appearance : appearance,
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
}
@@ -576,7 +597,8 @@ define([
lineWidth : geometryUpdater._scene.clampLineWidth(outlineWidth)
}
}),
- asynchronous : false
+ asynchronous : false,
+ shadows : shadows
}));
}
};
diff --git a/Source/DataSources/WallGraphics.js b/Source/DataSources/WallGraphics.js
index 3bac99635c44..f0a8e25f89b3 100644
--- a/Source/DataSources/WallGraphics.js
+++ b/Source/DataSources/WallGraphics.js
@@ -35,6 +35,7 @@ define([
* @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.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude point.
+ * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the wall casts or receives shadows from each light source.
*
* @see Entity
* @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Wall.html|Cesium Sandcastle Wall Demo}
@@ -60,6 +61,8 @@ define([
this._outlineColorSubscription = undefined;
this._outlineWidth = undefined;
this._outlineWidthSubscription = undefined;
+ this._shadows = undefined;
+ this._shadowsSubscription = undefined;
this._definitionChanged = new Event();
this.merge(defaultValue(options, defaultValue.EMPTY_OBJECT));
@@ -156,7 +159,16 @@ define([
* @type {Property}
* @default 1.0
*/
- outlineWidth : createPropertyDescriptor('outlineWidth')
+ outlineWidth : createPropertyDescriptor('outlineWidth'),
+
+ /**
+ * Get or sets the enum Property specifying whether the wall
+ * casts or receives shadows from each light source.
+ * @memberof WallGraphics.prototype
+ * @type {Property}
+ * @default ShadowMode.DISABLED
+ */
+ shadows : createPropertyDescriptor('shadows')
});
/**
@@ -179,6 +191,7 @@ define([
result.outline = this.outline;
result.outlineColor = this.outlineColor;
result.outlineWidth = this.outlineWidth;
+ result.shadows = this.shadows;
return result;
};
@@ -205,6 +218,7 @@ define([
this.outline = defaultValue(this.outline, source.outline);
this.outlineColor = defaultValue(this.outlineColor, source.outlineColor);
this.outlineWidth = defaultValue(this.outlineWidth, source.outlineWidth);
+ this.shadows = defaultValue(this.shadows, source.shadows);
};
return WallGraphics;
diff --git a/Source/Renderer/UniformState.js b/Source/Renderer/UniformState.js
index 0e138fbec12a..49ddc5cd50dd 100644
--- a/Source/Renderer/UniformState.js
+++ b/Source/Renderer/UniformState.js
@@ -261,7 +261,7 @@ define([
* @memberof UniformState.prototype
* @private
*/
- inverseTranposeModel : {
+ inverseTransposeModel : {
get : function() {
var m = this._inverseTransposeModel;
if (this._inverseTransposeModelDirty) {
diff --git a/Source/Scene/BillboardCollection.js b/Source/Scene/BillboardCollection.js
index 3e101a01a023..f31b0cde817e 100644
--- a/Source/Scene/BillboardCollection.js
+++ b/Source/Scene/BillboardCollection.js
@@ -789,8 +789,7 @@ define([
billboardCollection._maxPixelOffset = Math.max(billboardCollection._maxPixelOffset, Math.abs(pixelOffsetX + translateX), Math.abs(-pixelOffsetY + translateY));
var horizontalOrigin = billboard.horizontalOrigin;
- var heightReference = billboard._heightReference;
- var verticalOrigin = (heightReference === HeightReference.NONE) ? billboard._verticalOrigin : VerticalOrigin.BOTTOM;
+ var verticalOrigin = billboard._verticalOrigin;
var show = billboard.show;
// If the color alpha is zero, do not show this billboard. This lets us avoid providing
diff --git a/Source/Scene/Camera.js b/Source/Scene/Camera.js
index b4b8c6361dae..965e29b1417c 100644
--- a/Source/Scene/Camera.js
+++ b/Source/Scene/Camera.js
@@ -227,6 +227,7 @@ define([
this._projection = projection;
this._maxCoord = projection.project(new Cartographic(Math.PI, CesiumMath.PI_OVER_TWO));
this._max2Dfrustum = undefined;
+ this._suspendTerrainAdjustment = false;
// set default view
rectangleCameraPosition3D(this, Camera.DEFAULT_VIEW_RECTANGLE, this.position, true);
@@ -346,6 +347,76 @@ define([
}
};
+ var scratchAdjustHeightTransform = new Matrix4();
+ var scratchAdjustHeightCartographic = new Cartographic();
+
+ Camera.prototype._adjustHeightForTerrain = function() {
+ var scene = this._scene;
+
+ var screenSpaceCameraController = scene.screenSpaceCameraController;
+ var enableCollisionDetection = screenSpaceCameraController.enableCollisionDetection;
+ var minimumCollisionTerrainHeight = screenSpaceCameraController.minimumCollisionTerrainHeight;
+ var minimumZoomDistance = screenSpaceCameraController.minimumZoomDistance;
+
+ if (this._suspendTerrainAdjustment || !enableCollisionDetection) {
+ return;
+ }
+
+ var mode = this._mode;
+ var globe = scene.globe;
+
+ if (!defined(globe) || mode === SceneMode.SCENE2D || mode === SceneMode.MORPHING) {
+ return;
+ }
+
+ var ellipsoid = globe.ellipsoid;
+ var projection = scene.mapProjection;
+
+ var transform;
+ var mag;
+ if (!Matrix4.equals(this.transform, Matrix4.IDENTITY)) {
+ transform = Matrix4.clone(this.transform, scratchAdjustHeightTransform);
+ mag = Cartesian3.magnitude(this.position);
+ this._setTransform(Matrix4.IDENTITY);
+ }
+
+ var cartographic = scratchAdjustHeightCartographic;
+ if (mode === SceneMode.SCENE3D) {
+ ellipsoid.cartesianToCartographic(this.position, cartographic);
+ } else {
+ projection.unproject(this.position, cartographic);
+ }
+
+ var heightUpdated = false;
+ if (cartographic.height < minimumCollisionTerrainHeight) {
+ var height = globe.getHeight(cartographic);
+ if (defined(height)) {
+ height += minimumZoomDistance;
+ if (cartographic.height < height) {
+ cartographic.height = height;
+ if (mode === SceneMode.SCENE3D) {
+ ellipsoid.cartographicToCartesian(cartographic, this.position);
+ } else {
+ projection.project(cartographic, this.position);
+ }
+ heightUpdated = true;
+ }
+ }
+ }
+
+ if (defined(transform)) {
+ this._setTransform(transform);
+ if (heightUpdated) {
+ Cartesian3.normalize(this.position, this.position);
+ Cartesian3.negate(this.position, this.direction);
+ Cartesian3.multiplyByScalar(this.position, Math.max(mag, minimumZoomDistance), this.position);
+ Cartesian3.normalize(this.direction, this.direction);
+ Cartesian3.cross(this.direction, this.up, this.right);
+ Cartesian3.cross(this.right, this.direction, this.up);
+ }
+ }
+ };
+
function convertTransformForColumbusView(camera) {
Transforms.basisTo2D(camera._projection, camera._transform, camera._actualTransform);
}
@@ -862,6 +933,13 @@ define([
if (this._mode === SceneMode.SCENE2D) {
clampMove2D(this, this.position);
}
+
+ var globe = this._scene.globe;
+ var globeFinishedUpdating = !defined(globe) || (globe._surface.tileProvider.ready && !defined(globe._surface._tileLoadQueue.head) && globe._surface._debug.tilesWaitingForChildren === 0);
+ if (this._suspendTerrainAdjustment) {
+ this._suspendTerrainAdjustment = !globeFinishedUpdating;
+ }
+ this._adjustHeightForTerrain();
};
var setTransformPosition = new Cartesian3();
@@ -1090,6 +1168,8 @@ define([
var pitch = defaultValue(orientation.pitch, -CesiumMath.PI_OVER_TWO);
var roll = defaultValue(orientation.roll, 0.0);
+ this._suspendTerrainAdjustment = true;
+
if (mode === SceneMode.SCENE3D) {
setView3D(this, destination, heading, pitch, roll);
} else if (mode === SceneMode.SCENE2D) {
@@ -2458,7 +2538,6 @@ define([
};
var scratchFlyToDestination = new Cartesian3();
- var scratchFlyToCarto = new Cartographic();
var newOptions = {
destination : undefined,
heading : undefined,
@@ -2472,6 +2551,17 @@ define([
easingFunction : undefined
};
+ /**
+ * Cancels the current camera flight if one is in progress.
+ * The camera is left at it's current location.
+ */
+ Camera.prototype.cancelFlight = function () {
+ if (defined(this._currentFlight)) {
+ this._currentFlight.cancelTween();
+ this._currentFlight = undefined;
+ }
+ };
+
/**
* Flies the camera from its current position to a new position.
*
@@ -2533,6 +2623,8 @@ define([
return;
}
+ this.cancelFlight();
+
var orientation = defaultValue(options.orientation, defaultValue.EMPTY_OBJECT);
if (defined(orientation.direction)) {
orientation = directionUpToHeadingPitchRoll(this, destination, orientation, scratchSetViewOptions.orientation);
@@ -2558,45 +2650,22 @@ define([
destination = this.getRectangleCameraCoordinates(destination, scratchFlyToDestination);
}
- var sscc = this._scene.screenSpaceCameraController;
-
- if (defined(sscc) || mode === SceneMode.SCENE2D) {
- var ellipsoid = this._scene.mapProjection.ellipsoid;
- var destinationCartographic = ellipsoid.cartesianToCartographic(destination, scratchFlyToCarto);
- var height = destinationCartographic.height;
-
- // Make sure camera doesn't zoom outside set limits
- if (defined(sscc)) {
- //The computed height for rectangle in 2D/CV is stored in the 'z' component of Cartesian3
- if (mode !== SceneMode.SCENE3D && isRectangle) {
- destination.z = CesiumMath.clamp(destination.z, sscc.minimumZoomDistance, sscc.maximumZoomDistance);
- } else {
- destinationCartographic.height = CesiumMath.clamp(destinationCartographic.height, sscc.minimumZoomDistance, sscc.maximumZoomDistance);
- }
- }
-
- // The max height in 2D might be lower than the max height for sscc.
- if (mode === SceneMode.SCENE2D) {
- var maxHeight = ellipsoid.maximumRadius * Math.PI * 2.0;
- if (isRectangle) {
- destination.z = Math.min(destination.z, maxHeight);
- } else {
- destinationCartographic.height = Math.min(destinationCartographic.height, maxHeight);
- }
- }
-
- //Only change if we clamped the height
- if (destinationCartographic.height !== height) {
- destination = ellipsoid.cartographicToCartesian(destinationCartographic, scratchFlyToDestination);
- }
- }
+ var that = this;
+ var flightTween;
newOptions.destination = destination;
newOptions.heading = orientation.heading;
newOptions.pitch = orientation.pitch;
newOptions.roll = orientation.roll;
newOptions.duration = options.duration;
- newOptions.complete = options.complete;
+ newOptions.complete = function () {
+ if(flightTween === that._currentFlight){
+ that._currentFlight = undefined;
+ }
+ if (defined(options.complete)) {
+ options.complete();
+ }
+ };
newOptions.cancel = options.cancel;
newOptions.endTransform = options.endTransform;
newOptions.convert = isRectangle ? false : options.convert;
@@ -2604,7 +2673,8 @@ define([
newOptions.easingFunction = options.easingFunction;
var scene = this._scene;
- scene.tweens.add(CameraFlightPath.createTween(scene, newOptions));
+ flightTween = scene.tweens.add(CameraFlightPath.createTween(scene, newOptions));
+ this._currentFlight = flightTween;
};
function distanceToBoundingSphere3D(camera, radius) {
diff --git a/Source/Scene/CameraFlightPath.js b/Source/Scene/CameraFlightPath.js
index 4b7b28df3e94..3aacb634f9b1 100644
--- a/Source/Scene/CameraFlightPath.js
+++ b/Source/Scene/CameraFlightPath.js
@@ -151,10 +151,6 @@ define([
var startRoll = adjustAngleForLERP(camera.roll, roll);
var destCart = ellipsoid.cartesianToCartographic(destination, scratchEndCart);
- if (destCart.height <= 0.0) {
- destCart.height = startCart.height;
- }
-
startCart.longitude = CesiumMath.zeroToTwoPi(startCart.longitude);
destCart.longitude = CesiumMath.zeroToTwoPi(destCart.longitude);
diff --git a/Source/Scene/FrameState.js b/Source/Scene/FrameState.js
index dbd4935771e7..f64149f62758 100644
--- a/Source/Scene/FrameState.js
+++ b/Source/Scene/FrameState.js
@@ -170,6 +170,23 @@ define([
this.terrainExaggeration = 1.0;
this.shadowHints = {
+ /**
+ * Whether there are any active shadow maps this frame.
+ * @type {Boolean}
+ */
+ shadowsEnabled : true,
+
+ /**
+ * All shadow maps that are enabled this frame.
+ */
+ 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}
diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js
index 118b7b96e800..e16b87fba3bc 100644
--- a/Source/Scene/Globe.js
+++ b/Source/Scene/Globe.js
@@ -7,6 +7,7 @@ define([
'../Core/defaultValue',
'../Core/defined',
'../Core/defineProperties',
+ '../Core/deprecationWarning',
'../Core/destroyObject',
'../Core/DeveloperError',
'../Core/Ellipsoid',
@@ -27,7 +28,8 @@ define([
'./GlobeSurfaceTileProvider',
'./ImageryLayerCollection',
'./QuadtreePrimitive',
- './SceneMode'
+ './SceneMode',
+ './ShadowMode'
], function(
BoundingSphere,
buildModuleUrl,
@@ -36,6 +38,7 @@ define([
defaultValue,
defined,
defineProperties,
+ deprecationWarning,
destroyObject,
DeveloperError,
Ellipsoid,
@@ -56,7 +59,8 @@ define([
GlobeSurfaceTileProvider,
ImageryLayerCollection,
QuadtreePrimitive,
- SceneMode) {
+ SceneMode,
+ ShadowMode) {
'use strict';
/**
@@ -188,23 +192,14 @@ define([
this.depthTestAgainstTerrain = false;
/**
- * Determines whether the globe casts shadows from each light source. Any primitive that has
- * receiveShadows
set to true
will receive shadows that are casted by
- * the globe. This may impact performance since the terrain is rendered again from the light's
- * perspective. Currently only terrain that is in view casts shadows.
+ * Determines whether the globe casts or receives shadows from each light source. Setting the globe
+ * to cast shadows may impact performance since the terrain is rendered again from the light's perspective.
+ * Currently only terrain that is in view casts shadows. By default the globe does not cast shadows.
*
- * @type {Boolean}
- * @default false
- */
- this.castShadows = false;
-
- /**
- * Determines whether the globe receives shadows from shadow casters in the scene.
- *
- * @type {Boolean}
- * @default true
+ * @type {ShadowMode}
+ * @default ShadowMode.RECEIVE_ONLY
*/
- this.receiveShadows = true;
+ this.shadows = ShadowMode.RECEIVE_ONLY;
this._oceanNormalMap = undefined;
this._zoomedOutOceanSpecularIntensity = 0.5;
@@ -286,6 +281,46 @@ define([
get: function() {
return this._surface.tileLoadProgressEvent;
}
+ },
+
+ /**
+ * Determines whether the globe casts shadows from each light source.
+ *
+ * @memberof Globe.prototype
+ * @type {Boolean}
+ * @deprecated
+ */
+ castShadows : {
+ get : function() {
+ deprecationWarning('Globe.castShadows', 'Globe.castShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Globe.shadows instead.');
+ return ShadowMode.castShadows(this.shadows);
+ },
+ set : function(value) {
+ deprecationWarning('Globe.castShadows', 'Globe.castShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Globe.shadows instead.');
+ var castShadows = value;
+ var receiveShadows = ShadowMode.receiveShadows(this.shadows);
+ this.shadows = ShadowMode.fromCastReceive(castShadows, receiveShadows);
+ }
+ },
+
+ /**
+ * Determines whether the globe receives shadows from shadow casters in the scene.
+ *
+ * @memberof Globe.prototype
+ * @type {Boolean}
+ * @deprecated
+ */
+ receiveShadows : {
+ get : function() {
+ deprecationWarning('Globe.receiveShadows', 'Globe.receiveShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Globe.shadows instead.');
+ return ShadowMode.receiveShadows(this.shadows);
+ },
+ set : function(value) {
+ deprecationWarning('Globe.receiveShadows', 'Globe.receiveShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Globe.shadows instead.');
+ var castShadows = ShadowMode.castShadows(this.shadows);
+ var receiveShadows = value;
+ this.shadows = ShadowMode.fromCastReceive(castShadows, receiveShadows);
+ }
}
});
@@ -505,8 +540,7 @@ define([
tileProvider.hasWaterMask = hasWaterMask;
tileProvider.oceanNormalMap = this._oceanNormalMap;
tileProvider.enableLighting = this.enableLighting;
- tileProvider.castShadows = this.castShadows;
- tileProvider.receiveShadows = this.receiveShadows;
+ tileProvider.shadows = this.shadows;
surface.beginFrame(frameState);
}
diff --git a/Source/Scene/GlobeSurfaceTileProvider.js b/Source/Scene/GlobeSurfaceTileProvider.js
index a27a7ba7d1f6..613d72eee6d9 100644
--- a/Source/Scene/GlobeSurfaceTileProvider.js
+++ b/Source/Scene/GlobeSurfaceTileProvider.js
@@ -43,7 +43,8 @@ define([
'./ImageryLayer',
'./ImageryState',
'./QuadtreeTileLoadState',
- './SceneMode'
+ './SceneMode',
+ './ShadowMode'
], function(
BoundingSphere,
BoxOutlineGeometry,
@@ -88,7 +89,8 @@ define([
ImageryLayer,
ImageryState,
QuadtreeTileLoadState,
- SceneMode) {
+ SceneMode,
+ ShadowMode) {
'use strict';
/**
@@ -125,8 +127,7 @@ define([
this.oceanNormalMap = undefined;
this.zoomedOutOceanSpecularIntensity = 0.5;
this.enableLighting = false;
- this.castShadows = false;
- this.receiveShadows = false;
+ this.shadows = ShadowMode.RECEIVE_ONLY;
this._quadtree = undefined;
this._terrainProvider = options.terrainProvider;
@@ -924,8 +925,8 @@ define([
var showOceanWaves = showReflectiveOcean && defined(oceanNormalMap);
var hasVertexNormals = tileProvider.terrainProvider.ready && tileProvider.terrainProvider.hasVertexNormals;
var enableFog = frameState.fog.enabled;
- var castShadows = tileProvider.castShadows;
- var receiveShadows = tileProvider.receiveShadows;
+ var castShadows = ShadowMode.castShadows(tileProvider.shadows);
+ var receiveShadows = ShadowMode.receiveShadows(tileProvider.shadows);
if (showReflectiveOcean) {
--maxTextures;
diff --git a/Source/Scene/ImageryLayer.js b/Source/Scene/ImageryLayer.js
index b60b22e12030..7b68a411bdb4 100644
--- a/Source/Scene/ImageryLayer.js
+++ b/Source/Scene/ImageryLayer.js
@@ -761,6 +761,7 @@ define([
if (!(this._imageryProvider.tilingScheme instanceof GeographicTilingScheme) &&
rectangle.width / texture.width > 1e-5) {
var that = this;
+ imagery.addReference();
var computeCommand = new ComputeCommand({
persists : true,
owner : this,
@@ -773,6 +774,7 @@ define([
texture.destroy();
imagery.texture = outputTexture;
finalizeReprojectTexture(that, context, imagery, outputTexture);
+ imagery.releaseReference();
}
});
this._reprojectComputeCommands.push(computeCommand);
diff --git a/Source/Scene/LabelCollection.js b/Source/Scene/LabelCollection.js
index 44d8c2ff7759..6b28307d8c66 100644
--- a/Source/Scene/LabelCollection.js
+++ b/Source/Scene/LabelCollection.js
@@ -242,8 +242,7 @@ define([
glyphPixelOffset.x = widthOffset * resolutionScale;
glyphPixelOffset.y = 0;
- var heightReference = label._heightReference;
- var verticalOrigin = (heightReference === HeightReference.NONE) ? label._verticalOrigin : VerticalOrigin.BOTTOM;
+ var verticalOrigin = label._verticalOrigin;
for (glyphIndex = 0; glyphIndex < glyphLength; ++glyphIndex) {
glyph = glyphs[glyphIndex];
dimensions = glyph.dimensions;
diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js
index 77f7f67fe898..5644c433eb83 100644
--- a/Source/Scene/Model.js
+++ b/Source/Scene/Model.js
@@ -11,6 +11,7 @@ define([
'../Core/defaultValue',
'../Core/defined',
'../Core/defineProperties',
+ '../Core/deprecationWarning',
'../Core/destroyObject',
'../Core/DeveloperError',
'../Core/FeatureDetection',
@@ -47,7 +48,7 @@ define([
'../ThirdParty/gltfDefaults',
'../ThirdParty/Uri',
'../ThirdParty/when',
- './getModelAccessor',
+ './getBinaryAccessor',
'./HeightReference',
'./ModelAnimationCache',
'./ModelAnimationCollection',
@@ -56,7 +57,8 @@ define([
'./ModelMesh',
'./ModelNode',
'./Pass',
- './SceneMode'
+ './SceneMode',
+ './ShadowMode'
], function(
BoundingSphere,
Cartesian2,
@@ -69,6 +71,7 @@ define([
defaultValue,
defined,
defineProperties,
+ deprecationWarning,
destroyObject,
DeveloperError,
FeatureDetection,
@@ -105,7 +108,7 @@ define([
gltfDefaults,
Uri,
when,
- getModelAccessor,
+ getBinaryAccessor,
HeightReference,
ModelAnimationCache,
ModelAnimationCollection,
@@ -114,7 +117,8 @@ define([
ModelMesh,
ModelNode,
Pass,
- SceneMode) {
+ SceneMode,
+ ShadowMode) {
'use strict';
// Bail out if the browser doesn't support typed arrays, to prevent the setup function
@@ -311,8 +315,9 @@ define([
* @param {Boolean} [options.allowPicking=true] When true
, each glTF mesh and primitive is pickable with {@link Scene#pick}.
* @param {Boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded.
* @param {Boolean} [options.asynchronous=true] Determines if model WebGL resource creation will be spread out over several frames or block until completion once all glTF files are loaded.
- * @param {Boolean} [options.castShadows=true] Determines whether the model casts shadows from each light source.
- * @param {Boolean} [options.receiveShadows=true] Determines whether the model receives shadows from shadow casters in the scene.
+ * @param {Boolean} [options.castShadows=true] Deprecated, use options.shadows instead. Determines whether the model casts shadows from each light source.
+ * @param {Boolean} [options.receiveShadows=true] Deprecated, use options.shadows instead. Determines whether the model receives shadows from shadow casters in the scene.
+ * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the model casts or receives shadows from each light source.
* @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each draw command in the model.
* @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe.
* @param {HeightReference} [options.heightReference] Determines how the model is drawn relative to terrain.
@@ -502,25 +507,19 @@ define([
this._incrementallyLoadTextures = defaultValue(options.incrementallyLoadTextures, true);
this._asynchronous = defaultValue(options.asynchronous, true);
- /**
- * Determines whether the model casts shadows from each light source.
- *
- * @type {Boolean}
- *
- * @default true
- */
- this.castShadows = defaultValue(options.castShadows, true);
- this._castShadows = this.castShadows;
+ // Deprecated options
+ var castShadows = defaultValue(options.castShadows, true);
+ var receiveShadows = defaultValue(options.receiveShadows, true);
/**
- * Determines whether the model receives shadows from shadow casters in the scene.
+ * Determines whether the model casts or receives shadows from each light source.
*
- * @type {Boolean}
+ * @type {ShadowMode}
*
- * @default true
+ * @default ShadowMode.ENABLED
*/
- this.receiveShadows = defaultValue(options.receiveShadows, true);
- this._receiveShadows = this.receiveShadows;
+ this.shadows = defaultValue(options.shadows, ShadowMode.fromCastReceive(castShadows, receiveShadows));
+ this._shadows = this.shadows;
/**
* This property is for debugging only; it is not for production use nor is it optimized.
@@ -868,6 +867,50 @@ define([
get : function() {
return this._dirty;
}
+ },
+
+ /**
+ * Determines whether the model casts shadows from each light source.
+ *
+ * @memberof Model.prototype
+ *
+ * @type {Boolean}
+ *
+ * @deprecated
+ */
+ castShadows : {
+ get : function() {
+ deprecationWarning('Model.castShadows', 'Model.castShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Model.shadows instead.');
+ return ShadowMode.castShadows(this.shadows);
+ },
+ set : function(value) {
+ deprecationWarning('Model.castShadows', 'Model.castShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Model.shadows instead.');
+ var castShadows = value;
+ var receiveShadows = ShadowMode.receiveShadows(this.shadows);
+ this.shadows = ShadowMode.fromCastReceive(castShadows, receiveShadows);
+ }
+ },
+
+ /**
+ * Determines whether the model receives shadows from shadow casters in the scene.
+ *
+ * @memberof Model.prototype
+ *
+ * @type {Boolean}
+ *
+ * @deprecated
+ */
+ receiveShadows : {
+ get : function() {
+ deprecationWarning('Model.receiveShadows', 'Model.receiveShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Model.shadows instead.');
+ return ShadowMode.receiveShadows(this.shadows);
+ },
+ set : function(value) {
+ deprecationWarning('Model.receiveShadows', 'Model.receiveShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Model.shadows instead.');
+ var castShadows = ShadowMode.castShadows(this.shadows);
+ var receiveShadows = value;
+ this.shadows = ShadowMode.fromCastReceive(castShadows, receiveShadows);
+ }
}
});
@@ -946,8 +989,7 @@ define([
* @param {Boolean} [options.allowPicking=true] When true
, each glTF mesh and primitive is pickable with {@link Scene#pick}.
* @param {Boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded.
* @param {Boolean} [options.asynchronous=true] Determines if model WebGL resource creation will be spread out over several frames or block until completion once all glTF files are loaded.
- * @param {Boolean} [options.castShadows=true] Determines whether the model casts shadows from each light source.
- * @param {Boolean} [options.receiveShadows=true] Determines whether the model receives shadows from shadow casters in the scene.
+ * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the model casts or receives shadows from each light source.
* @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each {@link DrawCommand} in the model.
* @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe.
*
@@ -1629,7 +1671,7 @@ define([
}
return undefined;
}
-
+
function modifyShaderForQuantizedAttributes(shader, programName, model, context) {
var quantizedUniforms = {};
model._quantizedUniforms[programName] = quantizedUniforms;
@@ -2172,7 +2214,7 @@ define([
attributes.push({
index : attributeLocation,
vertexBuffer : rendererBuffers[a.bufferView],
- componentsPerAttribute : getModelAccessor(a).componentsPerAttribute,
+ componentsPerAttribute : getBinaryAccessor(a).componentsPerAttribute,
componentDatatype : a.componentType,
normalize : false,
offsetInBytes : a.byteOffset,
@@ -2386,7 +2428,7 @@ define([
},
MODELINVERSETRANSPOSE : function(uniformState, model) {
return function() {
- return uniformState.inverseTranposeModel;
+ return uniformState.inverseTransposeModel;
};
},
MODELVIEWINVERSETRANSPOSE : function(uniformState, model) {
@@ -2880,7 +2922,7 @@ define([
else {
var positions = accessors[primitive.attributes.POSITION];
count = positions.count;
- var accessorInfo = getModelAccessor(positions);
+ var accessorInfo = getBinaryAccessor(positions);
offset = (positions.byteOffset / (accessorInfo.componentsPerAttribute*ComponentDatatype.getSizeInBytes(positions.componentType)));
}
@@ -2915,6 +2957,9 @@ define([
mesh : runtimeMeshesByName[mesh.name]
};
+ var castShadows = ShadowMode.castShadows(model._shadows);
+ var receiveShadows = ShadowMode.receiveShadows(model._shadows);
+
var command = new DrawCommand({
boundingVolume : new BoundingSphere(), // updated in update()
cull : model.cull,
@@ -2924,8 +2969,8 @@ define([
count : count,
offset : offset,
shaderProgram : rendererPrograms[technique.program],
- castShadows : model._castShadows,
- receiveShadows : model._receiveShadows,
+ castShadows : castShadows,
+ receiveShadows : receiveShadows,
uniformMap : uniformMap,
renderState : rs,
owner : owner,
@@ -3353,12 +3398,11 @@ define([
}
function updateShadows(model) {
- if ((model.castShadows !== model._castShadows) || (model.receiveShadows !== model._receiveShadows)) {
- model._castShadows = model.castShadows;
- model._receiveShadows = model.receiveShadows;
+ if (model.shadows !== model._shadows) {
+ model._shadows = model.shadows;
- var castShadows = model.castShadows;
- var receiveShadows = model.receiveShadows;
+ var castShadows = ShadowMode.castShadows(model.shadows);
+ var receiveShadows = ShadowMode.receiveShadows(model.shadows);
var nodeCommands = model._nodeCommands;
var length = nodeCommands.length;
diff --git a/Source/Scene/ModelAnimationCache.js b/Source/Scene/ModelAnimationCache.js
index 9fa635e4c6be..d19ce82e4a52 100644
--- a/Source/Scene/ModelAnimationCache.js
+++ b/Source/Scene/ModelAnimationCache.js
@@ -8,7 +8,7 @@ define([
'../Core/Quaternion',
'../Core/QuaternionSpline',
'../Renderer/WebGLConstants',
- './getModelAccessor'
+ './getBinaryAccessor'
], function(
Cartesian3,
defaultValue,
@@ -18,7 +18,7 @@ define([
Quaternion,
QuaternionSpline,
WebGLConstants,
- getModelAccessor) {
+ getBinaryAccessor) {
'use strict';
/**
@@ -36,7 +36,7 @@ define([
var buffer = buffers[bufferView.buffer];
var byteOffset = bufferView.byteOffset + accessor.byteOffset;
- var byteLength = accessor.count * getModelAccessor(accessor).componentsPerAttribute;
+ var byteLength = accessor.count * getBinaryAccessor(accessor).componentsPerAttribute;
// buffer.path will be undefined when animations are embedded.
return model.cacheKey + '//' + defaultValue(buffer.path, '') + '/' + byteOffset + '/' + byteLength;
@@ -67,7 +67,7 @@ define([
// Convert typed array to Cesium types
var buffer = loadResources.getBuffer(bufferView);
- var typedArray = getModelAccessor(accessor).createArrayBufferView(buffer.buffer, buffer.byteOffset + accessor.byteOffset, count);
+ var typedArray = getBinaryAccessor(accessor).createArrayBufferView(buffer.buffer, buffer.byteOffset + accessor.byteOffset, count);
var i;
if ((componentType === WebGLConstants.FLOAT) && (type === 'SCALAR')) {
@@ -180,7 +180,7 @@ define([
var type = accessor.type;
var count = accessor.count;
var buffer = loadResources.getBuffer(bufferView);
- var typedArray = getModelAccessor(accessor).createArrayBufferView(buffer.buffer, buffer.byteOffset + accessor.byteOffset, count);
+ var typedArray = getBinaryAccessor(accessor).createArrayBufferView(buffer.buffer, buffer.byteOffset + accessor.byteOffset, count);
matrices = new Array(count);
if ((componentType === WebGLConstants.FLOAT) && (type === 'MAT4')) {
diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js
index a46052f31bea..995078d0fe1b 100644
--- a/Source/Scene/Primitive.js
+++ b/Source/Scene/Primitive.js
@@ -9,6 +9,7 @@ define([
'../Core/defaultValue',
'../Core/defined',
'../Core/defineProperties',
+ '../Core/deprecationWarning',
'../Core/destroyObject',
'../Core/DeveloperError',
'../Core/FeatureDetection',
@@ -33,7 +34,8 @@ define([
'./Pass',
'./PrimitivePipeline',
'./PrimitiveState',
- './SceneMode'
+ './SceneMode',
+ './ShadowMode'
], function(
BoundingSphere,
Cartesian2,
@@ -44,6 +46,7 @@ define([
defaultValue,
defined,
defineProperties,
+ deprecationWarning,
destroyObject,
DeveloperError,
FeatureDetection,
@@ -68,7 +71,8 @@ define([
Pass,
PrimitivePipeline,
PrimitiveState,
- SceneMode) {
+ SceneMode,
+ ShadowMode) {
'use strict';
/**
@@ -108,8 +112,9 @@ define([
* @param {Boolean} [options.cull=true] When true
, the renderer frustum culls and horizon culls the primitive's commands based on their bounding volume. Set this to false
for a small performance gain if you are manually culling the primitive.
* @param {Boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready.
* @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown.
- * @param {Boolean} [options.castShadows=false] Determines whether this primitive casts shadows from each light source.
- * @param {Boolean} [options.receiveShadows=false] Determines whether this primitive receives shadows from shadow casters in the scene.
+ * @param {Boolean} [options.castShadows=true] Deprecated, use options.shadows instead. Determines whether the primitive casts shadows from each light source.
+ * @param {Boolean} [options.receiveShadows=true] Deprecated, use options.shadows instead. Determines whether the primitive receives shadows from shadow casters in the scene.
+ * @param {ShadowMode} [options.shadows=ShadowMode.DISABLED] Determines whether this primitive casts or receives shadows from each light source.
*
* @example
* // 1. Draw a translucent ellipse on the surface with a checkerboard pattern
@@ -283,23 +288,18 @@ define([
}
//>>includeEnd('debug');
- /**
- * Determines whether this primitive casts shadows from each light source.
- *
- * @type {Boolean}
- *
- * @default false
- */
- this.castShadows = defaultValue(options.castShadows, false);
+ // Deprecated options
+ var castShadows = defaultValue(options.castShadows, false);
+ var receiveShadows = defaultValue(options.receiveShadows, false);
/**
- * Determines whether this primitive receives shadows from shadow casters in the scene.
+ * Determines whether this primitive casts or receives shadows from each light source.
*
- * @type {Boolean}
+ * @type {ShadowMode}
*
- * @default false
+ * @default ShadowMode.DISABLED
*/
- this.receiveShadows = defaultValue(options.receiveShadows, false);
+ this.shadows = defaultValue(options.shadows, ShadowMode.fromCastReceive(castShadows, receiveShadows));
this._translucent = undefined;
@@ -475,6 +475,46 @@ define([
get : function() {
return this._readyPromise.promise;
}
+ },
+
+ /**
+ * Determines whether the primitive casts shadows from each light source.
+ *
+ * @memberof Primitive.prototype
+ * @type {Boolean}
+ * @deprecated
+ */
+ castShadows : {
+ get : function() {
+ deprecationWarning('Primitive.castShadows', 'Primitive.castShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Primitive.shadows instead.');
+ return ShadowMode.castShadows(this.shadows);
+ },
+ set : function(value) {
+ deprecationWarning('Primitive.castShadows', 'Primitive.castShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Primitive.shadows instead.');
+ var castShadows = value;
+ var receiveShadows = ShadowMode.receiveShadows(this.shadows);
+ this.shadows = ShadowMode.fromCastReceive(castShadows, receiveShadows);
+ }
+ },
+
+ /**
+ * Determines whether the primitive receives shadows from shadow casters in the scene.
+ *
+ * @memberof Primitive.prototype
+ * @type {Boolean}
+ * @deprecated
+ */
+ receiveShadows : {
+ get : function() {
+ deprecationWarning('Primitive.receiveShadows', 'Primitive.receiveShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Primitive.shadows instead.');
+ return ShadowMode.receiveShadows(this.shadows);
+ },
+ set : function(value) {
+ deprecationWarning('Primitive.receiveShadows', 'Primitive.receiveShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Primitive.shadows instead.');
+ var castShadows = ShadowMode.castShadows(this.shadows);
+ var receiveShadows = value;
+ this.shadows = ShadowMode.fromCastReceive(castShadows, receiveShadows);
+ }
}
});
@@ -1325,6 +1365,8 @@ define([
var commandList = frameState.commandList;
var passes = frameState.passes;
if (passes.render) {
+ var castShadows = ShadowMode.castShadows(primitive.shadows);
+ var receiveShadows = ShadowMode.receiveShadows(primitive.shadows);
var colorLength = colorCommands.length;
for (var j = 0; j < colorLength; ++j) {
var sphereIndex = twoPasses ? Math.floor(j / 2) : j;
@@ -1333,8 +1375,8 @@ define([
colorCommand.boundingVolume = boundingSpheres[sphereIndex];
colorCommand.cull = cull;
colorCommand.debugShowBoundingVolume = debugShowBoundingVolume;
- colorCommand.castShadows = primitive.castShadows;
- colorCommand.receiveShadows = primitive.receiveShadows;
+ colorCommand.castShadows = castShadows;
+ colorCommand.receiveShadows = receiveShadows;
commandList.push(colorCommand);
}
diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js
index fcfd53fc76d5..d43b448aab00 100644
--- a/Source/Scene/Scene.js
+++ b/Source/Scene/Scene.js
@@ -1102,9 +1102,11 @@ define([
function updateDerivedCommands(scene, command) {
var frameState = scene.frameState;
- var shadowMaps = frameState.shadowMaps;
var context = scene._context;
var shadowsEnabled = frameState.shadowHints.shadowsEnabled;
+ var shadowMaps = frameState.shadowHints.shadowMaps;
+ var lightShadowMaps = frameState.shadowHints.lightShadowMaps;
+ var lightShadowsEnabled = shadowsEnabled && (lightShadowMaps.length > 0);
var shadowsDirty = false;
if (shadowsEnabled && (command.receiveShadows || command.castShadows)) {
@@ -1123,12 +1125,12 @@ define([
var derivedCommands = command.derivedCommands;
if (shadowsEnabled && (command.receiveShadows || command.castShadows)) {
- derivedCommands.shadows = ShadowMap.createDerivedCommands(shadowMaps, command, shadowsDirty, context, derivedCommands.shadows);
+ derivedCommands.shadows = ShadowMap.createDerivedCommands(shadowMaps, lightShadowMaps, command, shadowsDirty, context, derivedCommands.shadows);
}
var oit = scene._oit;
if (command.pass === Pass.TRANSLUCENT && defined(oit) && oit.isSupported()) {
- if (shadowsEnabled && command.receiveShadows) {
+ if (lightShadowsEnabled && command.receiveShadows) {
derivedCommands.oit = oit.createDerivedCommands(command.derivedCommands.shadows.receiveCommand, context, derivedCommands.oit);
} else {
derivedCommands.oit = oit.createDerivedCommands(command, context, derivedCommands.oit);
@@ -1485,9 +1487,12 @@ define([
return;
}
+ var shadowsEnabled = scene.frameState.shadowHints.shadowsEnabled;
+ var lightShadowsEnabled = shadowsEnabled && (scene.frameState.shadowHints.lightShadowMaps.length > 0);
+
if (scene.debugShowCommands || scene.debugShowFrustums) {
executeDebugCommand(command, scene, passState);
- } else if (scene.frameState.shadowHints.shadowsEnabled && command.receiveShadows && defined(command.derivedCommands.shadows)) {
+ } else if (lightShadowsEnabled && command.receiveShadows && defined(command.derivedCommands.shadows)) {
// If the command receives shadows, execute the derived shadows command.
// Some commands, such as OIT derived commands, do not have derived shadow commands themselves
// and instead shadowing is built-in. In this case execute the command regularly below.
@@ -1832,14 +1837,13 @@ define([
var command = commandList[i];
updateDerivedCommands(scene, command);
- // Don't insert globe commands with the rest of the scene commands since they are handled separately
if (command.castShadows && (command.pass === Pass.GLOBE || command.pass === Pass.OPAQUE || command.pass === Pass.TRANSLUCENT)) {
if (isVisible(command, shadowVolume)) {
if (isPointLight) {
for (var k = 0; k < numberOfPasses; ++k) {
passes[k].commandList.push(command);
}
- } else if (numberOfPasses <= 1) {
+ } else if (numberOfPasses === 1) {
passes[0].commandList.push(command);
} else {
var wasVisible = false;
@@ -1863,7 +1867,7 @@ define([
function executeShadowMapCastCommands(scene) {
var frameState = scene.frameState;
- var shadowMaps = frameState.shadowMaps;
+ var shadowMaps = frameState.shadowHints.shadowMaps;
var shadowMapLength = shadowMaps.length;
if (!frameState.shadowHints.shadowsEnabled) {
@@ -2145,10 +2149,28 @@ define([
return;
}
+ // Check if the shadow maps are different than the shadow maps last frame.
+ // If so, the derived commands need to be updated.
+ for (var j = 0; j < length; ++j) {
+ if (shadowMaps[j] !== frameState.shadowHints.shadowMaps[j]) {
+ ++frameState.shadowHints.lastDirtyTime;
+ break;
+ }
+ }
+
+ frameState.shadowHints.shadowMaps.length = 0;
+ frameState.shadowHints.lightShadowMaps.length = 0;
+
for (var i = 0; i < length; ++i) {
var shadowMap = shadowMaps[i];
shadowMap.update(frameState);
+ frameState.shadowHints.shadowMaps.push(shadowMap);
+
+ if (shadowMap.fromLightSource) {
+ frameState.shadowHints.lightShadowMaps.push(shadowMap);
+ }
+
if (shadowMap.dirty) {
++frameState.shadowHints.lastDirtyTime;
shadowMap.dirty = false;
@@ -2303,13 +2325,14 @@ define([
}
this._tweens.update();
- this._camera.update(this._mode);
- this._camera._updateCameraChanged();
this._screenSpaceCameraController.update();
if (defined(this._deviceOrientationCameraController)) {
this._deviceOrientationCameraController.update();
}
+
+ this._camera.update(this._mode);
+ this._camera._updateCameraChanged();
};
var scratchEyeTranslation = new Cartesian3();
diff --git a/Source/Scene/ScreenSpaceCameraController.js b/Source/Scene/ScreenSpaceCameraController.js
index 23af144ee69d..02a98707494e 100644
--- a/Source/Scene/ScreenSpaceCameraController.js
+++ b/Source/Scene/ScreenSpaceCameraController.js
@@ -991,7 +991,6 @@ define([
}
function rotateCVOnTerrain(controller, startPosition, movement) {
- var ellipsoid = controller._ellipsoid;
var scene = controller._scene;
var camera = scene.camera;
@@ -1046,7 +1045,7 @@ define([
var verticalCenter = IntersectionTests.rayPlane(ray, plane, rotateCVVerticalCenter);
var projection = camera._projection;
- ellipsoid = projection.ellipsoid;
+ var ellipsoid = projection.ellipsoid;
Cartesian3.fromElements(center.y, center.z, center.x, center);
var cart = projection.unproject(center, rotateCVCart);
@@ -1122,7 +1121,7 @@ define([
controller._rotateRateRangeAdjustment = radius;
var originalPosition = Cartesian3.clone(camera.positionWC, rotateCVCartesian3);
- adjustHeightForTerrain(controller);
+ camera._adjustHeightForTerrain();
if (!Cartesian3.equals(camera.positionWC, originalPosition)) {
camera._setTransform(verticalTransform);
@@ -1753,7 +1752,7 @@ define([
controller._rotateRateRangeAdjustment = radius;
var originalPosition = Cartesian3.clone(camera.positionWC, tilt3DCartesian3);
- adjustHeightForTerrain(controller);
+ camera._adjustHeightForTerrain();
if (!Cartesian3.equals(camera.positionWC, originalPosition)) {
camera._setTransform(verticalTransform);
@@ -1866,70 +1865,6 @@ define([
reactToInput(controller, controller.enableLook, controller.lookEventTypes, look3D);
}
- var scratchAdjustHeightCartographic = new Cartographic();
-
- function adjustHeightForTerrain(controller) {
- if (!controller.enableCollisionDetection) {
- return;
- }
-
- var scene = controller._scene;
- var mode = scene.mode;
- var globe = scene.globe;
-
- if (!defined(globe) || mode === SceneMode.SCENE2D || mode === SceneMode.MORPHING) {
- return;
- }
-
- var camera = scene.camera;
- var ellipsoid = globe.ellipsoid;
- var projection = scene.mapProjection;
-
- var transform;
- var mag;
- if (!Matrix4.equals(camera.transform, Matrix4.IDENTITY)) {
- transform = Matrix4.clone(camera.transform);
- mag = Cartesian3.magnitude(camera.position);
- camera._setTransform(Matrix4.IDENTITY);
- }
-
- var cartographic = scratchAdjustHeightCartographic;
- if (mode === SceneMode.SCENE3D) {
- ellipsoid.cartesianToCartographic(camera.position, cartographic);
- } else {
- projection.unproject(camera.position, cartographic);
- }
-
- var heightUpdated = false;
- if (cartographic.height < controller._minimumCollisionTerrainHeight) {
- var height = globe.getHeight(cartographic);
- if (defined(height)) {
- height += controller.minimumZoomDistance;
- if (cartographic.height < height) {
- cartographic.height = height;
- if (mode === SceneMode.SCENE3D) {
- ellipsoid.cartographicToCartesian(cartographic, camera.position);
- } else {
- projection.project(cartographic, camera.position);
- }
- heightUpdated = true;
- }
- }
- }
-
- if (defined(transform)) {
- camera._setTransform(transform);
- if (heightUpdated) {
- Cartesian3.normalize(camera.position, camera.position);
- Cartesian3.negate(camera.position, camera.direction);
- Cartesian3.multiplyByScalar(camera.position, Math.max(mag, controller.minimumZoomDistance), camera.position);
- Cartesian3.normalize(camera.direction, camera.direction);
- Cartesian3.cross(camera.direction, camera.up, camera.right);
- Cartesian3.cross(camera.right, camera.direction, camera.up);
- }
- }
- }
-
/**
* @private
*/
@@ -1962,8 +1897,6 @@ define([
update3D(this);
}
- adjustHeightForTerrain(this);
-
this._aggregator.reset();
};
diff --git a/Source/Scene/ShadowMap.js b/Source/Scene/ShadowMap.js
index 22d22a0b673f..6007e8c2059d 100644
--- a/Source/Scene/ShadowMap.js
+++ b/Source/Scene/ShadowMap.js
@@ -161,6 +161,14 @@ define([
this._softShadows = defaultValue(options.softShadows, false);
this.dirty = true;
+ /**
+ * Specifies whether the shadow map originates from a light source. Shadow maps that are used for analytical
+ * purposes should set this to false so as not to affect scene rendering.
+ *
+ * @private
+ */
+ this.fromLightSource = defaultValue(options.fromLightSource, true);
+
/**
* Determines the darkness of the shadows.
*
@@ -1535,11 +1543,12 @@ define([
return result;
}
- ShadowMap.createDerivedCommands = function(shadowMaps, command, shadowsDirty, context, result) {
+ ShadowMap.createDerivedCommands = function(shadowMaps, lightShadowMaps, command, shadowsDirty, context, result) {
if (!defined(result)) {
result = {};
}
+ var lightShadowMapsEnabled = (lightShadowMaps.length > 0);
var shaderProgram = command.shaderProgram;
var vertexShaderSource = shaderProgram.vertexShaderSource;
var fragmentShaderSource = shaderProgram.fragmentShaderSource;
@@ -1568,7 +1577,8 @@ define([
result.castShaderProgramId = command.shaderProgram.id;
}
- if (command.receiveShadows) {
+ if (command.receiveShadows && lightShadowMapsEnabled) {
+ // Only generate a receiveCommand if there is a shadow map originating from a light source.
var receiveShader;
var receiveUniformMap;
if (defined(result.receiveCommand)) {
@@ -1591,7 +1601,7 @@ define([
}
var receiveVS = ShadowMapShader.createShadowReceiveVertexShader(vertexShaderSource, isTerrain, hasTerrainNormal);
- var receiveFS = ShadowMapShader.createShadowReceiveFragmentShader(fragmentShaderSource, shadowMaps[0], command.castShadows, isTerrain, hasTerrainNormal);
+ var receiveFS = ShadowMapShader.createShadowReceiveFragmentShader(fragmentShaderSource, lightShadowMaps[0], command.castShadows, isTerrain, hasTerrainNormal);
receiveShader = ShaderProgram.fromCache({
context : context,
@@ -1600,7 +1610,7 @@ define([
attributeLocations : shaderProgram._attributeLocations
});
- receiveUniformMap = combineUniforms(shadowMaps[0], command.uniformMap, isTerrain);
+ receiveUniformMap = combineUniforms(lightShadowMaps[0], command.uniformMap, isTerrain);
}
result.receiveCommand.shaderProgram = receiveShader;
diff --git a/Source/Scene/ShadowMode.js b/Source/Scene/ShadowMode.js
new file mode 100644
index 000000000000..68983ad7febd
--- /dev/null
+++ b/Source/Scene/ShadowMode.js
@@ -0,0 +1,83 @@
+/*global define*/
+define([
+ '../Core/freezeObject'
+ ], function(
+ freezeObject) {
+ 'use strict';
+
+ /**
+ * Specifies whether the object casts or receives shadows from each light source when
+ * shadows are enabled.
+ *
+ * @exports ShadowMode
+ */
+ var ShadowMode = {
+ /**
+ * The object does not cast or receive shadows.
+ *
+ * @type {Number}
+ * @constant
+ */
+ DISABLED : 0,
+
+ /**
+ * The object casts and receives shadows.
+ *
+ * @type {Number}
+ * @constant
+ */
+ ENABLED : 1,
+
+ /**
+ * The object casts shadows only.
+ *
+ * @type {Number}
+ * @constant
+ */
+ CAST_ONLY : 2,
+
+ /**
+ * The object receives shadows only.
+ *
+ * @type {Number}
+ * @constant
+ */
+ RECEIVE_ONLY : 3,
+
+ /**
+ * @private
+ */
+ NUMBER_OF_SHADOW_MODES : 4
+ };
+
+ /**
+ * @private
+ */
+ ShadowMode.castShadows = function(shadowMode) {
+ return (shadowMode === ShadowMode.ENABLED) || (shadowMode === ShadowMode.CAST_ONLY);
+ };
+
+ /**
+ * @private
+ */
+ ShadowMode.receiveShadows = function(shadowMode) {
+ return (shadowMode === ShadowMode.ENABLED) || (shadowMode === ShadowMode.RECEIVE_ONLY);
+ };
+
+ /**
+ * @private
+ */
+ ShadowMode.fromCastReceive = function(castShadows, receiveShadows) {
+ if (castShadows && receiveShadows) {
+ return ShadowMode.ENABLED;
+ } else if (castShadows) {
+ return ShadowMode.CAST_ONLY;
+ } else if (receiveShadows) {
+ return ShadowMode.RECEIVE_ONLY;
+ } else {
+ return ShadowMode.DISABLED;
+ }
+ };
+
+ return freezeObject(ShadowMode);
+});
diff --git a/Source/Scene/getBinaryAccessor.js b/Source/Scene/getBinaryAccessor.js
new file mode 100644
index 000000000000..e4aa0036f26a
--- /dev/null
+++ b/Source/Scene/getBinaryAccessor.js
@@ -0,0 +1,64 @@
+/*global define*/
+define([
+ '../Core/Cartesian2',
+ '../Core/Cartesian3',
+ '../Core/Cartesian4',
+ '../Core/ComponentDatatype',
+ '../Core/Matrix2',
+ '../Core/Matrix3',
+ '../Core/Matrix4'
+ ], function(
+ Cartesian2,
+ Cartesian3,
+ Cartesian4,
+ ComponentDatatype,
+ Matrix2,
+ Matrix3,
+ Matrix4) {
+ 'use strict';
+
+ var ComponentsPerAttribute = {
+ SCALAR : 1,
+ VEC2 : 2,
+ VEC3 : 3,
+ VEC4 : 4,
+ MAT2 : 4,
+ MAT3 : 9,
+ MAT4 : 16
+ };
+
+ var ClassPerType = {
+ SCALAR : undefined,
+ VEC2 : Cartesian2,
+ VEC3 : Cartesian3,
+ VEC4 : Cartesian4,
+ MAT2 : Matrix2,
+ MAT3 : Matrix3,
+ MAT4 : Matrix4
+ };
+
+ /**
+ * @private
+ */
+ function getBinaryAccessor(accessor) {
+ var componentType = accessor.componentType;
+ var componentDatatype;
+ if (typeof componentType === 'string') {
+ componentDatatype = ComponentDatatype.fromName(componentType);
+ } else {
+ componentDatatype = componentType;
+ }
+
+ var componentsPerAttribute = ComponentsPerAttribute[accessor.type];
+ var classType = ClassPerType[accessor.type];
+ return {
+ componentsPerAttribute : componentsPerAttribute,
+ classType : classType,
+ createArrayBufferView : function(buffer, byteOffset, length) {
+ return ComponentDatatype.createArrayBufferView(componentDatatype, buffer, byteOffset, componentsPerAttribute * length);
+ }
+ };
+ }
+
+ return getBinaryAccessor;
+});
diff --git a/Source/Scene/getModelAccessor.js b/Source/Scene/getModelAccessor.js
deleted file mode 100644
index 59ba2d6c2472..000000000000
--- a/Source/Scene/getModelAccessor.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/*global define*/
-define([
- '../Core/ComponentDatatype'
- ], function(
- ComponentDatatype) {
- 'use strict';
-
- var ComponentsPerAttribute = {
- SCALAR : 1,
- VEC2 : 2,
- VEC3 : 3,
- VEC4 : 4,
- MAT2 : 4,
- MAT3 : 9,
- MAT4 : 16
- };
-
- /**
- * @private
- */
- function getModelAccessor(accessor) {
- var componentDatatype = accessor.componentType;
- var componentsPerAttribute = ComponentsPerAttribute[accessor.type];
-
- return {
- componentsPerAttribute : componentsPerAttribute,
- createArrayBufferView : function(buffer, byteOffset, length) {
- return ComponentDatatype.createArrayBufferView(componentDatatype, buffer, byteOffset, componentsPerAttribute * length);
- }
- };
- }
-
- return getModelAccessor;
-});
diff --git a/Source/Shaders/Builtin/Functions/transpose.glsl b/Source/Shaders/Builtin/Functions/transpose.glsl
index 7c39ca70d69b..8578d4403875 100644
--- a/Source/Shaders/Builtin/Functions/transpose.glsl
+++ b/Source/Shaders/Builtin/Functions/transpose.glsl
@@ -1,5 +1,5 @@
/**
- * Returns the transpose of the matrix. The input matrix
can be
+ * Returns the transpose of the matrix. The input matrix
can be
* a mat2
, mat3
, or mat4
.
*
* @name czm_transpose
@@ -15,7 +15,7 @@
* mat3 czm_transpose(mat3 matrix);
* mat4 czm_transpose(mat4 matrix);
*
- * // Tranpose a 3x3 rotation matrix to find its inverse.
+ * // Transpose a 3x3 rotation matrix to find its inverse.
* mat3 eastNorthUpToEye = czm_eastNorthUpToEyeCoordinates(
* positionMC, normalEC);
* mat3 eyeToEastNorthUp = czm_transpose(eastNorthUpToEye);
diff --git a/Source/ThirdParty/earcut-2.1.1.js b/Source/ThirdParty/earcut-2.1.1.js
index 4ac1683e6f21..be074fec16b9 100644
--- a/Source/ThirdParty/earcut-2.1.1.js
+++ b/Source/ThirdParty/earcut-2.1.1.js
@@ -1,7 +1,6 @@
-(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.earcut = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o