From 0455a130868847a151c3da1c8e64ffc1428bb004 Mon Sep 17 00:00:00 2001 From: Heiko Thiel Date: Fri, 2 Jun 2017 15:46:17 +0200 Subject: [PATCH 001/132] Extent setters in Cesium3DTileStyle --- Source/Scene/Cesium3DTileStyle.js | 37 ++++++- Specs/Scene/Cesium3DTileStyleSpec.js | 138 +++++++++++++++++++++++++++ 2 files changed, 172 insertions(+), 3 deletions(-) diff --git a/Source/Scene/Cesium3DTileStyle.js b/Source/Scene/Cesium3DTileStyle.js index a90f09be6e86..baeaceb50981 100644 --- a/Source/Scene/Cesium3DTileStyle.js +++ b/Source/Scene/Cesium3DTileStyle.js @@ -252,8 +252,19 @@ define([ return this._show; }, set : function(value) { + if (typeof value === 'boolean') { + this._show = new Expression(String(value)); + } else if (typeof value === 'string') { + this._show = new Expression(value); + } else if (defined(value.conditions)) { + this._show = new ConditionsExpression(value); + } else if (defined(value.expression) || defined(value.conditionsExpression)) { + this._show = value; + } else { + this._show = undefined; + return; + } this._showShaderFunctionReady = false; - this._show = value; } }, @@ -297,8 +308,17 @@ define([ return this._color; }, set : function(value) { + if (typeof value === 'string') { + this._color = new Expression(value); + } else if (defined(value.conditions)) { + this._color = new ConditionsExpression(value); + } else if (defined(value.expression) || defined(value.conditionsExpression)) { + this._color = value; + } else { + this._color = undefined; + return; + } this._colorShaderFunctionReady = false; - this._color = value; } }, @@ -342,8 +362,19 @@ define([ return this._pointSize; }, set : function(value) { + if (typeof value === 'number') { + this._pointSize = new Expression(String(value)); + } else if (typeof value === 'string') { + this._pointSize = new Expression(value); + } else if (defined(value.conditions)) { + this._pointSize = new ConditionsExpression(value); + } else if (defined(value.expression) || defined(value.conditionsExpression)) { + this._pointSize = value; + } else { + this._pointSize = undefined; + return; + } this._pointSizeShaderFunctionReady = false; - this._pointSize = value; } }, diff --git a/Specs/Scene/Cesium3DTileStyleSpec.js b/Specs/Scene/Cesium3DTileStyleSpec.js index e6ca079fe116..ddbf2b123606 100644 --- a/Specs/Scene/Cesium3DTileStyleSpec.js +++ b/Specs/Scene/Cesium3DTileStyleSpec.js @@ -155,6 +155,53 @@ defineSuite([ expect(style.show).toEqual(undefined); }); + it('sets show expressions in setter', function() { + var style = new Cesium3DTileStyle(); + + var condExp = new ConditionsExpression({ + conditions : [ + ['${height} > 2', 'false'], + ['true', 'true'] + ] + }); + + style.show = condExp; + expect(style.show).toEqual(condExp); + + var exp = new Expression('false'); + style.show = exp; + expect(style.show).toEqual(exp); + }); + + it('sets show values in setter', function() { + var style = new Cesium3DTileStyle(); + + style.show = '${height} * 10 >= 1000'; + expect(style.show).toEqual(new Expression('${height} * 10 >= 1000')); + + style.show = false; + expect(style.show).toEqual(new Expression('false')); + + var jsonExp = { + conditions : [ + ['${height} > 2', 'false'], + ['true', 'true'] + ] + }; + + style.show = jsonExp; + expect(style.show).toEqual(new ConditionsExpression(jsonExp)); + }); + + it('sets show to undefined if not a string, boolean or conditional in setter', function() { + var style = new Cesium3DTileStyle({ + show : true + }); + + style.show = 5; + expect(style.show).toEqual(undefined); + }); + it('sets color value to expression', function() { var style = new Cesium3DTileStyle({ color : 'color("red")' @@ -193,6 +240,50 @@ defineSuite([ expect(style.color).toEqual(undefined); }); + it('sets color expressions in setter', function() { + var style = new Cesium3DTileStyle(); + + var exp = new Expression('color("red")'); + style.color = exp; + expect(style.color).toEqual(exp); + + var condExp = new ConditionsExpression({ + conditions : [ + ['${height} > 2', 'color("cyan")'], + ['true', 'color("blue")'] + ] + }); + + style.color = condExp; + expect(style.color).toEqual(condExp); + }); + + it('sets color values in setter', function() { + var style = new Cesium3DTileStyle(); + + style.color = 'color("red")'; + expect(style.color).toEqual(new Expression('color("red")')); + + var jsonExp = { + conditions : [ + ['${height} > 2', 'color("cyan")'], + ['true', 'color("blue")'] + ] + }; + + style.color = jsonExp; + expect(style.color).toEqual(new ConditionsExpression(jsonExp)); + }); + + it('sets color to undefined if not a string or conditional in setter', function() { + var style = new Cesium3DTileStyle({ + color : 'color("red")' + }); + + style.color = 5; + expect(style.color).toEqual(undefined); + }); + it('sets pointSize value to expression', function() { var style = new Cesium3DTileStyle({ pointSize : '2' @@ -231,6 +322,53 @@ defineSuite([ expect(style.pointSize).toEqual(undefined); }); + it('sets pointSize expressions in setter', function() { + var style = new Cesium3DTileStyle(); + + var exp = new Expression('2'); + style.pointSize = exp; + expect(style.pointSize).toEqual(exp); + + var condExp = new ConditionsExpression({ + conditions : [ + ['${height} > 2', '1.0'], + ['true', '2.0'] + ] + }); + + style.pointSize = condExp; + expect(style.pointSize).toEqual(condExp); + }); + + it('sets pointSize values in setter', function() { + var style = new Cesium3DTileStyle(); + + style.pointSize = 2; + expect(style.pointSize).toEqual(new Expression('2')); + + style.pointSize = '${height} / 10'; + expect(style.pointSize).toEqual(new Expression('${height} / 10')); + + var jsonExp = { + conditions : [ + ['${height} > 2', '1.0'], + ['true', '2.0'] + ] + }; + + style.pointSize = jsonExp; + expect(style.pointSize).toEqual(new ConditionsExpression(jsonExp)); + }); + + it('sets pointSize to undefined if not a number, string or conditional in setter', function() { + var style = new Cesium3DTileStyle({ + pointSize : true + }); + + style.pointSize = false; + expect(style.pointSize).toEqual(undefined); + }); + it('throws on accessing style if not ready', function() { var style = new Cesium3DTileStyle({}); style._ready = false; From 8b551d2eabbeb895f6bc988657dce6aaafcfd82f Mon Sep 17 00:00:00 2001 From: Heiko Thiel Date: Mon, 12 Jun 2017 09:29:14 +0200 Subject: [PATCH 002/132] Adjusted documentation --- Source/Scene/Cesium3DTileStyle.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Scene/Cesium3DTileStyle.js b/Source/Scene/Cesium3DTileStyle.js index 59379ae8eb67..8f14527c03eb 100644 --- a/Source/Scene/Cesium3DTileStyle.js +++ b/Source/Scene/Cesium3DTileStyle.js @@ -211,7 +211,7 @@ define([ }, /** - * Gets or sets the {@link StyleExpression} object used to evaluate the style's show property. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's show property. Alternative an object defining a show style can be used. *

* The expression must return or convert to a Boolean. *

@@ -267,7 +267,7 @@ define([ }, /** - * Gets or sets the {@link StyleExpression} object used to evaluate the style's color property. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's color property. Alternative an object defining a color style can be used. *

* The expression must return a Color. *

@@ -321,7 +321,7 @@ define([ }, /** - * Gets or sets the {@link StyleExpression} object used to evaluate the style's pointSize property. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's pointSize property. Alternative an object defining a pointSize style can be used. *

* The expression must return or convert to a Number. *

From b371c27fddb1a45a757c0dd18a51f3258bbcd501 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 5 Jul 2017 21:04:52 -0400 Subject: [PATCH 003/132] Initial classification primitive work. --- .../gallery/ClassificationPrimitive.html | 72 + Source/Scene/ClassificationPrimitive.js | 1209 +++++++++++++++++ Source/Scene/Scene.js | 18 +- 3 files changed, 1292 insertions(+), 7 deletions(-) create mode 100644 Apps/Sandcastle/gallery/ClassificationPrimitive.html create mode 100644 Source/Scene/ClassificationPrimitive.js diff --git a/Apps/Sandcastle/gallery/ClassificationPrimitive.html b/Apps/Sandcastle/gallery/ClassificationPrimitive.html new file mode 100644 index 000000000000..1c7df51c6d46 --- /dev/null +++ b/Apps/Sandcastle/gallery/ClassificationPrimitive.html @@ -0,0 +1,72 @@ + + + + + + + + + Cesium Demo + + + + + + +
+

Loading...

+ + + diff --git a/Source/Scene/ClassificationPrimitive.js b/Source/Scene/ClassificationPrimitive.js new file mode 100644 index 000000000000..258a72a1465e --- /dev/null +++ b/Source/Scene/ClassificationPrimitive.js @@ -0,0 +1,1209 @@ +/*global define*/ +define([ + '../Core/BoundingSphere', + '../Core/buildModuleUrl', + '../Core/Cartesian2', + '../Core/Cartesian3', + '../Core/Cartographic', + '../Core/ColorGeometryInstanceAttribute', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/GeographicTilingScheme', + '../Core/GeometryInstance', + '../Core/isArray', + '../Core/loadJson', + '../Core/Math', + '../Core/OrientedBoundingBox', + '../Core/Rectangle', + '../Renderer/DrawCommand', + '../Renderer/Pass', + '../Renderer/RenderState', + '../Renderer/ShaderProgram', + '../Renderer/ShaderSource', + '../Shaders/ShadowVolumeFS', + '../Shaders/ShadowVolumeVS', + '../ThirdParty/when', + './BlendingState', + './DepthFunction', + './PerInstanceColorAppearance', + './Primitive', + './SceneMode', + './StencilFunction', + './StencilOperation' + ], function( + BoundingSphere, + buildModuleUrl, + Cartesian2, + Cartesian3, + Cartographic, + ColorGeometryInstanceAttribute, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + GeographicTilingScheme, + GeometryInstance, + isArray, + loadJson, + CesiumMath, + OrientedBoundingBox, + Rectangle, + DrawCommand, + Pass, + RenderState, + ShaderProgram, + ShaderSource, + ShadowVolumeFS, + ShadowVolumeVS, + when, + BlendingState, + DepthFunction, + PerInstanceColorAppearance, + Primitive, + SceneMode, + StencilFunction, + StencilOperation) { + 'use strict'; + + /** + * A ground primitive represents geometry draped over the terrain in the {@link Scene}. The geometry must be from a single {@link GeometryInstance}. + * Batching multiple geometries is not yet supported. + *

+ * A primitive combines the geometry instance with an {@link Appearance} that describes the full shading, including + * {@link Material} and {@link RenderState}. Roughly, the geometry instance defines the structure and placement, + * and the appearance defines the visual characteristics. Decoupling geometry and appearance allows us to mix + * and match most of them and add a new geometry or appearance independently of each other. Only the {@link PerInstanceColorAppearance} + * is supported at this time. + *

+ *

+ * For correct rendering, this feature requires the EXT_frag_depth WebGL extension. For hardware that do not support this extension, there + * will be rendering artifacts for some viewing angles. + *

+ *

+ * Valid geometries are {@link CircleGeometry}, {@link CorridorGeometry}, {@link EllipseGeometry}, {@link PolygonGeometry}, and {@link RectangleGeometry}. + *

+ * + * @alias ClassificationPrimitive + * @constructor + * + * @param {Object} [options] Object with the following properties: + * @param {Array|GeometryInstance} [options.geometryInstances] The geometry instances to render. + * @param {Boolean} [options.show=true] Determines if this primitive will be shown. + * @param {Boolean} [options.vertexCacheOptimize=false] When true, geometry vertices are optimized for the pre and post-vertex-shader caches. + * @param {Boolean} [options.interleave=false] When true, geometry vertex attributes are interleaved, which can slightly improve rendering performance but increases load time. + * @param {Boolean} [options.compressVertices=true] When true, the geometry vertices are compressed, which will save memory. + * @param {Boolean} [options.releaseGeometryInstances=true] When true, the primitive does not keep a reference to the input geometryInstances to save memory. + * @param {Boolean} [options.allowPicking=true] When true, each geometry instance will only be pickable with {@link Scene#pick}. When false, GPU memory is saved. + * @param {Boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. If false initializeTerrainHeights() must be called first. + * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. + * @param {Boolean} [options.debugShowShadowVolume=false] For debugging only. Determines if the shadow volume for each geometry in the primitive is drawn. Must be true on + * creation for the volumes to be created before the geometry is released or options.releaseGeometryInstance must be false. + * + * @see Primitive + * @see GeometryInstance + * @see Appearance + */ + function ClassificationPrimitive(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + /** + * The geometry instance rendered with this primitive. This may + * be undefined if options.releaseGeometryInstances + * is true when the primitive is constructed. + *

+ * Changing this property after the primitive is rendered has no effect. + *

+ *

+ * Because of the rendering technique used, all geometry instances must be the same color. + * If there is an instance with a differing color, a DeveloperError will be thrown + * on the first attempt to render. + *

+ * + * @type {Array|GeometryInstance} + * + * @default undefined + */ + this.geometryInstances = options.geometryInstances; + /** + * Determines if the primitive will be shown. This affects all geometry + * instances in the primitive. + * + * @type {Boolean} + * + * @default true + */ + this.show = defaultValue(options.show, true); + /** + * This property is for debugging only; it is not for production use nor is it optimized. + *

+ * Draws the bounding sphere for each draw command in the primitive. + *

+ * + * @type {Boolean} + * + * @default false + */ + this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); + + /** + * This property is for debugging only; it is not for production use nor is it optimized. + *

+ * Draws the shadow volume for each geometry in the primitive. + *

+ * + * @type {Boolean} + * + * @default false + */ + this.debugShowShadowVolume = defaultValue(options.debugShowShadowVolume, false); + this._debugShowShadowVolume = false; + + this._sp = undefined; + this._spPick = undefined; + + this._rsStencilPreloadPass = undefined; + this._rsStencilDepthPass = undefined; + this._rsColorPass = undefined; + this._rsPickPass = undefined; + + this._uniformMap = { + u_globeMinimumAltitude: function() { + return 55000.0; + } + }; + + this._boundingVolumes = []; + this._boundingVolumes2D = []; + + this._ready = false; + this._readyPromise = when.defer(); + + this._primitive = undefined; + + this._maxHeight = undefined; + this._minHeight = undefined; + + this._maxTerrainHeight = ClassificationPrimitive._defaultMaxTerrainHeight; + this._minTerrainHeight = ClassificationPrimitive._defaultMinTerrainHeight; + + this._boundingSpheresKeys = []; + this._boundingSpheres = []; + + var appearance = new PerInstanceColorAppearance({ + flat : true + }); + + var readOnlyAttributes; + if (defined(this.geometryInstances) && isArray(this.geometryInstances) && this.geometryInstances.length > 1) { + readOnlyAttributes = readOnlyInstanceAttributesScratch; + } + + this._primitiveOptions = { + geometryInstances : undefined, + appearance : appearance, + vertexCacheOptimize : defaultValue(options.vertexCacheOptimize, false), + interleave : defaultValue(options.interleave, false), + releaseGeometryInstances : defaultValue(options.releaseGeometryInstances, true), + allowPicking : defaultValue(options.allowPicking, true), + asynchronous : defaultValue(options.asynchronous, true), + compressVertices : defaultValue(options.compressVertices, true), + _readOnlyInstanceAttributes : readOnlyAttributes, + _createRenderStatesFunction : undefined, + _createShaderProgramFunction : undefined, + _createCommandsFunction : undefined, + _createPickOffsets : true + }; + } + + var readOnlyInstanceAttributesScratch = ['color']; + + defineProperties(ClassificationPrimitive.prototype, { + /** + * When true, geometry vertices are optimized for the pre and post-vertex-shader caches. + * + * @memberof ClassificationPrimitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + vertexCacheOptimize : { + get : function() { + return this._primitiveOptions.vertexCacheOptimize; + } + }, + + /** + * Determines if geometry vertex attributes are interleaved, which can slightly improve rendering performance. + * + * @memberof ClassificationPrimitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default false + */ + interleave : { + get : function() { + return this._primitiveOptions.interleave; + } + }, + + /** + * When true, the primitive does not keep a reference to the input geometryInstances to save memory. + * + * @memberof ClassificationPrimitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + releaseGeometryInstances : { + get : function() { + return this._primitiveOptions.releaseGeometryInstances; + } + }, + + /** + * When true, each geometry instance will only be pickable with {@link Scene#pick}. When false, GPU memory is saved. + * + * @memberof ClassificationPrimitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + allowPicking : { + get : function() { + return this._primitiveOptions.allowPicking; + } + }, + + /** + * Determines if the geometry instances will be created and batched on a web worker. + * + * @memberof ClassificationPrimitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + asynchronous : { + get : function() { + return this._primitiveOptions.asynchronous; + } + }, + + /** + * When true, geometry vertices are compressed, which will save memory. + * + * @memberof ClassificationPrimitive.prototype + * + * @type {Boolean} + * @readonly + * + * @default true + */ + compressVertices : { + get : function() { + return this._primitiveOptions.compressVertices; + } + }, + + /** + * Determines if the primitive is complete and ready to render. If this property is + * true, the primitive will be rendered the next time that {@link ClassificationPrimitive#update} + * is called. + * + * @memberof ClassificationPrimitive.prototype + * + * @type {Boolean} + * @readonly + */ + ready : { + get : function() { + return this._ready; + } + }, + + /** + * Gets a promise that resolves when the primitive is ready to render. + * @memberof ClassificationPrimitive.prototype + * @type {Promise.} + * @readonly + */ + readyPromise : { + get : function() { + return this._readyPromise.promise; + } + } + }); + + /** + * Determines if ClassificationPrimitive rendering is supported. + * + * @param {Scene} scene The scene. + * @returns {Boolean} true if ClassificationPrimitives are supported; otherwise, returns false + */ + ClassificationPrimitive.isSupported = function(scene) { + return scene.context.stencilBuffer; + }; + + ClassificationPrimitive._defaultMaxTerrainHeight = 9000.0; + ClassificationPrimitive._defaultMinTerrainHeight = -100000.0; + + ClassificationPrimitive._terrainHeights = undefined; + ClassificationPrimitive._terrainHeightsMaxLevel = 6; + + function getComputeMaximumHeightFunction(primitive) { + return function(granularity, ellipsoid) { + var r = ellipsoid.maximumRadius; + var delta = (r / Math.cos(granularity * 0.5)) - r; + return primitive._maxHeight + delta; + }; + } + + function getComputeMinimumHeightFunction(primitive) { + return function(granularity, ellipsoid) { + return primitive._minHeight; + }; + } + + function getStencilPreloadRenderState(enableStencil) { + return { + colorMask : { + red : false, + green : false, + blue : false, + alpha : false + }, + stencilTest : { + enabled : enableStencil, + frontFunction : StencilFunction.ALWAYS, + frontOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.DECREMENT_WRAP, + zPass : StencilOperation.DECREMENT_WRAP + }, + backFunction : StencilFunction.ALWAYS, + backOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.INCREMENT_WRAP, + zPass : StencilOperation.INCREMENT_WRAP + }, + reference : 0, + mask : ~0 + }, + depthTest : { + enabled : false + }, + depthMask : false + }; + } + + function getStencilDepthRenderState(enableStencil) { + return { + colorMask : { + red : false, + green : false, + blue : false, + alpha : false + }, + stencilTest : { + enabled : enableStencil, + frontFunction : StencilFunction.ALWAYS, + frontOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.INCREMENT_WRAP + }, + backFunction : StencilFunction.ALWAYS, + backOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.DECREMENT_WRAP + }, + reference : 0, + mask : ~0 + }, + depthTest : { + enabled : true, + func : DepthFunction.LESS_OR_EQUAL + }, + depthMask : false + }; + } + + + function getColorRenderState(enableStencil) { + return { + stencilTest : { + enabled : enableStencil, + frontFunction : StencilFunction.NOT_EQUAL, + frontOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.DECREMENT_WRAP + }, + backFunction : StencilFunction.NOT_EQUAL, + backOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.DECREMENT_WRAP + }, + reference : 0, + mask : ~0 + }, + depthTest : { + enabled : false + }, + depthMask : false, + blending : BlendingState.ALPHA_BLEND + }; + } + + var pickRenderState = { + stencilTest : { + enabled : true, + frontFunction : StencilFunction.NOT_EQUAL, + frontOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.DECREMENT_WRAP + }, + backFunction : StencilFunction.NOT_EQUAL, + backOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.DECREMENT_WRAP + }, + reference : 0, + mask : ~0 + }, + depthTest : { + enabled : false + }, + depthMask : false + }; + + var scratchBVCartesianHigh = new Cartesian3(); + var scratchBVCartesianLow = new Cartesian3(); + var scratchBVCartesian = new Cartesian3(); + var scratchBVCartographic = new Cartographic(); + var scratchBVRectangle = new Rectangle(); + var tilingScheme = new GeographicTilingScheme(); + var scratchCorners = [new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic()]; + var scratchTileXY = new Cartesian2(); + + function getRectangle(frameState, geometry) { + var ellipsoid = frameState.mapProjection.ellipsoid; + + if (!defined(geometry.attributes) || !defined(geometry.attributes.position3DHigh)) { + if (defined(geometry.rectangle)) { + return geometry.rectangle; + } + + return undefined; + } + + var highPositions = geometry.attributes.position3DHigh.values; + var lowPositions = geometry.attributes.position3DLow.values; + var length = highPositions.length; + + var minLat = Number.POSITIVE_INFINITY; + var minLon = Number.POSITIVE_INFINITY; + var maxLat = Number.NEGATIVE_INFINITY; + var maxLon = Number.NEGATIVE_INFINITY; + + for (var i = 0; i < length; i +=3) { + var highPosition = Cartesian3.unpack(highPositions, i, scratchBVCartesianHigh); + var lowPosition = Cartesian3.unpack(lowPositions, i, scratchBVCartesianLow); + + var position = Cartesian3.add(highPosition, lowPosition, scratchBVCartesian); + var cartographic = ellipsoid.cartesianToCartographic(position, scratchBVCartographic); + + var latitude = cartographic.latitude; + var longitude = cartographic.longitude; + + minLat = Math.min(minLat, latitude); + minLon = Math.min(minLon, longitude); + maxLat = Math.max(maxLat, latitude); + maxLon = Math.max(maxLon, longitude); + } + + var rectangle = scratchBVRectangle; + rectangle.north = maxLat; + rectangle.south = minLat; + rectangle.east = maxLon; + rectangle.west = minLon; + + return rectangle; + } + + var scratchDiagonalCartesianNE = new Cartesian3(); + var scratchDiagonalCartesianSW = new Cartesian3(); + var scratchDiagonalCartographic = new Cartographic(); + var scratchCenterCartesian = new Cartesian3(); + var scratchSurfaceCartesian = new Cartesian3(); + + function getTileXYLevel(rectangle) { + Cartographic.fromRadians(rectangle.east, rectangle.north, 0.0, scratchCorners[0]); + Cartographic.fromRadians(rectangle.west, rectangle.north, 0.0, scratchCorners[1]); + Cartographic.fromRadians(rectangle.east, rectangle.south, 0.0, scratchCorners[2]); + Cartographic.fromRadians(rectangle.west, rectangle.south, 0.0, scratchCorners[3]); + + // Determine which tile the bounding rectangle is in + var lastLevelX = 0, lastLevelY = 0; + var currentX = 0, currentY = 0; + var maxLevel = ClassificationPrimitive._terrainHeightsMaxLevel; + for(var i = 0; i <= maxLevel; ++i) { + var failed = false; + for(var j = 0; j < 4; ++j) { + var corner = scratchCorners[j]; + tilingScheme.positionToTileXY(corner, i, scratchTileXY); + if (j === 0) { + currentX = scratchTileXY.x; + currentY = scratchTileXY.y; + } else if(currentX !== scratchTileXY.x || currentY !== scratchTileXY.y) { + failed = true; + break; + } + } + + if (failed) { + break; + } + + lastLevelX = currentX; + lastLevelY = currentY; + } + + if (i === 0) { + return undefined; + } + + return { + x : lastLevelX, + y : lastLevelY, + level : (i > maxLevel) ? maxLevel : (i - 1) + }; + } + + function setMinMaxTerrainHeights(primitive, rectangle, ellipsoid) { + var xyLevel = getTileXYLevel(rectangle); + + // Get the terrain min/max for that tile + var minTerrainHeight = ClassificationPrimitive._defaultMinTerrainHeight; + var maxTerrainHeight = ClassificationPrimitive._defaultMaxTerrainHeight; + if (defined(xyLevel)) { + var key = xyLevel.level + '-' + xyLevel.x + '-' + xyLevel.y; + var heights = ClassificationPrimitive._terrainHeights[key]; + if (defined(heights)) { + minTerrainHeight = heights[0]; + maxTerrainHeight = heights[1]; + } + + // Compute min by taking the center of the NE->SW diagonal and finding distance to the surface + ellipsoid.cartographicToCartesian(Rectangle.northeast(rectangle, scratchDiagonalCartographic), + scratchDiagonalCartesianNE); + ellipsoid.cartographicToCartesian(Rectangle.southwest(rectangle, scratchDiagonalCartographic), + scratchDiagonalCartesianSW); + + Cartesian3.subtract(scratchDiagonalCartesianSW, scratchDiagonalCartesianNE, scratchCenterCartesian); + Cartesian3.add(scratchDiagonalCartesianNE, + Cartesian3.multiplyByScalar(scratchCenterCartesian, 0.5, scratchCenterCartesian), scratchCenterCartesian); + var surfacePosition = ellipsoid.scaleToGeodeticSurface(scratchCenterCartesian, scratchSurfaceCartesian); + if (defined(surfacePosition)) { + var distance = Cartesian3.distance(scratchCenterCartesian, surfacePosition); + minTerrainHeight = Math.min(minTerrainHeight, -distance); + } else { + minTerrainHeight = ClassificationPrimitive._defaultMinTerrainHeight; + } + } + + primitive._minTerrainHeight = Math.max(ClassificationPrimitive._defaultMinTerrainHeight, minTerrainHeight); + primitive._maxTerrainHeight = maxTerrainHeight; + } + + var scratchBoundingSphere = new BoundingSphere(); + function getInstanceBoundingSphere(rectangle, ellipsoid) { + var xyLevel = getTileXYLevel(rectangle); + + // Get the terrain max for that tile + var maxTerrainHeight = ClassificationPrimitive._defaultMaxTerrainHeight; + if (defined(xyLevel)) { + var key = xyLevel.level + '-' + xyLevel.x + '-' + xyLevel.y; + var heights = ClassificationPrimitive._terrainHeights[key]; + if (defined(heights)) { + maxTerrainHeight = heights[1]; + } + } + + var result = BoundingSphere.fromRectangle3D(rectangle, ellipsoid, 0.0); + BoundingSphere.fromRectangle3D(rectangle, ellipsoid, maxTerrainHeight, scratchBoundingSphere); + + return BoundingSphere.union(result, scratchBoundingSphere, result); + } + + function createBoundingVolume(groundPrimitive, frameState, geometry) { + var ellipsoid = frameState.mapProjection.ellipsoid; + var rectangle = getRectangle(frameState, geometry); + + // Use an oriented bounding box by default, but switch to a bounding sphere if bounding box creation would fail. + if (rectangle.width < CesiumMath.PI) { + var obb = OrientedBoundingBox.fromRectangle(rectangle, groundPrimitive._maxHeight, groundPrimitive._minHeight, ellipsoid); + groundPrimitive._boundingVolumes.push(obb); + } else { + var highPositions = geometry.attributes.position3DHigh.values; + var lowPositions = geometry.attributes.position3DLow.values; + groundPrimitive._boundingVolumes.push(BoundingSphere.fromEncodedCartesianVertices(highPositions, lowPositions)); + } + + if (!frameState.scene3DOnly) { + var projection = frameState.mapProjection; + var boundingVolume = BoundingSphere.fromRectangleWithHeights2D(rectangle, projection, groundPrimitive._maxHeight, groundPrimitive._minHeight); + Cartesian3.fromElements(boundingVolume.center.z, boundingVolume.center.x, boundingVolume.center.y, boundingVolume.center); + + groundPrimitive._boundingVolumes2D.push(boundingVolume); + } + } + + function createRenderStates(groundPrimitive, context, appearance, twoPasses) { + if (defined(groundPrimitive._rsStencilPreloadPass)) { + return; + } + var stencilEnabled = !groundPrimitive.debugShowShadowVolume; + + groundPrimitive._rsStencilPreloadPass = RenderState.fromCache(getStencilPreloadRenderState(stencilEnabled)); + groundPrimitive._rsStencilDepthPass = RenderState.fromCache(getStencilDepthRenderState(stencilEnabled)); + groundPrimitive._rsColorPass = RenderState.fromCache(getColorRenderState(stencilEnabled)); + groundPrimitive._rsPickPass = RenderState.fromCache(pickRenderState); + } + + function modifyForEncodedNormals(primitive, vertexShaderSource) { + if (!primitive.compressVertices) { + return vertexShaderSource; + } + + if (vertexShaderSource.search(/attribute\s+vec3\s+extrudeDirection;/g) !== -1) { + var attributeName = 'compressedAttributes'; + + //only shadow volumes use extrudeDirection, and shadow volumes use vertexFormat: POSITION_ONLY so we don't need to check other attributes + var attributeDecl = 'attribute vec2 ' + attributeName + ';'; + + var globalDecl = 'vec3 extrudeDirection;\n'; + var decode = ' extrudeDirection = czm_octDecode(' + attributeName + ', 65535.0);\n'; + + var modifiedVS = vertexShaderSource; + modifiedVS = modifiedVS.replace(/attribute\s+vec3\s+extrudeDirection;/g, ''); + modifiedVS = ShaderSource.replaceMain(modifiedVS, 'czm_non_compressed_main'); + var compressedMain = + 'void main() \n' + + '{ \n' + + decode + + ' czm_non_compressed_main(); \n' + + '}'; + + return [attributeDecl, globalDecl, modifiedVS, compressedMain].join('\n'); + } + } + + function createShaderProgram(groundPrimitive, frameState, appearance) { + if (defined(groundPrimitive._sp)) { + return; + } + + var context = frameState.context; + var primitive = groundPrimitive._primitive; + var vs = ShadowVolumeVS; + vs = groundPrimitive._primitive._batchTable.getVertexShaderCallback()(vs); + vs = Primitive._appendShowToShader(primitive, vs); + vs = Primitive._appendDistanceDisplayConditionToShader(primitive, vs); + vs = Primitive._modifyShaderPosition(groundPrimitive, vs, frameState.scene3DOnly); + vs = Primitive._updateColorAttribute(primitive, vs); + vs = modifyForEncodedNormals(primitive, vs); + + var fs = ShadowVolumeFS; + var attributeLocations = groundPrimitive._primitive._attributeLocations; + + groundPrimitive._sp = ShaderProgram.replaceCache({ + context : context, + shaderProgram : groundPrimitive._sp, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + + if (groundPrimitive._primitive.allowPicking) { + var vsPick = ShaderSource.createPickVertexShaderSource(vs); + vsPick = Primitive._updatePickColorAttribute(vsPick); + + var pickFS = new ShaderSource({ + sources : [fs], + pickColorQualifier : 'varying' + }); + groundPrimitive._spPick = ShaderProgram.replaceCache({ + context : context, + shaderProgram : groundPrimitive._spPick, + vertexShaderSource : vsPick, + fragmentShaderSource : pickFS, + attributeLocations : attributeLocations + }); + } else { + groundPrimitive._spPick = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + } + } + + function createColorCommands(groundPrimitive, colorCommands) { + var primitive = groundPrimitive._primitive; + var length = primitive._va.length * 3; + colorCommands.length = length; + + var vaIndex = 0; + var uniformMap = primitive._batchTable.getUniformMapCallback()(groundPrimitive._uniformMap); + + for (var i = 0; i < length; i += 3) { + var vertexArray = primitive._va[vaIndex++]; + + // stencil preload command + var command = colorCommands[i]; + if (!defined(command)) { + command = colorCommands[i] = new DrawCommand({ + owner : groundPrimitive, + primitiveType : primitive._primitiveType + }); + } + + command.vertexArray = vertexArray; + command.renderState = groundPrimitive._rsStencilPreloadPass; + command.shaderProgram = groundPrimitive._sp; + command.uniformMap = uniformMap; + command.pass = Pass.GROUND; + + // stencil depth command + command = colorCommands[i + 1]; + if (!defined(command)) { + command = colorCommands[i + 1] = new DrawCommand({ + owner : groundPrimitive, + primitiveType : primitive._primitiveType + }); + } + + command.vertexArray = vertexArray; + command.renderState = groundPrimitive._rsStencilDepthPass; + command.shaderProgram = groundPrimitive._sp; + command.uniformMap = uniformMap; + command.pass = Pass.GROUND; + + // color command + command = colorCommands[i + 2]; + if (!defined(command)) { + command = colorCommands[i + 2] = new DrawCommand({ + owner : groundPrimitive, + primitiveType : primitive._primitiveType + }); + } + + command.vertexArray = vertexArray; + command.renderState = groundPrimitive._rsColorPass; + command.shaderProgram = groundPrimitive._sp; + command.uniformMap = uniformMap; + command.pass = Pass.GROUND; + } + } + + function createPickCommands(groundPrimitive, pickCommands) { + var primitive = groundPrimitive._primitive; + var pickOffsets = primitive._pickOffsets; + var length = pickOffsets.length * 3; + pickCommands.length = length; + + var pickIndex = 0; + var uniformMap = primitive._batchTable.getUniformMapCallback()(groundPrimitive._uniformMap); + + for (var j = 0; j < length; j += 3) { + var pickOffset = pickOffsets[pickIndex++]; + + var offset = pickOffset.offset; + var count = pickOffset.count; + var vertexArray = primitive._va[pickOffset.index]; + + // stencil preload command + var command = pickCommands[j]; + if (!defined(command)) { + command = pickCommands[j] = new DrawCommand({ + owner : groundPrimitive, + primitiveType : primitive._primitiveType + }); + } + + command.vertexArray = vertexArray; + command.offset = offset; + command.count = count; + command.renderState = groundPrimitive._rsStencilPreloadPass; + command.shaderProgram = groundPrimitive._sp; + command.uniformMap = uniformMap; + command.pass = Pass.GROUND; + + // stencil depth command + command = pickCommands[j + 1]; + if (!defined(command)) { + command = pickCommands[j + 1] = new DrawCommand({ + owner : groundPrimitive, + primitiveType : primitive._primitiveType + }); + } + + command.vertexArray = vertexArray; + command.offset = offset; + command.count = count; + command.renderState = groundPrimitive._rsStencilDepthPass; + command.shaderProgram = groundPrimitive._sp; + command.uniformMap = uniformMap; + command.pass = Pass.GROUND; + + // color command + command = pickCommands[j + 2]; + if (!defined(command)) { + command = pickCommands[j + 2] = new DrawCommand({ + owner : groundPrimitive, + primitiveType : primitive._primitiveType + }); + } + + command.vertexArray = vertexArray; + command.offset = offset; + command.count = count; + command.renderState = groundPrimitive._rsPickPass; + command.shaderProgram = groundPrimitive._spPick; + command.uniformMap = uniformMap; + command.pass = Pass.GROUND; + } + } + + function createCommands(groundPrimitive, appearance, material, translucent, twoPasses, colorCommands, pickCommands) { + createColorCommands(groundPrimitive, colorCommands); + createPickCommands(groundPrimitive, pickCommands); + } + + function updateAndQueueCommands(groundPrimitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { + var boundingVolumes; + if (frameState.mode === SceneMode.SCENE3D) { + boundingVolumes = groundPrimitive._boundingVolumes; + } else if (frameState.mode !== SceneMode.SCENE3D && defined(groundPrimitive._boundingVolumes2D)) { + boundingVolumes = groundPrimitive._boundingVolumes2D; + } + + var commandList = frameState.commandList; + var passes = frameState.passes; + if (passes.render) { + var colorLength = colorCommands.length; + for (var j = 0; j < colorLength; ++j) { + colorCommands[j].modelMatrix = modelMatrix; + colorCommands[j].boundingVolume = undefined;//boundingVolumes[Math.floor(j / 3)]; + colorCommands[j].cull = cull; + colorCommands[j].debugShowBoundingVolume = debugShowBoundingVolume; + + commandList.push(colorCommands[j]); + } + } + + if (passes.pick) { + var primitive = groundPrimitive._primitive; + var pickOffsets = primitive._pickOffsets; + var length = pickOffsets.length * 3; + pickCommands.length = length; + + var pickIndex = 0; + for (var k = 0; k < length; k += 3) { + var pickOffset = pickOffsets[pickIndex++]; + var bv = boundingVolumes[pickOffset.index]; + + pickCommands[k].modelMatrix = modelMatrix; + pickCommands[k].boundingVolume = bv; + pickCommands[k].cull = cull; + + pickCommands[k + 1].modelMatrix = modelMatrix; + pickCommands[k + 1].boundingVolume = bv; + pickCommands[k + 1].cull = cull; + + pickCommands[k + 2].modelMatrix = modelMatrix; + pickCommands[k + 2].boundingVolume = bv; + pickCommands[k + 2].cull = cull; + + commandList.push(pickCommands[k], pickCommands[k + 1], pickCommands[k + 2]); + } + } + } + + ClassificationPrimitive._initialized = false; + ClassificationPrimitive._initPromise = undefined; + + /** + * Initializes the minimum and maximum terrain heights. This only needs to be called if you are creating the + * ClassificationPrimitive synchronously. + * + * @returns {Promise} A promise that will resolve once the terrain heights have been loaded. + * + */ + ClassificationPrimitive.initializeTerrainHeights = function() { + var initPromise = ClassificationPrimitive._initPromise; + if (defined(initPromise)) { + return initPromise; + } + + ClassificationPrimitive._initPromise = loadJson(buildModuleUrl('Assets/approximateTerrainHeights.json')).then(function(json) { + ClassificationPrimitive._initialized = true; + ClassificationPrimitive._terrainHeights = json; + }); + + return ClassificationPrimitive._initPromise; + }; + + /** + * Called when {@link Viewer} or {@link CesiumWidget} render the scene to + * get the draw commands needed to render this primitive. + *

+ * Do not call this function directly. This is documented just to + * list the exceptions that may be propagated when the scene is rendered: + *

+ * + * @exception {DeveloperError} All instance geometries must have the same primitiveType. + * @exception {DeveloperError} Appearance and material have a uniform with the same name. + * @exception {DeveloperError} Not all of the geometry instances have the same color attribute. + */ + ClassificationPrimitive.prototype.update = function(frameState) { + if (!this.show || (!defined(this._primitive) && !defined(this.geometryInstances))) { + return; + } + + if (!ClassificationPrimitive._initialized) { + //>>includeStart('debug', pragmas.debug); + if (!this.asynchronous) { + throw new DeveloperError('For synchronous ClassificationPrimitives, you must call ClassificationPrimitive.initializeTerrainHeights() and wait for the returned promise to resolve.'); + } + //>>includeEnd('debug'); + + ClassificationPrimitive.initializeTerrainHeights(); + return; + } + + var that = this; + var primitiveOptions = this._primitiveOptions; + + if (!defined(this._primitive)) { + var ellipsoid = frameState.mapProjection.ellipsoid; + + var instance; + var geometry; + var instanceType; + + var instances = isArray(this.geometryInstances) ? this.geometryInstances : [this.geometryInstances]; + var length = instances.length; + var groundInstances = new Array(length); + + var i; + var color; + var rectangle; + for (i = 0; i < length; ++i) { + instance = instances[i]; + geometry = instance.geometry; + var instanceRectangle = getRectangle(frameState, geometry); + if (!defined(rectangle)) { + rectangle = instanceRectangle; + } else { + if (defined(instanceRectangle)) { + Rectangle.union(rectangle, instanceRectangle, rectangle); + } + } + + var id = instance.id; + if (defined(id) && defined(instanceRectangle)) { + var boundingSphere = getInstanceBoundingSphere(instanceRectangle, ellipsoid); + this._boundingSpheresKeys.push(id); + this._boundingSpheres.push(boundingSphere); + } + + instanceType = geometry.constructor; + if (defined(instanceType)/* && defined(instanceType.createShadowVolume)*/) { + var attributes = instance.attributes; + + //>>includeStart('debug', pragmas.debug); + if (!defined(attributes) || !defined(attributes.color)) { + throw new DeveloperError('Not all of the geometry instances have the same color attribute.'); + } else if (defined(color) && !ColorGeometryInstanceAttribute.equals(color, attributes.color)) { + throw new DeveloperError('Not all of the geometry instances have the same color attribute.'); + } else if (!defined(color)) { + color = attributes.color; + } + //>>includeEnd('debug'); + } else { + //>>includeStart('debug', pragmas.debug); + throw new DeveloperError('Not all of the geometry instances have ClassificationPrimitive support.'); + //>>includeEnd('debug'); + } + } + + // Now compute the min/max heights for the primitive + //setMinMaxTerrainHeights(this, rectangle, frameState.mapProjection.ellipsoid); + //var exaggeration = frameState.terrainExaggeration; + //this._minHeight = this._minTerrainHeight * exaggeration; + //this._maxHeight = this._maxTerrainHeight * exaggeration; + + this._minHeight = ClassificationPrimitive._defaultMaxTerrainHeight; + this._maxHeight = ClassificationPrimitive._defaultMinTerrainHeight; + + for (i = 0; i < length; ++i) { + instance = instances[i]; + geometry = instance.geometry; + instanceType = geometry.constructor; + groundInstances[i] = new GeometryInstance({ + //geometry : instanceType.createShadowVolume(geometry, getComputeMinimumHeightFunction(this), + // getComputeMaximumHeightFunction(this)), + geometry : geometry, + attributes : instance.attributes, + id : instance.id, + pickPrimitive : this + }); + } + + primitiveOptions.geometryInstances = groundInstances; + + primitiveOptions._createBoundingVolumeFunction = function(frameState, geometry) { + createBoundingVolume(that, frameState, geometry); + }; + primitiveOptions._createRenderStatesFunction = function(primitive, context, appearance, twoPasses) { + createRenderStates(that, context); + }; + primitiveOptions._createShaderProgramFunction = function(primitive, frameState, appearance) { + createShaderProgram(that, frameState); + }; + primitiveOptions._createCommandsFunction = function(primitive, appearance, material, translucent, twoPasses, colorCommands, pickCommands) { + createCommands(that, undefined, undefined, true, false, colorCommands, pickCommands); + }; + primitiveOptions._updateAndQueueCommandsFunction = function(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { + updateAndQueueCommands(that, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses); + }; + + this._primitive = new Primitive(primitiveOptions); + this._primitive.readyPromise.then(function(primitive) { + that._ready = true; + + if (that.releaseGeometryInstances) { + that.geometryInstances = undefined; + } + + var error = primitive._error; + if (!defined(error)) { + that._readyPromise.resolve(that); + } else { + that._readyPromise.reject(error); + } + }); + } + + if (this.debugShowShadowVolume && !this._debugShowShadowVolume && this._ready) { + this._debugShowShadowVolume = true; + this._rsStencilPreloadPass = RenderState.fromCache(getStencilPreloadRenderState(false)); + this._rsStencilDepthPass = RenderState.fromCache(getStencilDepthRenderState(false)); + this._rsColorPass = RenderState.fromCache(getColorRenderState(false)); + } else if (!this.debugShowShadowVolume && this._debugShowShadowVolume) { + this._debugShowShadowVolume = false; + this._rsStencilPreloadPass = RenderState.fromCache(getStencilPreloadRenderState(true)); + this._rsStencilDepthPass = RenderState.fromCache(getStencilDepthRenderState(true)); + this._rsColorPass = RenderState.fromCache(getColorRenderState(true)); + } + + this._primitive.debugShowBoundingVolume = this.debugShowBoundingVolume; + this._primitive.update(frameState); + }; + + /** + * @private + */ + ClassificationPrimitive.prototype.getBoundingSphere = function(id) { + var index = this._boundingSpheresKeys.indexOf(id); + if (index !== -1) { + return this._boundingSpheres[index]; + } + + return undefined; + }; + + /** + * Returns the modifiable per-instance attributes for a {@link GeometryInstance}. + * + * @param {Object} id The id of the {@link GeometryInstance}. + * @returns {Object} The typed array in the attribute's format or undefined if the is no instance with id. + * + * @exception {DeveloperError} must call update before calling getGeometryInstanceAttributes. + * + * @example + * var attributes = primitive.getGeometryInstanceAttributes('an id'); + * attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(Cesium.Color.AQUA); + * attributes.show = Cesium.ShowGeometryInstanceAttribute.toValue(true); + */ + ClassificationPrimitive.prototype.getGeometryInstanceAttributes = function(id) { + //>>includeStart('debug', pragmas.debug); + if (!defined(this._primitive)) { + throw new DeveloperError('must call update before calling getGeometryInstanceAttributes'); + } + //>>includeEnd('debug'); + return this._primitive.getGeometryInstanceAttributes(id); + }; + + /** + * Returns true if this object was destroyed; otherwise, false. + *

+ * If this object was destroyed, it should not be used; calling any function other than + * isDestroyed will result in a {@link DeveloperError} exception. + *

+ * + * @returns {Boolean} true if this object was destroyed; otherwise, false. + * + * @see ClassificationPrimitive#destroy + */ + ClassificationPrimitive.prototype.isDestroyed = function() { + return false; + }; + + /** + * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic + * release of WebGL resources, instead of relying on the garbage collector to destroy this object. + *

+ * Once an object is destroyed, it should not be used; calling any function other than + * isDestroyed will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (undefined) to the object as done in the example. + *

+ * + * @returns {undefined} + * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @example + * e = e && e.destroy(); + * + * @see ClassificationPrimitive#isDestroyed + */ + ClassificationPrimitive.prototype.destroy = function() { + this._primitive = this._primitive && this._primitive.destroy(); + this._sp = this._sp && this._sp.destroy(); + this._spPick = this._spPick && this._spPick.destroy(); + return destroyObject(this); + }; + + return ClassificationPrimitive; +}); diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 9c52f0f7c97d..a54894087514 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1910,6 +1910,17 @@ define([ passState.framebuffer = fb; } + us.updatePass(Pass.CESIUM_3D_TILE); + commands = frustumCommands.commands[Pass.CESIUM_3D_TILE]; + length = frustumCommands.indices[Pass.CESIUM_3D_TILE]; + for (j = 0; j < length; ++j) { + executeCommand(commands[j], scene, context, passState); + } + + if (length > 0 && context.stencilBuffer) { + scene._stencilClearCommand.execute(context, passState); + } + us.updatePass(Pass.GROUND); commands = frustumCommands.commands[Pass.GROUND]; length = frustumCommands.indices[Pass.GROUND]; @@ -1929,13 +1940,6 @@ define([ } } - us.updatePass(Pass.CESIUM_3D_TILE); - commands = frustumCommands.commands[Pass.CESIUM_3D_TILE]; - length = frustumCommands.indices[Pass.CESIUM_3D_TILE]; - for (j = 0; j < length; ++j) { - executeCommand(commands[j], scene, context, passState); - } - // Execute commands in order by pass up to the translucent pass. // Translucent geometry needs special handling (sorting/OIT). var startPass = Pass.GROUND + 1; From 9652e9dbbf0d37a9fa52d357378e6777e81c0c65 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 6 Jul 2017 15:40:54 -0400 Subject: [PATCH 004/132] Fix wrong model matrix. --- Apps/Sandcastle/gallery/ClassificationPrimitive.html | 7 ++----- Source/Scene/ClassificationPrimitive.js | 6 +++++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Apps/Sandcastle/gallery/ClassificationPrimitive.html b/Apps/Sandcastle/gallery/ClassificationPrimitive.html index 1c7df51c6d46..4f4eb03ea4e9 100644 --- a/Apps/Sandcastle/gallery/ClassificationPrimitive.html +++ b/Apps/Sandcastle/gallery/ClassificationPrimitive.html @@ -37,7 +37,7 @@ viewer.camera.viewBoundingSphere(boundingSphere, new Cesium.HeadingPitchRange(0.0, -0.5, boundingSphere.radius)); viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); - var dimensions = new Cesium.Cartesian3(400000.0, 300000.0, 500000.0); + var dimensions = new Cesium.Cartesian3(40.0, 30.0, 50.0); var boxModelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(boundingSphere.center); var boxGeometry = Cesium.BoxGeometry.fromDimensions({ vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, @@ -51,10 +51,7 @@ } }); viewer.scene.primitives.add(new Cesium.ClassificationPrimitive({ - geometryInstances : boxGeometryInstance, - appearance : new Cesium.PerInstanceColorAppearance({ - closed: true - }) + geometryInstances : boxGeometryInstance })); }).otherwise(function(error) { throw(error); diff --git a/Source/Scene/ClassificationPrimitive.js b/Source/Scene/ClassificationPrimitive.js index 258a72a1465e..8c143f301abc 100644 --- a/Source/Scene/ClassificationPrimitive.js +++ b/Source/Scene/ClassificationPrimitive.js @@ -1068,6 +1068,7 @@ define([ for (i = 0; i < length; ++i) { instance = instances[i]; + /* geometry = instance.geometry; instanceType = geometry.constructor; groundInstances[i] = new GeometryInstance({ @@ -1078,9 +1079,12 @@ define([ id : instance.id, pickPrimitive : this }); + */ + instance.pickPrimitive = this; } - primitiveOptions.geometryInstances = groundInstances; + //primitiveOptions.geometryInstances = groundInstances; + primitiveOptions.geometryInstances = instances; primitiveOptions._createBoundingVolumeFunction = function(frameState, geometry) { createBoundingVolume(that, frameState, geometry); From 337b33411fd0b7cdec1ad5af8bff6dcd9a1631db Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 6 Jul 2017 16:25:36 -0400 Subject: [PATCH 005/132] Clean up classification primitive, fix rendering artifact and update ground primitive. --- Source/Scene/ClassificationPrimitive.js | 345 ++---------------------- Source/Scene/GroundPrimitive.js | 25 +- Source/Shaders/ShadowVolumeVS.glsl | 9 +- 3 files changed, 44 insertions(+), 335 deletions(-) diff --git a/Source/Scene/ClassificationPrimitive.js b/Source/Scene/ClassificationPrimitive.js index 8c143f301abc..d6005cce739c 100644 --- a/Source/Scene/ClassificationPrimitive.js +++ b/Source/Scene/ClassificationPrimitive.js @@ -69,6 +69,8 @@ define([ StencilOperation) { 'use strict'; + var readOnlyInstanceAttributesScratch = ['color']; + /** * A ground primitive represents geometry draped over the terrain in the {@link Scene}. The geometry must be from a single {@link GeometryInstance}. * Batching multiple geometries is not yet supported. @@ -148,7 +150,6 @@ define([ * @default false */ this.debugShowBoundingVolume = defaultValue(options.debugShowBoundingVolume, false); - /** * This property is for debugging only; it is not for production use nor is it optimized. *

@@ -170,29 +171,11 @@ define([ this._rsColorPass = undefined; this._rsPickPass = undefined; - this._uniformMap = { - u_globeMinimumAltitude: function() { - return 55000.0; - } - }; - - this._boundingVolumes = []; - this._boundingVolumes2D = []; - this._ready = false; this._readyPromise = when.defer(); this._primitive = undefined; - this._maxHeight = undefined; - this._minHeight = undefined; - - this._maxTerrainHeight = ClassificationPrimitive._defaultMaxTerrainHeight; - this._minTerrainHeight = ClassificationPrimitive._defaultMinTerrainHeight; - - this._boundingSpheresKeys = []; - this._boundingSpheres = []; - var appearance = new PerInstanceColorAppearance({ flat : true }); @@ -219,8 +202,6 @@ define([ }; } - var readOnlyInstanceAttributesScratch = ['color']; - defineProperties(ClassificationPrimitive.prototype, { /** * When true, geometry vertices are optimized for the pre and post-vertex-shader caches. @@ -357,26 +338,6 @@ define([ return scene.context.stencilBuffer; }; - ClassificationPrimitive._defaultMaxTerrainHeight = 9000.0; - ClassificationPrimitive._defaultMinTerrainHeight = -100000.0; - - ClassificationPrimitive._terrainHeights = undefined; - ClassificationPrimitive._terrainHeightsMaxLevel = 6; - - function getComputeMaximumHeightFunction(primitive) { - return function(granularity, ellipsoid) { - var r = ellipsoid.maximumRadius; - var delta = (r / Math.cos(granularity * 0.5)) - r; - return primitive._maxHeight + delta; - }; - } - - function getComputeMinimumHeightFunction(primitive) { - return function(granularity, ellipsoid) { - return primitive._minHeight; - }; - } - function getStencilPreloadRenderState(enableStencil) { return { colorMask : { @@ -494,188 +455,6 @@ define([ depthMask : false }; - var scratchBVCartesianHigh = new Cartesian3(); - var scratchBVCartesianLow = new Cartesian3(); - var scratchBVCartesian = new Cartesian3(); - var scratchBVCartographic = new Cartographic(); - var scratchBVRectangle = new Rectangle(); - var tilingScheme = new GeographicTilingScheme(); - var scratchCorners = [new Cartographic(), new Cartographic(), new Cartographic(), new Cartographic()]; - var scratchTileXY = new Cartesian2(); - - function getRectangle(frameState, geometry) { - var ellipsoid = frameState.mapProjection.ellipsoid; - - if (!defined(geometry.attributes) || !defined(geometry.attributes.position3DHigh)) { - if (defined(geometry.rectangle)) { - return geometry.rectangle; - } - - return undefined; - } - - var highPositions = geometry.attributes.position3DHigh.values; - var lowPositions = geometry.attributes.position3DLow.values; - var length = highPositions.length; - - var minLat = Number.POSITIVE_INFINITY; - var minLon = Number.POSITIVE_INFINITY; - var maxLat = Number.NEGATIVE_INFINITY; - var maxLon = Number.NEGATIVE_INFINITY; - - for (var i = 0; i < length; i +=3) { - var highPosition = Cartesian3.unpack(highPositions, i, scratchBVCartesianHigh); - var lowPosition = Cartesian3.unpack(lowPositions, i, scratchBVCartesianLow); - - var position = Cartesian3.add(highPosition, lowPosition, scratchBVCartesian); - var cartographic = ellipsoid.cartesianToCartographic(position, scratchBVCartographic); - - var latitude = cartographic.latitude; - var longitude = cartographic.longitude; - - minLat = Math.min(minLat, latitude); - minLon = Math.min(minLon, longitude); - maxLat = Math.max(maxLat, latitude); - maxLon = Math.max(maxLon, longitude); - } - - var rectangle = scratchBVRectangle; - rectangle.north = maxLat; - rectangle.south = minLat; - rectangle.east = maxLon; - rectangle.west = minLon; - - return rectangle; - } - - var scratchDiagonalCartesianNE = new Cartesian3(); - var scratchDiagonalCartesianSW = new Cartesian3(); - var scratchDiagonalCartographic = new Cartographic(); - var scratchCenterCartesian = new Cartesian3(); - var scratchSurfaceCartesian = new Cartesian3(); - - function getTileXYLevel(rectangle) { - Cartographic.fromRadians(rectangle.east, rectangle.north, 0.0, scratchCorners[0]); - Cartographic.fromRadians(rectangle.west, rectangle.north, 0.0, scratchCorners[1]); - Cartographic.fromRadians(rectangle.east, rectangle.south, 0.0, scratchCorners[2]); - Cartographic.fromRadians(rectangle.west, rectangle.south, 0.0, scratchCorners[3]); - - // Determine which tile the bounding rectangle is in - var lastLevelX = 0, lastLevelY = 0; - var currentX = 0, currentY = 0; - var maxLevel = ClassificationPrimitive._terrainHeightsMaxLevel; - for(var i = 0; i <= maxLevel; ++i) { - var failed = false; - for(var j = 0; j < 4; ++j) { - var corner = scratchCorners[j]; - tilingScheme.positionToTileXY(corner, i, scratchTileXY); - if (j === 0) { - currentX = scratchTileXY.x; - currentY = scratchTileXY.y; - } else if(currentX !== scratchTileXY.x || currentY !== scratchTileXY.y) { - failed = true; - break; - } - } - - if (failed) { - break; - } - - lastLevelX = currentX; - lastLevelY = currentY; - } - - if (i === 0) { - return undefined; - } - - return { - x : lastLevelX, - y : lastLevelY, - level : (i > maxLevel) ? maxLevel : (i - 1) - }; - } - - function setMinMaxTerrainHeights(primitive, rectangle, ellipsoid) { - var xyLevel = getTileXYLevel(rectangle); - - // Get the terrain min/max for that tile - var minTerrainHeight = ClassificationPrimitive._defaultMinTerrainHeight; - var maxTerrainHeight = ClassificationPrimitive._defaultMaxTerrainHeight; - if (defined(xyLevel)) { - var key = xyLevel.level + '-' + xyLevel.x + '-' + xyLevel.y; - var heights = ClassificationPrimitive._terrainHeights[key]; - if (defined(heights)) { - minTerrainHeight = heights[0]; - maxTerrainHeight = heights[1]; - } - - // Compute min by taking the center of the NE->SW diagonal and finding distance to the surface - ellipsoid.cartographicToCartesian(Rectangle.northeast(rectangle, scratchDiagonalCartographic), - scratchDiagonalCartesianNE); - ellipsoid.cartographicToCartesian(Rectangle.southwest(rectangle, scratchDiagonalCartographic), - scratchDiagonalCartesianSW); - - Cartesian3.subtract(scratchDiagonalCartesianSW, scratchDiagonalCartesianNE, scratchCenterCartesian); - Cartesian3.add(scratchDiagonalCartesianNE, - Cartesian3.multiplyByScalar(scratchCenterCartesian, 0.5, scratchCenterCartesian), scratchCenterCartesian); - var surfacePosition = ellipsoid.scaleToGeodeticSurface(scratchCenterCartesian, scratchSurfaceCartesian); - if (defined(surfacePosition)) { - var distance = Cartesian3.distance(scratchCenterCartesian, surfacePosition); - minTerrainHeight = Math.min(minTerrainHeight, -distance); - } else { - minTerrainHeight = ClassificationPrimitive._defaultMinTerrainHeight; - } - } - - primitive._minTerrainHeight = Math.max(ClassificationPrimitive._defaultMinTerrainHeight, minTerrainHeight); - primitive._maxTerrainHeight = maxTerrainHeight; - } - - var scratchBoundingSphere = new BoundingSphere(); - function getInstanceBoundingSphere(rectangle, ellipsoid) { - var xyLevel = getTileXYLevel(rectangle); - - // Get the terrain max for that tile - var maxTerrainHeight = ClassificationPrimitive._defaultMaxTerrainHeight; - if (defined(xyLevel)) { - var key = xyLevel.level + '-' + xyLevel.x + '-' + xyLevel.y; - var heights = ClassificationPrimitive._terrainHeights[key]; - if (defined(heights)) { - maxTerrainHeight = heights[1]; - } - } - - var result = BoundingSphere.fromRectangle3D(rectangle, ellipsoid, 0.0); - BoundingSphere.fromRectangle3D(rectangle, ellipsoid, maxTerrainHeight, scratchBoundingSphere); - - return BoundingSphere.union(result, scratchBoundingSphere, result); - } - - function createBoundingVolume(groundPrimitive, frameState, geometry) { - var ellipsoid = frameState.mapProjection.ellipsoid; - var rectangle = getRectangle(frameState, geometry); - - // Use an oriented bounding box by default, but switch to a bounding sphere if bounding box creation would fail. - if (rectangle.width < CesiumMath.PI) { - var obb = OrientedBoundingBox.fromRectangle(rectangle, groundPrimitive._maxHeight, groundPrimitive._minHeight, ellipsoid); - groundPrimitive._boundingVolumes.push(obb); - } else { - var highPositions = geometry.attributes.position3DHigh.values; - var lowPositions = geometry.attributes.position3DLow.values; - groundPrimitive._boundingVolumes.push(BoundingSphere.fromEncodedCartesianVertices(highPositions, lowPositions)); - } - - if (!frameState.scene3DOnly) { - var projection = frameState.mapProjection; - var boundingVolume = BoundingSphere.fromRectangleWithHeights2D(rectangle, projection, groundPrimitive._maxHeight, groundPrimitive._minHeight); - Cartesian3.fromElements(boundingVolume.center.z, boundingVolume.center.x, boundingVolume.center.y, boundingVolume.center); - - groundPrimitive._boundingVolumes2D.push(boundingVolume); - } - } - function createRenderStates(groundPrimitive, context, appearance, twoPasses) { if (defined(groundPrimitive._rsStencilPreloadPass)) { return; @@ -773,7 +552,7 @@ define([ colorCommands.length = length; var vaIndex = 0; - var uniformMap = primitive._batchTable.getUniformMapCallback()(groundPrimitive._uniformMap); + var uniformMap = primitive._batchTable.getUniformMapCallback()(); for (var i = 0; i < length; i += 3) { var vertexArray = primitive._va[vaIndex++]; @@ -832,7 +611,7 @@ define([ pickCommands.length = length; var pickIndex = 0; - var uniformMap = primitive._batchTable.getUniformMapCallback()(groundPrimitive._uniformMap); + var uniformMap = primitive._batchTable.getUniformMapCallback()(); for (var j = 0; j < length; j += 3) { var pickOffset = pickOffsets[pickIndex++]; @@ -949,30 +728,6 @@ define([ } } - ClassificationPrimitive._initialized = false; - ClassificationPrimitive._initPromise = undefined; - - /** - * Initializes the minimum and maximum terrain heights. This only needs to be called if you are creating the - * ClassificationPrimitive synchronously. - * - * @returns {Promise} A promise that will resolve once the terrain heights have been loaded. - * - */ - ClassificationPrimitive.initializeTerrainHeights = function() { - var initPromise = ClassificationPrimitive._initPromise; - if (defined(initPromise)) { - return initPromise; - } - - ClassificationPrimitive._initPromise = loadJson(buildModuleUrl('Assets/approximateTerrainHeights.json')).then(function(json) { - ClassificationPrimitive._initialized = true; - ClassificationPrimitive._terrainHeights = json; - }); - - return ClassificationPrimitive._initPromise; - }; - /** * Called when {@link Viewer} or {@link CesiumWidget} render the scene to * get the draw commands needed to render this primitive. @@ -990,105 +745,39 @@ define([ return; } - if (!ClassificationPrimitive._initialized) { - //>>includeStart('debug', pragmas.debug); - if (!this.asynchronous) { - throw new DeveloperError('For synchronous ClassificationPrimitives, you must call ClassificationPrimitive.initializeTerrainHeights() and wait for the returned promise to resolve.'); - } - //>>includeEnd('debug'); - - ClassificationPrimitive.initializeTerrainHeights(); - return; - } - var that = this; var primitiveOptions = this._primitiveOptions; if (!defined(this._primitive)) { - var ellipsoid = frameState.mapProjection.ellipsoid; - - var instance; - var geometry; - var instanceType; - var instances = isArray(this.geometryInstances) ? this.geometryInstances : [this.geometryInstances]; var length = instances.length; - var groundInstances = new Array(length); var i; + var instance; + //>>includeStart('debug', pragmas.debug); var color; - var rectangle; for (i = 0; i < length; ++i) { instance = instances[i]; - geometry = instance.geometry; - var instanceRectangle = getRectangle(frameState, geometry); - if (!defined(rectangle)) { - rectangle = instanceRectangle; - } else { - if (defined(instanceRectangle)) { - Rectangle.union(rectangle, instanceRectangle, rectangle); - } - } - - var id = instance.id; - if (defined(id) && defined(instanceRectangle)) { - var boundingSphere = getInstanceBoundingSphere(instanceRectangle, ellipsoid); - this._boundingSpheresKeys.push(id); - this._boundingSpheres.push(boundingSphere); - } - - instanceType = geometry.constructor; - if (defined(instanceType)/* && defined(instanceType.createShadowVolume)*/) { - var attributes = instance.attributes; - - //>>includeStart('debug', pragmas.debug); - if (!defined(attributes) || !defined(attributes.color)) { - throw new DeveloperError('Not all of the geometry instances have the same color attribute.'); - } else if (defined(color) && !ColorGeometryInstanceAttribute.equals(color, attributes.color)) { - throw new DeveloperError('Not all of the geometry instances have the same color attribute.'); - } else if (!defined(color)) { - color = attributes.color; - } - //>>includeEnd('debug'); - } else { - //>>includeStart('debug', pragmas.debug); - throw new DeveloperError('Not all of the geometry instances have ClassificationPrimitive support.'); - //>>includeEnd('debug'); + var attributes = instance.attributes; + if (!defined(attributes) || !defined(attributes.color)) { + throw new DeveloperError('Not all of the geometry instances have the same color attribute.'); + } else if (defined(color) && !ColorGeometryInstanceAttribute.equals(color, attributes.color)) { + throw new DeveloperError('Not all of the geometry instances have the same color attribute.'); + } else if (!defined(color)) { + color = attributes.color; } } - - // Now compute the min/max heights for the primitive - //setMinMaxTerrainHeights(this, rectangle, frameState.mapProjection.ellipsoid); - //var exaggeration = frameState.terrainExaggeration; - //this._minHeight = this._minTerrainHeight * exaggeration; - //this._maxHeight = this._maxTerrainHeight * exaggeration; - - this._minHeight = ClassificationPrimitive._defaultMaxTerrainHeight; - this._maxHeight = ClassificationPrimitive._defaultMinTerrainHeight; + //>>includeEnd('debug'); for (i = 0; i < length; ++i) { instance = instances[i]; - /* - geometry = instance.geometry; - instanceType = geometry.constructor; - groundInstances[i] = new GeometryInstance({ - //geometry : instanceType.createShadowVolume(geometry, getComputeMinimumHeightFunction(this), - // getComputeMaximumHeightFunction(this)), - geometry : geometry, - attributes : instance.attributes, - id : instance.id, - pickPrimitive : this - }); - */ + + // TODO: clone instances instance.pickPrimitive = this; } - //primitiveOptions.geometryInstances = groundInstances; primitiveOptions.geometryInstances = instances; - primitiveOptions._createBoundingVolumeFunction = function(frameState, geometry) { - createBoundingVolume(that, frameState, geometry); - }; primitiveOptions._createRenderStatesFunction = function(primitive, context, appearance, twoPasses) { createRenderStates(that, context); }; @@ -1138,6 +827,7 @@ define([ /** * @private */ + /* ClassificationPrimitive.prototype.getBoundingSphere = function(id) { var index = this._boundingSpheresKeys.indexOf(id); if (index !== -1) { @@ -1146,6 +836,7 @@ define([ return undefined; }; + */ /** * Returns the modifiable per-instance attributes for a {@link GeometryInstance}. diff --git a/Source/Scene/GroundPrimitive.js b/Source/Scene/GroundPrimitive.js index 6deff85dbfad..56427a4ab401 100644 --- a/Source/Scene/GroundPrimitive.js +++ b/Source/Scene/GroundPrimitive.js @@ -68,6 +68,8 @@ define([ StencilOperation) { 'use strict'; + var readOnlyInstanceAttributesScratch = ['color']; + /** * A ground primitive represents geometry draped over the terrain in the {@link Scene}. The geometry must be from a single {@link GeometryInstance}. * Batching multiple geometries is not yet supported. @@ -238,8 +240,6 @@ define([ }); var readOnlyAttributes; - var readOnlyInstanceAttributesScratch = ['color']; - if (defined(this.geometryInstances) && isArray(this.geometryInstances) && this.geometryInstances.length > 1) { readOnlyAttributes = readOnlyInstanceAttributesScratch; } @@ -772,14 +772,20 @@ define([ vs = Primitive._updateColorAttribute(primitive, vs); vs = modifyForEncodedNormals(primitive, vs); - var fs = ShadowVolumeFS; + var vsSource = new ShaderSource({ + defines : ['EXTRUDED_GEOMETRY'], + sources : [vs] + }); + var fsSource = new ShaderSource({ + sources : [ShadowVolumeFS] + }); var attributeLocations = groundPrimitive._primitive._attributeLocations; groundPrimitive._sp = ShaderProgram.replaceCache({ context : context, shaderProgram : groundPrimitive._sp, - vertexShaderSource : vs, - fragmentShaderSource : fs, + vertexShaderSource : vsSource, + fragmentShaderSource : fsSource, attributeLocations : attributeLocations }); @@ -787,14 +793,19 @@ define([ var vsPick = ShaderSource.createPickVertexShaderSource(vs); vsPick = Primitive._updatePickColorAttribute(vsPick); + var pickVS = new ShaderSource({ + defines : ['EXTRUDED_GEOMETRY'], + sources : [vsPick] + }); + var pickFS = new ShaderSource({ - sources : [fs], + sources : [ShadowVolumeFS], pickColorQualifier : 'varying' }); groundPrimitive._spPick = ShaderProgram.replaceCache({ context : context, shaderProgram : groundPrimitive._spPick, - vertexShaderSource : vsPick, + vertexShaderSource : pickVS, fragmentShaderSource : pickFS, attributeLocations : attributeLocations }); diff --git a/Source/Shaders/ShadowVolumeVS.glsl b/Source/Shaders/ShadowVolumeVS.glsl index 809cf0be80a3..a85fc04a548e 100644 --- a/Source/Shaders/ShadowVolumeVS.glsl +++ b/Source/Shaders/ShadowVolumeVS.glsl @@ -1,10 +1,13 @@ attribute vec3 position3DHigh; attribute vec3 position3DLow; -attribute vec3 extrudeDirection; attribute vec4 color; attribute float batchId; +#ifdef EXTRUDED_GEOMETRY +attribute vec3 extrudeDirection; + uniform float u_globeMinimumAltitude; +#endif // emulated noperspective varying float v_WindowZ; @@ -22,10 +25,14 @@ void main() v_color = color; vec4 position = czm_computePosition(); + +#ifdef EXTRUDED_GEOMETRY float delta = min(u_globeMinimumAltitude, czm_geometricToleranceOverMeter * length(position.xyz)); delta *= czm_sceneMode == czm_sceneMode3D ? 1.0 : 0.0; //extrudeDirection is zero for the top layer position = position + vec4(extrudeDirection * delta, 0.0); +#endif + gl_Position = depthClampFarPlane(czm_modelViewProjectionRelativeToEye * position); } From 2cfa4a5b54138fc48b653bee658ba3bf26a91c7e Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 6 Jul 2017 19:54:39 -0400 Subject: [PATCH 006/132] Fix picking classification primitives and update Sandcastle example. --- .../gallery/ClassificationPrimitive.html | 28 ++++- Source/Scene/Batched3DModel3DTileContent.js | 3 + Source/Scene/Cesium3DTileBatchTable.js | 4 - Source/Scene/ClassificationPrimitive.js | 115 ++++++------------ Source/Scene/GroundPrimitive.js | 4 +- Source/Scene/Instanced3DModel3DTileContent.js | 5 +- Source/Scene/Model.js | 10 +- Source/Scene/ModelInstanceCollection.js | 10 +- 8 files changed, 89 insertions(+), 90 deletions(-) diff --git a/Apps/Sandcastle/gallery/ClassificationPrimitive.html b/Apps/Sandcastle/gallery/ClassificationPrimitive.html index 4f4eb03ea4e9..bee4474bad45 100644 --- a/Apps/Sandcastle/gallery/ClassificationPrimitive.html +++ b/Apps/Sandcastle/gallery/ClassificationPrimitive.html @@ -27,6 +27,8 @@ 'use strict'; //Sandcastle_Begin var viewer = new Cesium.Viewer('cesiumContainer'); +var scene = viewer.scene; +var camera = scene.camera; var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({ url : 'https://beta.cesium.com/api/assets/1458?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxYmJiNTAxOC1lOTg5LTQzN2EtODg1OC0zMWJjM2IxNGNlYmMiLCJpZCI6NDQsImFzc2V0cyI6WzE0NThdLCJpYXQiOjE0OTkyNjM4MjB9.1WKijRa-ILkmG6utrhDWX6rDgasjD7dZv-G5ZyCmkKg' @@ -34,8 +36,8 @@ tileset.readyPromise.then(function() { var boundingSphere = tileset.boundingSphere; - viewer.camera.viewBoundingSphere(boundingSphere, new Cesium.HeadingPitchRange(0.0, -0.5, boundingSphere.radius)); - viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); + camera.viewBoundingSphere(boundingSphere, new Cesium.HeadingPitchRange(0.0, -0.5, boundingSphere.radius)); + camera.lookAtTransform(Cesium.Matrix4.IDENTITY); var dimensions = new Cesium.Cartesian3(40.0, 30.0, 50.0); var boxModelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(boundingSphere.center); @@ -48,14 +50,32 @@ modelMatrix : boxModelMatrix, attributes : { color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 0.0, 0.5)) - } + }, + id : 'box volume' }); - viewer.scene.primitives.add(new Cesium.ClassificationPrimitive({ + scene.primitives.add(new Cesium.ClassificationPrimitive({ geometryInstances : boxGeometryInstance })); }).otherwise(function(error) { throw(error); }); + +var currentObjectId; +var currentPrimitive; + +var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); +handler.setInputAction(function(movement) { + var pickedObject = scene.pick(movement.endPosition); + if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.primitive) && Cesium.defined(pickedObject.id) && Cesium.defined(pickedObject.primitive.getGeometryInstanceAttributes)) { + currentObjectId = pickedObject.id; + currentPrimitive = pickedObject.primitive; + currentPrimitive.getGeometryInstanceAttributes(currentObjectId).color = [255, 0, 255, 128]; + } else if (Cesium.defined(currentObjectId)) { + currentPrimitive.getGeometryInstanceAttributes(currentObjectId).color = [255, 0, 0, 128]; + currentObjectId = undefined; + currentPrimitive = undefined; + } +}, Cesium.ScreenSpaceEventType.MOUSE_MOVE); //Sandcastle_End Sandcastle.finishedLoading(); } diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index fd2a50198a5f..0bcd5f7e3181 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -13,6 +13,7 @@ define([ '../Core/getStringFromTypedArray', '../Core/RequestType', '../Core/RuntimeError', + '../Renderer/Pass', './Cesium3DTileBatchTable', './Cesium3DTileFeature', './Cesium3DTileFeatureTable', @@ -33,6 +34,7 @@ define([ getStringFromTypedArray, RequestType, RuntimeError, + Pass, Cesium3DTileBatchTable, Cesium3DTileFeature, Cesium3DTileFeatureTable, @@ -352,6 +354,7 @@ define([ gltf : gltfView, cull : false, // The model is already culled by 3D Tiles releaseGltfJson : true, // Models are unique and will not benefit from caching so save memory + opaquePass : Pass.CESIUM_3D_TILE, // Draw opaque portions of the model during the 3D Tiles pass basePath : basePath, requestType : RequestType.TILES3D, modelMatrix : tile.computedTransform, diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index 79401ae40314..7526fe2cbdf0 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -1305,10 +1305,6 @@ define([ // even though their style is opaque. var translucentCommand = (derivedCommand.pass === Pass.TRANSLUCENT); - if (!translucentCommand) { - derivedCommand.pass = Pass.CESIUM_3D_TILE; - } - derivedCommand.uniformMap = defined(derivedCommand.uniformMap) ? derivedCommand.uniformMap : {}; derivedCommand.uniformMap.tile_translucentCommand = function() { return translucentCommand; diff --git a/Source/Scene/ClassificationPrimitive.js b/Source/Scene/ClassificationPrimitive.js index d6005cce739c..e1319a78f5f6 100644 --- a/Source/Scene/ClassificationPrimitive.js +++ b/Source/Scene/ClassificationPrimitive.js @@ -72,7 +72,7 @@ define([ var readOnlyInstanceAttributesScratch = ['color']; /** - * A ground primitive represents geometry draped over the terrain in the {@link Scene}. The geometry must be from a single {@link GeometryInstance}. + * A classification primitive represents a volume enclosing geometry in the {@link Scene} to be highlighted. The geometry must be from a single {@link GeometryInstance}. * Batching multiple geometries is not yet supported. *

* A primitive combines the geometry instance with an {@link Appearance} that describes the full shading, including @@ -86,7 +86,11 @@ define([ * will be rendering artifacts for some viewing angles. *

*

- * Valid geometries are {@link CircleGeometry}, {@link CorridorGeometry}, {@link EllipseGeometry}, {@link PolygonGeometry}, and {@link RectangleGeometry}. + * Valid geometries are {@link BoxGeometry}, {@link CylinderGeometry}, {@link EllipsoidGeometry}, {@link PolylineVolumeGeometry}, and {@link SphereGeometry}. + *

+ *

+ * Geometries that follow the surface of the ellipsoid, such as {@link CircleGeometry}, {@link CorridorGeometry}, {@link EllipseGeometry}, {@link PolygonGeometry}, and {@link RectangleGeometry}, + * are also valid if they are extruded volumes; otherwise, they will not be rendered. *

* * @alias ClassificationPrimitive @@ -106,6 +110,7 @@ define([ * creation for the volumes to be created before the geometry is released or options.releaseGeometryInstance must be false. * * @see Primitive + * @see GroundPrimitive * @see GeometryInstance * @see Appearance */ @@ -175,6 +180,7 @@ define([ this._readyPromise = when.defer(); this._primitive = undefined; + this._pickPrimitive = options.pickPrimitive; var appearance = new PerInstanceColorAppearance({ flat : true @@ -467,34 +473,6 @@ define([ groundPrimitive._rsPickPass = RenderState.fromCache(pickRenderState); } - function modifyForEncodedNormals(primitive, vertexShaderSource) { - if (!primitive.compressVertices) { - return vertexShaderSource; - } - - if (vertexShaderSource.search(/attribute\s+vec3\s+extrudeDirection;/g) !== -1) { - var attributeName = 'compressedAttributes'; - - //only shadow volumes use extrudeDirection, and shadow volumes use vertexFormat: POSITION_ONLY so we don't need to check other attributes - var attributeDecl = 'attribute vec2 ' + attributeName + ';'; - - var globalDecl = 'vec3 extrudeDirection;\n'; - var decode = ' extrudeDirection = czm_octDecode(' + attributeName + ', 65535.0);\n'; - - var modifiedVS = vertexShaderSource; - modifiedVS = modifiedVS.replace(/attribute\s+vec3\s+extrudeDirection;/g, ''); - modifiedVS = ShaderSource.replaceMain(modifiedVS, 'czm_non_compressed_main'); - var compressedMain = - 'void main() \n' + - '{ \n' + - decode + - ' czm_non_compressed_main(); \n' + - '}'; - - return [attributeDecl, globalDecl, modifiedVS, compressedMain].join('\n'); - } - } - function createShaderProgram(groundPrimitive, frameState, appearance) { if (defined(groundPrimitive._sp)) { return; @@ -508,7 +486,6 @@ define([ vs = Primitive._appendDistanceDisplayConditionToShader(primitive, vs); vs = Primitive._modifyShaderPosition(groundPrimitive, vs, frameState.scene3DOnly); vs = Primitive._updateColorAttribute(primitive, vs); - vs = modifyForEncodedNormals(primitive, vs); var fs = ShadowVolumeFS; var attributeLocations = groundPrimitive._primitive._attributeLocations; @@ -680,50 +657,47 @@ define([ function updateAndQueueCommands(groundPrimitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { var boundingVolumes; + var primitive = groundPrimitive._primitive; if (frameState.mode === SceneMode.SCENE3D) { - boundingVolumes = groundPrimitive._boundingVolumes; - } else if (frameState.mode !== SceneMode.SCENE3D && defined(groundPrimitive._boundingVolumes2D)) { - boundingVolumes = groundPrimitive._boundingVolumes2D; + boundingVolumes = primitive._boundingSphereWC; + } else if (frameState.mode === SceneMode.COLUMBUS_VIEW) { + boundingVolumes = primitive._boundingSphereCV; + } else if (frameState.mode === SceneMode.SCENE2D && defined(primitive._boundingSphere2D)) { + boundingVolumes = primitive._boundingSphere2D; + } else if (defined(primitive._boundingSphereMorph)) { + boundingVolumes = primitive._boundingSphereMorph; } var commandList = frameState.commandList; var passes = frameState.passes; if (passes.render) { var colorLength = colorCommands.length; - for (var j = 0; j < colorLength; ++j) { - colorCommands[j].modelMatrix = modelMatrix; - colorCommands[j].boundingVolume = undefined;//boundingVolumes[Math.floor(j / 3)]; - colorCommands[j].cull = cull; - colorCommands[j].debugShowBoundingVolume = debugShowBoundingVolume; - - commandList.push(colorCommands[j]); + for (var i = 0; i < colorLength; ++i) { + var colorCommand = colorCommands[i]; + colorCommand.modelMatrix = modelMatrix; + colorCommand.boundingVolume = undefined;//boundingVolumes[Math.floor(i / 3)]; + colorCommand.cull = cull; + colorCommand.debugShowBoundingVolume = debugShowBoundingVolume; + + commandList.push(colorCommand); } } if (passes.pick) { - var primitive = groundPrimitive._primitive; var pickOffsets = primitive._pickOffsets; var length = pickOffsets.length * 3; pickCommands.length = length; - var pickIndex = 0; - for (var k = 0; k < length; k += 3) { - var pickOffset = pickOffsets[pickIndex++]; + for (var j = 0; j < length; ++j) { + var pickOffset = pickOffsets[Math.floor(j / 3)]; var bv = boundingVolumes[pickOffset.index]; - pickCommands[k].modelMatrix = modelMatrix; - pickCommands[k].boundingVolume = bv; - pickCommands[k].cull = cull; - - pickCommands[k + 1].modelMatrix = modelMatrix; - pickCommands[k + 1].boundingVolume = bv; - pickCommands[k + 1].cull = cull; - - pickCommands[k + 2].modelMatrix = modelMatrix; - pickCommands[k + 2].boundingVolume = bv; - pickCommands[k + 2].cull = cull; + var pickCommand = pickCommands[j]; + pickCommand.modelMatrix = modelMatrix; + pickCommand.boundingVolume = undefined;//bv; + pickCommand.cull = cull; - commandList.push(pickCommands[k], pickCommands[k + 1], pickCommands[k + 2]); + commandList.push(pickCommand); } } } @@ -769,14 +743,19 @@ define([ } //>>includeEnd('debug'); + var geometryInstances = new Array(length); for (i = 0; i < length; ++i) { instance = instances[i]; - - // TODO: clone instances - instance.pickPrimitive = this; + geometryInstances[i] = new GeometryInstance({ + geometry : instance.geometry, + attributes : instance.attributes, + modelMatrix : instance.modelMatrix, + id : instance.id, + pickPrimitive : defaultValue(this._pickPrimitive, that) + }); } - primitiveOptions.geometryInstances = instances; + primitiveOptions.geometryInstances = geometryInstances; primitiveOptions._createRenderStatesFunction = function(primitive, context, appearance, twoPasses) { createRenderStates(that, context); @@ -824,20 +803,6 @@ define([ this._primitive.update(frameState); }; - /** - * @private - */ - /* - ClassificationPrimitive.prototype.getBoundingSphere = function(id) { - var index = this._boundingSpheresKeys.indexOf(id); - if (index !== -1) { - return this._boundingSpheres[index]; - } - - return undefined; - }; - */ - /** * Returns the modifiable per-instance attributes for a {@link GeometryInstance}. * diff --git a/Source/Scene/GroundPrimitive.js b/Source/Scene/GroundPrimitive.js index 56427a4ab401..de1327c1e2cc 100644 --- a/Source/Scene/GroundPrimitive.js +++ b/Source/Scene/GroundPrimitive.js @@ -812,8 +812,8 @@ define([ } else { groundPrimitive._spPick = ShaderProgram.fromCache({ context : context, - vertexShaderSource : vs, - fragmentShaderSource : fs, + vertexShaderSource : vsSource, + fragmentShaderSource : fsSource, attributeLocations : attributeLocations }); } diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index df1de7ca0593..8eeaac92317e 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -21,6 +21,7 @@ define([ '../Core/RuntimeError', '../Core/Transforms', '../Core/TranslationRotationScale', + '../Renderer/Pass', './Cesium3DTileBatchTable', './Cesium3DTileFeature', './Cesium3DTileFeatureTable', @@ -48,6 +49,7 @@ define([ RuntimeError, Transforms, TranslationRotationScale, + Pass, Cesium3DTileBatchTable, Cesium3DTileFeature, Cesium3DTileFeatureTable, @@ -303,7 +305,8 @@ define([ gltf : undefined, basePath : undefined, incrementallyLoadTextures : false, - upAxis : content._tileset._gltfUpAxis + upAxis : content._tileset._gltfUpAxis, + opaquePass : Pass.CESIUM_3D_TILE // Draw opaque portions during the 3D Tiles pass }; if (gltfFormat === 0) { diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 0759964059f3..f2791138c8d1 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -644,6 +644,12 @@ define([ */ this.cull = defaultValue(options.cull, true); + /** + * @private + * @readonly + */ + this.opaquePass = defaultValue(options.opaquePass, Pass.OPAQUE); + this._computedModelMatrix = new Matrix4(); // Derived from modelMatrix and scale this._initialRadius = undefined; // Radius without model's scale property, model-matrix scale, animations, or skins this._boundingSphere = undefined; @@ -3483,7 +3489,7 @@ define([ uniformMap : uniformMap, renderState : rs, owner : owner, - pass : isTranslucent ? Pass.TRANSLUCENT : Pass.OPAQUE + pass : isTranslucent ? Pass.TRANSLUCENT : model.opaquePass }); var pickCommand; @@ -3522,7 +3528,7 @@ define([ uniformMap : pickUniformMap, renderState : rs, owner : owner, - pass : isTranslucent ? Pass.TRANSLUCENT : Pass.OPAQUE + pass : isTranslucent ? Pass.TRANSLUCENT : model.opaquePass }); } diff --git a/Source/Scene/ModelInstanceCollection.js b/Source/Scene/ModelInstanceCollection.js index 86f7586b6b50..514e34323921 100644 --- a/Source/Scene/ModelInstanceCollection.js +++ b/Source/Scene/ModelInstanceCollection.js @@ -16,6 +16,7 @@ define([ '../Renderer/Buffer', '../Renderer/BufferUsage', '../Renderer/DrawCommand', + '../Renderer/Pass', '../Renderer/ShaderSource', '../ThirdParty/when', './getAttributeOrUniformBySemantic', @@ -41,6 +42,7 @@ define([ Buffer, BufferUsage, DrawCommand, + Pass, ShaderSource, when, getAttributeOrUniformBySemantic, @@ -107,12 +109,15 @@ define([ this._instancingSupported = false; this._dynamic = defaultValue(options.dynamic, false); this._allowPicking = defaultValue(options.allowPicking, true); - this._cull = defaultValue(options.cull, true); // Undocumented option this._ready = false; this._readyPromise = when.defer(); this._state = LoadState.NEEDS_LOAD; this._dirty = false; + // Undocumented options + this._cull = defaultValue(options.cull, true); + this._opaquePass = defaultValue(options.opaquePass, Pass.OPAQUE); + this._instances = createInstances(this, options.instances); // When the model instance collection is backed by an i3dm tile, @@ -603,7 +608,8 @@ define([ pickVertexShaderLoaded : undefined, pickFragmentShaderLoaded : undefined, pickUniformMapLoaded : undefined, - ignoreCommands : true + ignoreCommands : true, + opaquePass : collection._opaquePass }; if (allowPicking && !usesBatchTable) { From 4d54231b5d16eb455cf800aa7c7ee672210e97e2 Mon Sep 17 00:00:00 2001 From: Heiko Thiel Date: Tue, 11 Jul 2017 14:59:20 +0200 Subject: [PATCH 007/132] Adjust documentation --- Source/Scene/Cesium3DTileStyle.js | 82 ++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 17 deletions(-) diff --git a/Source/Scene/Cesium3DTileStyle.js b/Source/Scene/Cesium3DTileStyle.js index 52af95145538..ee7fb02aae85 100644 --- a/Source/Scene/Cesium3DTileStyle.js +++ b/Source/Scene/Cesium3DTileStyle.js @@ -209,7 +209,7 @@ define([ }, /** - * Gets or sets the {@link StyleExpression} object used to evaluate the style's show property. Alternative an object defining a show style can be used. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's show property. Alternatively a boolean, string, or object defining a show style can be used. *

* The expression must return or convert to a Boolean. *

@@ -234,7 +234,29 @@ define([ * return true; * } * }; - */ + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override show expression with a boolean + * style.show = true; + * }; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override show expression with a string + * style.show = '${Height} > 0'; + * }; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override show expression with a condition + * style.show = { + * conditions: [ + * ['${height} > 2', 'false'], + * ['true', 'true'] + * ]; + * }; + */ show : { get : function() { //>>includeStart('debug', pragmas.debug); @@ -252,18 +274,15 @@ define([ this._show = new Expression(value); } else if (defined(value.conditions)) { this._show = new ConditionsExpression(value); - } else if (defined(value.expression) || defined(value.conditionsExpression)) { - this._show = value; } else { - this._show = undefined; - return; + this._show = value; } this._showShaderFunctionReady = false; } }, /** - * Gets or sets the {@link StyleExpression} object used to evaluate the style's color property. Alternative an object defining a color style can be used. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's color property. Alternatively a string or object defining a color style can be used. *

* The expression must return a Color. *

@@ -288,6 +307,21 @@ define([ * return Cesium.Color.clone(Cesium.Color.WHITE, result); * } * }; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override color expression with a string + * style.color = 'color("blue")'; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override color expression with a condition + * style.color = { + * conditions : [ + * ['${height} > 2', 'color("cyan")'], + * ['true', 'color("blue")'] + * ] + * }; */ color : { get : function() { @@ -304,18 +338,15 @@ define([ this._color = new Expression(value); } else if (defined(value.conditions)) { this._color = new ConditionsExpression(value); - } else if (defined(value.expression) || defined(value.conditionsExpression)) { - this._color = value; } else { - this._color = undefined; - return; + this._color = value; } this._colorShaderFunctionReady = false; } }, /** - * Gets or sets the {@link StyleExpression} object used to evaluate the style's pointSize property. Alternative an object defining a pointSize style can be used. + * Gets or sets the {@link StyleExpression} object used to evaluate the style's pointSize property. Alternatively a number, string, or object defining a pointSize style can be used. *

* The expression must return or convert to a Number. *

@@ -340,7 +371,27 @@ define([ * return 1.0; * } * }; - */ + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override pointSize expression with a number + * style.pointSize = 1.0; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override pointSize expression with a string + * style.pointSize = '${height} / 10'; + * + * @example + * var style = new Cesium.Cesium3DTileStyle(); + * // Override pointSize expression with a condition + * style.pointSize = { + * conditions : [ + * ['${height} > 2', '1.0'], + * ['true', '2.0'] + * ] + * }; + */ pointSize : { get : function() { //>>includeStart('debug', pragmas.debug); @@ -358,11 +409,8 @@ define([ this._pointSize = new Expression(value); } else if (defined(value.conditions)) { this._pointSize = new ConditionsExpression(value); - } else if (defined(value.expression) || defined(value.conditionsExpression)) { - this._pointSize = value; } else { - this._pointSize = undefined; - return; + this._pointSize = value; } this._pointSizeShaderFunctionReady = false; } From 7e6edb0d3206141f8cd940a7517d295d365d95ad Mon Sep 17 00:00:00 2001 From: Rachel Hwang Date: Wed, 5 Jul 2017 12:16:18 -0400 Subject: [PATCH 008/132] make entity model matrix computation public --- Source/DataSources/BoxGeometryUpdater.js | 6 +++--- Source/DataSources/CylinderGeometryUpdater.js | 6 +++--- Source/DataSources/EllipsoidGeometryUpdater.js | 6 +++--- Source/DataSources/Entity.js | 9 +++++++-- Source/DataSources/ModelVisualizer.js | 2 +- Specs/DataSources/EntitySpec.js | 16 ++++++++-------- 6 files changed, 25 insertions(+), 20 deletions(-) diff --git a/Source/DataSources/BoxGeometryUpdater.js b/Source/DataSources/BoxGeometryUpdater.js index e216bc3cda29..638274b91e2a 100644 --- a/Source/DataSources/BoxGeometryUpdater.js +++ b/Source/DataSources/BoxGeometryUpdater.js @@ -362,7 +362,7 @@ define([ return new GeometryInstance({ id : entity, geometry : BoxGeometry.fromDimensions(this._options), - modelMatrix : entity._getModelMatrix(Iso8601.MINIMUM_VALUE), + modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), attributes : attributes }); }; @@ -394,7 +394,7 @@ define([ return new GeometryInstance({ id : entity, geometry : BoxOutlineGeometry.fromDimensions(this._options), - modelMatrix : entity._getModelMatrix(Iso8601.MINIMUM_VALUE), + modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), attributes : { show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), color : ColorGeometryInstanceAttribute.fromColor(outlineColor), @@ -555,7 +555,7 @@ define([ } var options = this._options; - var modelMatrix = entity._getModelMatrix(time); + var modelMatrix = entity.computeModelMatrix(time); var dimensions = Property.getValueOrUndefined(box.dimensions, time, options.dimensions); if (!defined(modelMatrix) || !defined(dimensions)) { return; diff --git a/Source/DataSources/CylinderGeometryUpdater.js b/Source/DataSources/CylinderGeometryUpdater.js index 45fa1736199a..426e8f4b0dd3 100644 --- a/Source/DataSources/CylinderGeometryUpdater.js +++ b/Source/DataSources/CylinderGeometryUpdater.js @@ -367,7 +367,7 @@ define([ return new GeometryInstance({ id : entity, geometry : new CylinderGeometry(this._options), - modelMatrix : entity._getModelMatrix(Iso8601.MINIMUM_VALUE), + modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), attributes : attributes }); }; @@ -399,7 +399,7 @@ define([ return new GeometryInstance({ id : entity, geometry : new CylinderOutlineGeometry(this._options), - modelMatrix : entity._getModelMatrix(Iso8601.MINIMUM_VALUE), + modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), attributes : { show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), color : ColorGeometryInstanceAttribute.fromColor(outlineColor), @@ -573,7 +573,7 @@ define([ } var options = this._options; - var modelMatrix = entity._getModelMatrix(time); + var modelMatrix = entity.computeModelMatrix(time); var length = Property.getValueOrUndefined(cylinder.length, time); var topRadius = Property.getValueOrUndefined(cylinder.topRadius, time); var bottomRadius = Property.getValueOrUndefined(cylinder.bottomRadius, time); diff --git a/Source/DataSources/EllipsoidGeometryUpdater.js b/Source/DataSources/EllipsoidGeometryUpdater.js index 00f93ca8f1fc..5334661ca1d7 100644 --- a/Source/DataSources/EllipsoidGeometryUpdater.js +++ b/Source/DataSources/EllipsoidGeometryUpdater.js @@ -374,7 +374,7 @@ define([ return new GeometryInstance({ id : entity, geometry : new EllipsoidGeometry(this._options), - modelMatrix : entity._getModelMatrix(Iso8601.MINIMUM_VALUE), + modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), attributes : attributes }); }; @@ -407,7 +407,7 @@ define([ return new GeometryInstance({ id : entity, geometry : new EllipsoidOutlineGeometry(this._options), - modelMatrix : entity._getModelMatrix(Iso8601.MINIMUM_VALUE), + modelMatrix : entity.computeModelMatrix(Iso8601.MINIMUM_VALUE), attributes : { show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)), color : ColorGeometryInstanceAttribute.fromColor(outlineColor), @@ -589,7 +589,7 @@ define([ } var radii = Property.getValueOrUndefined(ellipsoid.radii, time, radiiScratch); - var modelMatrix = entity._getModelMatrix(time, this._modelMatrix); + var modelMatrix = entity.computeModelMatrix(time, this._modelMatrix); if (!defined(modelMatrix) || !defined(radii)) { if (defined(this._primitive)) { this._primitive.show = false; diff --git a/Source/DataSources/Entity.js b/Source/DataSources/Entity.js index abc2823c379a..d5fcae72d21d 100644 --- a/Source/DataSources/Entity.js +++ b/Source/DataSources/Entity.js @@ -581,9 +581,14 @@ define([ var orientationScratch = new Quaternion(); /** - * @private + * Computes the model matrix for the entity's transform at specified time. + * + * @param {JulianDate} time The time to retrieve model matrix for. + * @param {Matrix4} [result] The object onto which to store the result. + * + * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. */ - Entity.prototype._getModelMatrix = function(time, result) { + Entity.prototype.computeModelMatrix = function(time, result) { var position = Property.getValueOrUndefined(this._position, time, positionScratch); if (!defined(position)) { return undefined; diff --git a/Source/DataSources/ModelVisualizer.js b/Source/DataSources/ModelVisualizer.js index fd24f13cc280..bf6e48d2dd2f 100644 --- a/Source/DataSources/ModelVisualizer.js +++ b/Source/DataSources/ModelVisualizer.js @@ -100,7 +100,7 @@ define([ var modelMatrix; if (show) { - modelMatrix = entity._getModelMatrix(time, modelMatrixScratch); + modelMatrix = entity.computeModelMatrix(time, modelMatrixScratch); uri = Property.getValueOrUndefined(modelGraphics._uri, time); show = defined(modelMatrix) && defined(uri); } diff --git a/Specs/DataSources/EntitySpec.js b/Specs/DataSources/EntitySpec.js index 85b1444e2915..14a76ee790fb 100644 --- a/Specs/DataSources/EntitySpec.js +++ b/Specs/DataSources/EntitySpec.js @@ -241,13 +241,13 @@ defineSuite([ }).toThrowDeveloperError(); }); - it('_getModelMatrix returns undefined when position is undefined.', function() { + it('computeModelMatrix returns undefined when position is undefined.', function() { var entity = new Entity(); entity.orientation = new ConstantProperty(Quaternion.IDENTITY); - expect(entity._getModelMatrix(new JulianDate())).toBeUndefined(); + expect(entity.computeModelMatrix(new JulianDate())).toBeUndefined(); }); - it('_getModelMatrix returns correct value.', function() { + it('computeModelMatrix returns correct value.', function() { var entity = new Entity(); var position = new Cartesian3(123456, 654321, 123456); @@ -257,28 +257,28 @@ defineSuite([ entity.position = new ConstantProperty(position); entity.orientation = new ConstantProperty(orientation); - var modelMatrix = entity._getModelMatrix(new JulianDate()); + var modelMatrix = entity.computeModelMatrix(new JulianDate()); var expected = Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientation), position); expect(modelMatrix).toEqual(expected); }); - it('_getModelMatrix returns ENU when quaternion is undefined.', function() { + it('computeModelMatrix returns ENU when quaternion is undefined.', function() { var entity = new Entity(); var position = new Cartesian3(123456, 654321, 123456); entity.position = new ConstantProperty(position); - var modelMatrix = entity._getModelMatrix(new JulianDate()); + var modelMatrix = entity.computeModelMatrix(new JulianDate()); var expected = Transforms.eastNorthUpToFixedFrame(position); expect(modelMatrix).toEqual(expected); }); - it('_getModelMatrix works with result parameter.', function() { + it('computeModelMatrix works with result parameter.', function() { var entity = new Entity(); var position = new Cartesian3(123456, 654321, 123456); entity.position = new ConstantProperty(position); var result = new Matrix4(); - var modelMatrix = entity._getModelMatrix(new JulianDate(), result); + var modelMatrix = entity.computeModelMatrix(new JulianDate(), result); var expected = Transforms.eastNorthUpToFixedFrame(position); expect(modelMatrix).toBe(result); expect(modelMatrix).toEqual(expected); From a05c5dc752d587e535b39be08922b0284af70116 Mon Sep 17 00:00:00 2001 From: Rachel Hwang Date: Tue, 11 Jul 2017 09:09:26 -0400 Subject: [PATCH 009/132] updating CHANGES --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 2cd1c2c0c442..793ec858449e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ Change Log * Fixed a bug where a Model's compressed textures were not being displayed. [#5596](https://github.com/AnalyticalGraphicsInc/cesium/pull/5596) * Fixed a bug where jsep was undefined when using webpack [#5593](https://github.com/AnalyticalGraphicsInc/cesium/issues/5593) +* Make Entity mode matrix public via computeModelMatrix(). [#5584](https://github.com/AnalyticalGraphicsInc/cesium/pull/5584) ### 1.35 - 2017-07-05 From 1974019ec19d13b605b808bf1e1cf354c3f78e71 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Tue, 11 Jul 2017 13:43:42 -0400 Subject: [PATCH 010/132] Fix label clamped position --- Source/Scene/Label.js | 9 +-------- Specs/Scene/LabelCollectionSpec.js | 17 +++++++++++++++++ Specs/createGlobe.js | 2 ++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/Source/Scene/Label.js b/Source/Scene/Label.js index 54865f47fde8..b48b4be9a051 100644 --- a/Source/Scene/Label.js +++ b/Source/Scene/Label.js @@ -194,9 +194,7 @@ define([ backgroundBillboard.position = value; } - if (this._heightReference !== HeightReference.NONE) { - this._updateClamping(); - } + this._updateClamping(); } } }, @@ -964,22 +962,17 @@ define([ this._actualClampedPosition = Cartesian3.clone(value, this._actualClampedPosition); var glyphs = this._glyphs; - value = defaultValue(value, this._position); for (var i = 0, len = glyphs.length; i < len; i++) { var glyph = glyphs[i]; if (defined(glyph.billboard)) { // Set all the private values here, because we already clamped to ground // so we don't want to do it again for every glyph glyph.billboard._clampedPosition = value; - Cartesian3.clone(value, glyph.billboard._position); - Cartesian3.clone(value, glyph.billboard._actualPosition); } } var backgroundBillboard = this._backgroundBillboard; if (defined(backgroundBillboard)) { backgroundBillboard._clampedPosition = value; - Cartesian3.clone(value, backgroundBillboard._position); - Cartesian3.clone(value, backgroundBillboard._actualPosition); } } }, diff --git a/Specs/Scene/LabelCollectionSpec.js b/Specs/Scene/LabelCollectionSpec.js index 1b10f96f4c5f..01d0a0e9f67e 100644 --- a/Specs/Scene/LabelCollectionSpec.js +++ b/Specs/Scene/LabelCollectionSpec.js @@ -2210,6 +2210,23 @@ defineSuite([ cartographic = scene.globe.ellipsoid.cartesianToCartographic(l._clampedPosition); expect(cartographic.height).toEqualEpsilon(100.0, CesiumMath.EPSILON9); }); + + it('resets the clamped position when HeightReference.NONE', function() { + scene.globe = createGlobe(); + spyOn(scene.camera, 'update'); + var l = labelsWithHeight.add({ + heightReference : HeightReference.CLAMP_TO_GROUND, + text: 't', + position : Cartesian3.fromDegrees(-72.0, 40.0) + }); + scene.renderForSpecs(); + expect(l._clampedPosition).toBeDefined(); + expect(l._glyphs[0].billboard._clampedPosition).toBeDefined(); + + l.heightReference = HeightReference.NONE; + expect(l._clampedPosition).toBeUndefined(); + expect(l._glyphs[0].billboard._clampedPosition).toBeUndefined(); + }); }); }, 'WebGL'); diff --git a/Specs/createGlobe.js b/Specs/createGlobe.js index aaa05130dca2..4ad23aec8b51 100644 --- a/Specs/createGlobe.js +++ b/Specs/createGlobe.js @@ -17,6 +17,8 @@ define([ callback : undefined, removedCallback : false, ellipsoid : ellipsoid, + beginFrame: function() {}, + endFrame: function() {}, update : function() {}, getHeight : function() { return 0.0; From e2ee679cb75b420e015129f7ccbdabb3d705e99d Mon Sep 17 00:00:00 2001 From: Tom Fili Date: Tue, 11 Jul 2017 14:50:24 -0400 Subject: [PATCH 011/132] Fixed issue where a composite tile containing and instanced tile that required padding would have a bad URL because the padding would end up appended to the url. --- Source/Scene/Instanced3DModel3DTileContent.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index df1de7ca0593..b26b64a05ba0 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -308,6 +308,10 @@ define([ if (gltfFormat === 0) { var gltfUrl = getStringFromTypedArray(gltfView); + + // We need to remove padding from the end of the model URL in case this tile was part of a composite tile + // This removes all white space and null characters from the end of the string. + gltfUrl = gltfUrl.trim().replace(/\0+$/, ''); collectionOptions.url = getAbsoluteUri(joinUrls(getBaseUri(content._url, true), gltfUrl)); } else { collectionOptions.gltf = gltfView; From 65840a48023c62bd44531350c8534a6953f7630c Mon Sep 17 00:00:00 2001 From: Tom Fili Date: Tue, 11 Jul 2017 18:01:50 -0400 Subject: [PATCH 012/132] Added test. --- .../MultipleInstancedTilesets/1/0/0.i3dm | Bin 0 -> 151 bytes .../MultipleInstancedTilesets/2/2/2.i3dm | Bin 0 -> 174 bytes .../MultipleInstancedTilesets/2/2/3.i3dm | Bin 0 -> 175 bytes .../MultipleInstancedTilesets/2/3/3.i3dm | Bin 0 -> 173 bytes .../MultipleInstancedTilesets/box1.glb | Bin 0 -> 1981 bytes .../MultipleInstancedTilesets/box2.glb | Bin 0 -> 2003 bytes .../MultipleInstancedTilesets/tileset.json | Bin 0 -> 481 bytes Specs/Scene/Composite3DTileContentSpec.js | 29 +++++++++++++++++- 8 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/1/0/0.i3dm create mode 100644 Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/2/2/2.i3dm create mode 100644 Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/2/2/3.i3dm create mode 100644 Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/2/3/3.i3dm create mode 100644 Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/box1.glb create mode 100644 Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/box2.glb create mode 100644 Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/tileset.json diff --git a/Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/1/0/0.i3dm b/Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/1/0/0.i3dm new file mode 100644 index 0000000000000000000000000000000000000000..f3c99b72a54a7025c98a4924b43fe08ae6128cd4 GIT binary patch literal 151 zcmV;I0BHXoiwFP!000003d=N3$z^08XWKA>gOKf zp=4#KqZHsD>>1+e@26x{t&~(*lIow9R-9U*WMxpRqvYxs91`#69~9yd9~z)!RZ>)% zTB{%*IK?x&Yr-iG`ARQ{xgM#R=@~#R(T1_L3JQ99`aqPFUty@1o|DAD001$=_CuHe F007w3L>&MC literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/2/2/2.i3dm b/Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/2/2/2.i3dm new file mode 100644 index 0000000000000000000000000000000000000000..3dd31dc796ba283f98ea2d41c751b7b14739288a GIT binary patch literal 174 zcmV;f08#%RiwFP!000003d=N3$z^07WvHVR;2-Q6;_2_FWL2${R9TYhpO#jfTB2lSP^+Wl>KGgn@8=&B;t?Mjpk!52 zRGO-z6zuHi&E)x}w%3d6y0v4ql1FN0dInHYw4tG%xk)Tk cp`M;T5GCbT80n?wBrz}m0EdR~(ZB!z03UEt*#H0l literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/2/2/3.i3dm b/Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/2/2/3.i3dm new file mode 100644 index 0000000000000000000000000000000000000000..bf77cccec5d649015a368e97ba41a30e05394bdf GIT binary patch literal 175 zcmV;g08sxQiwFP!000003d=N3$z^07WvHVR;2-Q6;_2_FWL2${R9TYhpO#jfTB2lSP^+Wl>KGgn@8=&B;t?Mjpk!52 zRGO-z6zuHiP7WvHVR;2-Q6;_2_FWL2${R9TYhpO#jfTB2lSP^+Wl>KGgn@8=&B;t?Mjpk!52 zRGO-z6zuHijR bP)|=Eh?4Rv4E54;k{B2Of)Ou6zyJUMGw4nd literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/box1.glb b/Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/box1.glb new file mode 100644 index 0000000000000000000000000000000000000000..d43defba2fb5ff1ce2284967dd091501b84992a1 GIT binary patch literal 1981 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 X#2F> Date: Tue, 11 Jul 2017 18:04:20 -0400 Subject: [PATCH 013/132] Tweaks. --- Source/Scene/Instanced3DModel3DTileContent.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index b26b64a05ba0..66ad743fc5d2 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -309,9 +309,9 @@ define([ if (gltfFormat === 0) { var gltfUrl = getStringFromTypedArray(gltfView); - // We need to remove padding from the end of the model URL in case this tile was part of a composite tile + // We need to remove padding from the end of the model URL in case this tile was part of a composite tile. // This removes all white space and null characters from the end of the string. - gltfUrl = gltfUrl.trim().replace(/\0+$/, ''); + gltfUrl = gltfUrl.replace(/[\s\0]+$/, ''); collectionOptions.url = getAbsoluteUri(joinUrls(getBaseUri(content._url, true), gltfUrl)); } else { collectionOptions.gltf = gltfView; From a6d88b3ef039aca95b8e0210989523658dd8da32 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Tue, 11 Jul 2017 20:42:52 -0400 Subject: [PATCH 014/132] Fix for reading mip level 0 of DXT --- Source/Workers/transcodeCRNToDXT.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/Workers/transcodeCRNToDXT.js b/Source/Workers/transcodeCRNToDXT.js index e5a28e1297cd..c643c0de9832 100644 --- a/Source/Workers/transcodeCRNToDXT.js +++ b/Source/Workers/transcodeCRNToDXT.js @@ -132,8 +132,11 @@ define([ // Mipmaps are unsupported, so copy the level 0 texture // When mipmaps are supported, a copy will still be necessary as dxtData is a view on the heap. var length = PixelFormat.compressedTextureSizeInBytes(format, width, height); + + // Equivalent to dxtData.slice(0, length), which is not supported in IE11 + var level0DXTDataView = dxtData.subarray(0, length); var level0DXTData = new Uint8Array(length); - level0DXTData.set(dxtData, 0); + level0DXTData.set(level0DXTDataView, 0); transferableObjects.push(level0DXTData.buffer); return new CompressedTextureBuffer(format, width, height, level0DXTData); From 15177bc84d4e9c45ebdb7942fa0650a8dcf17e7f Mon Sep 17 00:00:00 2001 From: Tom Fili Date: Wed, 12 Jul 2017 11:53:47 -0400 Subject: [PATCH 015/132] Updated CHANGES --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 28ac687b486d..73b8678675b4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ Change Log ### 1.36 - 2017-08-01 * Added ability to show tile urls in the 3D Tiles Inspector. [#5592](https://github.com/AnalyticalGraphicsInc/cesium/pull/5592) +* Fixed issue where composite 3D Tiles that contained instanced 3D Tiles with an external model reference would fail to download the model. ### 1.35.2 - 2017-07-11 From d109a22298d50eee954728cfd7dba24f0b85819d Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Wed, 12 Jul 2017 14:08:42 -0400 Subject: [PATCH 016/132] Initial commit of GLSLModernizer and other WebGL2 changes --- Source/Renderer/Context.js | 31 ++- Source/Renderer/GLSLModernizer.js | 351 ++++++++++++++++++++++++++++ Source/Renderer/ShaderCache.js | 11 +- Source/Renderer/ShaderSource.js | 40 +++- Source/Renderer/Texture.js | 14 ++ Source/Shaders/GlobeFS.glsl | 4 +- Specs/Renderer/ShaderProgramSpec.js | 4 +- Specs/Renderer/ShaderSourceSpec.js | 10 +- 8 files changed, 440 insertions(+), 25 deletions(-) create mode 100644 Source/Renderer/GLSLModernizer.js diff --git a/Source/Renderer/Context.js b/Source/Renderer/Context.js index 7eff7dc3fa52..e8af2d025cf2 100644 --- a/Source/Renderer/Context.js +++ b/Source/Renderer/Context.js @@ -268,13 +268,17 @@ define([ this._antialias = gl.getContextAttributes().antialias; // Query and initialize extensions - this._standardDerivatives = !!getExtension(gl, ['OES_standard_derivatives']); - this._elementIndexUint = !!getExtension(gl, ['OES_element_index_uint']); - this._depthTexture = !!getExtension(gl, ['WEBGL_depth_texture', 'WEBKIT_WEBGL_depth_texture']); - this._textureFloat = !!getExtension(gl, ['OES_texture_float']); - this._fragDepth = !!getExtension(gl, ['EXT_frag_depth']); + this._standardDerivatives = !!getExtension(gl, ['OES_standard_derivatives']) || this._webgl2; + this._elementIndexUint = !!getExtension(gl, ['OES_element_index_uint']) || this._webgl2; + this._depthTexture = !!getExtension(gl, ['WEBGL_depth_texture', 'WEBKIT_WEBGL_depth_texture']) || this._webgl2; + this._textureFloat = !!getExtension(gl, ['OES_texture_float']) || this._webgl2; + this._fragDepth = !!getExtension(gl, ['EXT_frag_depth']) || this._webgl2; this._debugShaders = getExtension(gl, ['WEBGL_debug_shaders']); + if (this._webgl2) { + this._colorBufferFloat = !!getExtension(gl, ['EXT_color_buffer_float']); + } + this._s3tc = !!getExtension(gl, ['WEBGL_compressed_texture_s3tc', 'MOZ_WEBGL_compressed_texture_s3tc', 'WEBKIT_WEBGL_compressed_texture_s3tc']); this._pvrtc = !!getExtension(gl, ['WEBGL_compressed_texture_pvrtc', 'WEBKIT_WEBGL_compressed_texture_pvrtc']); this._etc1 = !!getExtension(gl, ['WEBGL_compressed_texture_etc1']); @@ -614,6 +618,20 @@ define([ } }, + /** + * true if the EXT_color_buffer_float extension is supported. This + * extension makes the formats gl.R16F, gl.RG16F, gl.RGBA16F, gl.R32F, gl.RG32F, + * gl.RGBA32F, gl.R11F_G11F_B10F color renderable. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link https://www.khronos.org/registry/webgl/extensions/EXT_color_buffer_float/} + */ + colorBufferFloat : { + get : function() { + return this._colorBufferFloat; + } + }, + /** * true if the WEBGL_draw_buffers extension is supported. This * extensions provides support for multiple render targets. The framebuffer object can have mutiple @@ -1076,7 +1094,8 @@ define([ }), uniformMap : overrides.uniformMap, owner : overrides.owner, - framebuffer : overrides.framebuffer + framebuffer : overrides.framebuffer, + pass : overrides.pass }); }; diff --git a/Source/Renderer/GLSLModernizer.js b/Source/Renderer/GLSLModernizer.js new file mode 100644 index 000000000000..95c373455510 --- /dev/null +++ b/Source/Renderer/GLSLModernizer.js @@ -0,0 +1,351 @@ +/*global define*/ +define([ + '../Core/DeveloperError', + ], function( + DeveloperError) { + 'use strict'; + + /** + * A function to port GLSL shaders from GLSL ES 1.00 to GLSL ES 2.00 + * + * This function is nowhere near comprehensive or complete. It just + * handles some common cases. + * + * @private + */ + function glslModernizeShaderSource(shaderSource, isFragmentShader) { + for (var i = 0; i < shaderSource.sources.length; i++) { + shaderSource.sources[i] = + glslModernizeShaderText(shaderSource.sources[i], isFragmentShader, i === 0); + } + shaderSource.defines.push("MODERNIZED"); + } + + // Note that this function requires the presence of the + // "#define OUTPUT_DECLARATION" line that is appended + // by ShaderSource + function glslModernizeShaderText(source, isFragmentShader, first) { + var mainFunctionRegex = /void\s+main\s*\((void)?\)/; + var outputDeclarationRegex = /#define OUTPUT_DECLARATION/; + var splitSource = source.split('\n'); + + if (source.search(/#version 300 es/g) !== -1) { + return source; + } + + var outputDeclarationLine = -1; + var number; + for (number = 0; number < splitSource.length; number++) { + var line = splitSource[number]; + if (outputDeclarationRegex.exec(line)) { + outputDeclarationLine = number; + break; + } + }; + + if (outputDeclarationLine == -1) { + for (number = 0; number < splitSource.length; number++) { + var line = splitSource[number]; + if (mainFunctionRegex.exec(line)) { + outputDeclarationLine = number; + } + }; + } + + if (outputDeclarationLine == -1) { + throw new DeveloperError('Could not find a ' + + '#define OUTPUT_DECLARATION ' + + 'nor a main function!'); + } + + function safeNameFalseNegative(regex, region) { + var regExpStr = regex.toString(); + regExpStr = regExpStr.match(/\/([^\/]+)(\/.)?/)[1]; + var somethingBadInString = + new RegExp("[a-zA-Z0-9_]+" + regExpStr, 'g'); + var searchResult = region.search(somethingBadInString); + if (searchResult === -1) { + return true; + } else { + return false; + } + } + + function safeNameFind(regex, str) { + var originalMatch = regex.exec(str); + if (originalMatch == null) { + return -1; + } + var endPos = originalMatch.index + originalMatch[0].length; + var region = str.substring(0, endPos); + + var possiblyFalseNegative = safeNameFalseNegative(regex, region); + if (possiblyFalseNegative) { + return endPos; + } else { + var childResult = safeNameFind(regex, str.substring(endPos)); + if (childResult == -1) { + return -1; + } else { + return endPos + childResult; + } + } + } + + function safeNameReplace(regex, str, replacement) { + var originalMatch = regex.exec(str); + if (originalMatch == null) { + return str; + } + var endPos = originalMatch.index + originalMatch[0].length; + var region = str.substring(0, endPos); + + var possiblyFalseNegative = safeNameFalseNegative(regex, region); + if (possiblyFalseNegative) { + return region.replace(regex, replacement) + + safeNameReplace(regex, str.substr(endPos), replacement); + } else { + return region + + safeNameReplace(regex, str.substr(endPos), replacement); + } + } + + function replaceInSource(regex, replacement) { + for (var number = 0; number < splitSource.length; number++) { + splitSource[number] = safeNameReplace(regex, splitSource[number], replacement); + } + } + + function findInSource(regex) { + for (var number = 0; number < splitSource.length; number++) { + var line = splitSource[number]; + if (safeNameFind(regex, line) !== -1) { + return true; + } + } + return false; + } + + function compileSource() { + var wholeSource = ""; + for (var number = 0; number < splitSource.length; number++) { + wholeSource += splitSource[number] + "\n"; + } + return wholeSource; + } + + function setAdd(variable, set1) { + if (set1.indexOf(variable) === -1) + set1.push(variable); + } + + function setUnion(set1, set2) { + for (var a = 0; a < set2.length; a++) { + setAdd(set2[a], set1); + } + } + + function getVariablePreprocessorBranch(variablesThatWeCareAbout) { + var variableMap = {}; + var negativeMap = {}; + + for (var a = 0; a < variablesThatWeCareAbout.length; a++) { + var variableThatWeCareAbout = variablesThatWeCareAbout[a]; + variableMap[variableThatWeCareAbout] = [null]; + } + + var stack = []; + for (var i = 0; i < splitSource.length; i++) { + var line = splitSource[i]; + var hasIF = line.search(/(#ifdef|#if)/g) !== -1; + var hasELSE = line.search(/#else/g) !== -1; + var hasENDIF = line.search(/#endif/g) !== -1; + + if (hasIF) { + stack.push(line); + } else if (hasELSE) { + var top = stack[stack.length - 1]; + var op = top.replace("ifdef", "ifndef"); + if (op.search(/if/g) !== -1) { + op = op.replace(/(#if\s+)(\S*)([^]*)/, "$1!($2)$3"); + } + stack.pop(); + stack.push(op); + + negativeMap[top] = op; + negativeMap[op] = top; + } else if (hasENDIF) { + stack.pop(); + } else if (line.search(/layout/g) === -1) { + for (a = 0; a < variablesThatWeCareAbout.length; a++) { + var care = variablesThatWeCareAbout[a]; + if (line.indexOf(care) !== -1) { + if (variableMap[care].length === 1 && + variableMap[care][0] === null) { + variableMap[care] = stack.slice(); + } else { + variableMap[care] = variableMap[care].filter( + function(x) { return stack.indexOf(x) >= 0; }); + } + } + } + } + } + + // This code is probably no longer needed... it was used to handle + // removing negative conditions + for (var care in variableMap) { + if (variableMap.hasOwnProperty(care)) { + var entry = variableMap[care]; + var toDelete = []; + for (var b = 0; b < entry.length; b++) { + var item = entry[b]; + if (entry.indexOf(negativeMap[item]) !== -1) { + toDelete.push(item); + toDelete.push(negativeMap[item]); + } + } + + for (var c = 0; c < toDelete.length; c++) { + var ind = entry.indexOf(toDelete[c]); + if (ind !== -1) { + entry.splice(ind, 1); + } + } + } + } + + for (var care in variableMap) { + if (variableMap.hasOwnProperty(care)) { + if (variableMap.length === 1 && + variableMap[0] === null) { + variableMap.splice(0, 1); + } + } + } + + return variableMap; + } + + function removeExtension(name) { + var regex = "#extension\\s+GL_" + name + "\\s+:\\s+[a-zA-Z0-9]+\\s*$"; + replaceInSource(new RegExp(regex, "g"), ""); + } + + var variableSet = []; + + for (var i = 0; i < 10; i++) { + var fragDataString = "gl_FragData\\[" + i + "\\]"; + var newOutput = 'czm_out' + i; + var regex = new RegExp(fragDataString, "g"); + if (source.search(fragDataString) != -1) { + setAdd(newOutput, variableSet); + replaceInSource(regex, newOutput); + splitSource.splice(outputDeclarationLine, 0, + "layout(location = " + i + ") out vec4 " + + newOutput + ";"); + outputDeclarationLine += 1; + } + } + + var czmFragColor = "czm_fragColor"; + if (findInSource(/gl_FragColor/)) { + setAdd(czmFragColor, variableSet); + replaceInSource(/gl_FragColor/, czmFragColor); + splitSource.splice(outputDeclarationLine, 0, "layout(location = 0) out vec4 czm_fragColor;"); + outputDeclarationLine += 1; + } + + var variableMap = getVariablePreprocessorBranch(variableSet); + var lineAdds = {}; + for (var c = 0; c < splitSource.length; c++) { + var l = splitSource[c]; + for (var care in variableMap) { + if (variableMap.hasOwnProperty(care)) { + var matchVar = + new RegExp("(layout)[^]+(out)[^]+(" + care + ")[^]+", "g"); + if (matchVar.exec(l) !== null) { + lineAdds[l] = care; + } + } + } + } + + for (var layoutDeclaration in lineAdds) { + if (lineAdds.hasOwnProperty(layoutDeclaration)) { + var variableName = lineAdds[layoutDeclaration]; + var lineNumber = splitSource.indexOf(layoutDeclaration); + var entry = variableMap[variableName]; + var depth = entry.length; + var d; + for (d = 0; d < depth; d++) { + splitSource.splice(lineNumber, 0, entry[d]); + } + lineNumber += depth + 1; + for (d = depth - 1; d >= 0; d--) { + splitSource.splice(lineNumber, 0, "#endif //" + entry[d]); + } + } + } + + console.log(compileSource()); + + if (first === true) { + var versionThree = "#version 300 es"; + var foundVersion = false; + for (number = 0; number < splitSource.length; number++) { + if (splitSource[number].search(/#version/) != -1) { + splitSource[number] = versionThree; + foundVersion = true; + } + } + + if (!foundVersion) { + splitSource.splice(0, 0, versionThree); + } + } + + removeExtension("EXT_draw_buffers"); + removeExtension("EXT_frag_depth"); + + replaceInSource(/texture2D/, "texture"); + replaceInSource(/texture3D/, "texture"); + replaceInSource(/textureCube/, "texture"); + replaceInSource(/gl_FragDepthEXT/, "gl_FragDepth"); + + if (isFragmentShader) { + replaceInSource(/varying/, "in"); + } else { + replaceInSource(/attribute/, "in"); + replaceInSource(/varying/, "out"); + } + + return compileSource(); + } + + function glslModernizeShaderProgram(context, shaderProgram) { + var vsSource = shaderProgram.vertexShaderSource.clone(); + var fsSource = shaderProgram.fragmentShaderSource.clone(); + + glslModernizeShaderSource(vsSource, false); + glslModernizeShaderSource(fsSource, true); + + var newShaderProgramOptions = { + vertexShaderSource : vsSource, + fragmentShaderSource : fsSource, + gl : shaderProgram._gl, + logShaderCompilation : shaderProgram._logShaderCompilation, + attributeLocations : shaderProgram._attributeLocations + }; + + return context.shaderCache.getShaderProgram(newShaderProgramOptions); + } + + var GLSLModernizer = { + glslModernizeShaderText : glslModernizeShaderText, + glslModernizeShaderSource : glslModernizeShaderSource, + glslModernizeShaderProgram : glslModernizeShaderProgram + }; + + return GLSLModernizer; +}); diff --git a/Source/Renderer/ShaderCache.js b/Source/Renderer/ShaderCache.js index d8635213de6d..1720fd5c3f51 100644 --- a/Source/Renderer/ShaderCache.js +++ b/Source/Renderer/ShaderCache.js @@ -96,8 +96,8 @@ define([ }); } - var vertexShaderText = vertexShaderSource.createCombinedVertexShader(); - var fragmentShaderText = fragmentShaderSource.createCombinedFragmentShader(); + var vertexShaderText = vertexShaderSource.createCombinedVertexShader(this._context.webgl2); + var fragmentShaderText = fragmentShaderSource.createCombinedFragmentShader(this._context.webgl2); var keyword = vertexShaderText + fragmentShaderText + JSON.stringify(attributeLocations); var cachedShader; @@ -169,10 +169,11 @@ define([ }); } - var vertexShaderText = vertexShaderSource.createCombinedVertexShader(); - var fragmentShaderText = fragmentShaderSource.createCombinedFragmentShader(); - var context = this._context; + + var vertexShaderText = vertexShaderSource.createCombinedVertexShader(context.webgl2); + var fragmentShaderText = fragmentShaderSource.createCombinedFragmentShader(context.webgl2); + var derivedShaderProgram = new ShaderProgram({ gl : context._gl, logShaderCompilation : context.logShaderCompilation, diff --git a/Source/Renderer/ShaderSource.js b/Source/Renderer/ShaderSource.js index 36bb4637145b..b99ff5ee75ec 100644 --- a/Source/Renderer/ShaderSource.js +++ b/Source/Renderer/ShaderSource.js @@ -2,12 +2,14 @@ define([ '../Core/defaultValue', '../Core/defined', '../Core/DeveloperError', + '../Renderer/GLSLModernizer', '../Shaders/Builtin/CzmBuiltins', './AutomaticUniforms' ], function( defaultValue, defined, DeveloperError, + GLSLModernizer, CzmBuiltins, AutomaticUniforms) { 'use strict'; @@ -151,7 +153,7 @@ define([ return builtinsSource.replace(root.glslSource, ''); } - function combineShader(shaderSource, isFragmentShader) { + function combineShader(shaderSource, isFragmentShader, webgl2) { var i; var length; @@ -186,6 +188,17 @@ define([ return '\n'; }); + // Extract existing shader version from sources + var extensions = []; + combinedSources = combinedSources.replace(/#extension\s+(.*?)\n/gm, function(match, group1) { + // Extract extension to put at the top + extensions.push(match); + + // Replace original #extension directive with a new line so the line numbers + // are not off by one. + return '\n'; + }); + // Remove precision qualifier combinedSources = combinedSources.replace(/precision\s(lowp|mediump|highp)\s(float|int);/, ''); @@ -204,6 +217,10 @@ define([ result = '#version ' + version + '\n'; } + for (i = 0; i < extensions.length; i++) { + result += extensions[i]; + } + if (isFragmentShader) { result += '\ #ifdef GL_FRAGMENT_PRECISION_HIGH\n\ @@ -224,6 +241,8 @@ define([ } } + result += '#define OUTPUT_DECLARATION\n\n'; + // append built-ins if (shaderSource.includeBuiltIns) { result += getBuiltinsAndAutomaticUniforms(combinedSources); @@ -235,6 +254,13 @@ define([ // append actual source result += combinedSources; + // modernize the source + if (webgl2) { + result = GLSLModernizer.glslModernizeShaderText(result, + isFragmentShader, + true); + } + return result; } @@ -297,19 +323,23 @@ define([ /** * Create a single string containing the full, combined vertex shader with all dependencies and defines. * + * @param {Boolean} [webgl2] A boolean parameter which is true if the context is using WebGL 2, false otherwise + * * @returns {String} The combined shader string. */ - ShaderSource.prototype.createCombinedVertexShader = function() { - return combineShader(this, false); + ShaderSource.prototype.createCombinedVertexShader = function(webgl2) { + return combineShader(this, false, webgl2); }; /** * Create a single string containing the full, combined fragment shader with all dependencies and defines. * + * @param {Boolean} [webgl2] A boolean parameter which is true if the context is using WebGL 2, false otherwise + * * @returns {String} The combined shader string. */ - ShaderSource.prototype.createCombinedFragmentShader = function() { - return combineShader(this, true); + ShaderSource.prototype.createCombinedFragmentShader = function(webgl2) { + return combineShader(this, true, webgl2); }; /** diff --git a/Source/Renderer/Texture.js b/Source/Renderer/Texture.js index 2de068ea749e..915e73c6d389 100644 --- a/Source/Renderer/Texture.js +++ b/Source/Renderer/Texture.js @@ -71,6 +71,20 @@ define([ internalFormat = WebGLConstants.DEPTH_COMPONENT24; } } + + if (pixelDatatype == PixelDatatype.FLOAT) { + switch (pixelFormat) { + case PixelFormat.RGBA: + internalFormat = WebGLConstants.RGBA32F; + break; + case PixelFormat.RG: + internalFormat = WebGLConstants.RG32F; + break; + case PixelFormat.R: + internalFormat = WebGLConstants.R32F; + break; + } + } } //>>includeStart('debug', pragmas.debug); diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index c36fc9737286..34f8bc02c4ca 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -66,7 +66,7 @@ varying vec3 v_mieColor; vec4 sampleAndBlend( vec4 previousColor, - sampler2D texture, + sampler2D textureToSample, vec2 tileTextureCoordinates, vec4 textureCoordinateRectangle, vec4 textureCoordinateTranslationAndScale, @@ -94,7 +94,7 @@ vec4 sampleAndBlend( vec2 translation = textureCoordinateTranslationAndScale.xy; vec2 scale = textureCoordinateTranslationAndScale.zw; vec2 textureCoordinates = tileTextureCoordinates * scale + translation; - vec4 value = texture2D(texture, textureCoordinates); + vec4 value = texture2D(textureToSample, textureCoordinates); vec3 color = value.rgb; float alpha = value.a; diff --git a/Specs/Renderer/ShaderProgramSpec.js b/Specs/Renderer/ShaderProgramSpec.js index e2934ed94b66..bf52c55a8c8e 100644 --- a/Specs/Renderer/ShaderProgramSpec.js +++ b/Specs/Renderer/ShaderProgramSpec.js @@ -65,13 +65,13 @@ defineSuite([ var expectedVSText = new ShaderSource({ sources : [vs] - }).createCombinedVertexShader(); + }).createCombinedVertexShader(context.webgl2); expect(sp._vertexShaderText).toEqual(expectedVSText); var expectedFSText = new ShaderSource({ sources : [fs] - }).createCombinedFragmentShader(); + }).createCombinedFragmentShader(context.webgl2); expect(sp._fragmentShaderText).toEqual(expectedFSText); }); diff --git a/Specs/Renderer/ShaderSourceSpec.js b/Specs/Renderer/ShaderSourceSpec.js index b9105e4b28ed..3fa7fbaef0e5 100644 --- a/Specs/Renderer/ShaderSourceSpec.js +++ b/Specs/Renderer/ShaderSourceSpec.js @@ -9,7 +9,7 @@ defineSuite([ defines : ['A', 'B', ''] }); - var shaderText = source.createCombinedVertexShader(); + var shaderText = source.createCombinedVertexShader(false); expect(shaderText).toContain('#define A'); expect(shaderText).toContain('#define B'); expect(shaderText.match(/#define/g).length).toEqual(2); @@ -19,7 +19,7 @@ defineSuite([ var source = new ShaderSource({ sources : ['void func() {}', 'void main() {}'] }); - var shaderText = source.createCombinedVertexShader(); + var shaderText = source.createCombinedVertexShader(false); expect(shaderText).toContain('#line 0\nvoid func() {}'); expect(shaderText).toContain('#line 0\nvoid main() {}'); }); @@ -29,7 +29,7 @@ defineSuite([ defines : ['A', 'B', ''], sources : ['void func() {}', 'void main() {}'] }); - var shaderText = source.createCombinedVertexShader(); + var shaderText = source.createCombinedVertexShader(false); expect(shaderText).toContain('#define A'); expect(shaderText).toContain('#define B'); expect(shaderText.match(/#define/g).length).toEqual(2); @@ -42,7 +42,7 @@ defineSuite([ sources : ['void main() { gl_FragColor = vec4(1.0); }'], pickColorQualifier : 'uniform' }); - var shaderText = source.createCombinedVertexShader(); + var shaderText = source.createCombinedVertexShader(false); expect(shaderText).toContain('uniform vec4 czm_pickColor;'); expect(shaderText).toContain('gl_FragColor = czm_pickColor;'); }); @@ -52,7 +52,7 @@ defineSuite([ sources : ['void main() { gl_FragColor = vec4(1.0); }'], pickColorQualifier : 'varying' }); - var shaderText = source.createCombinedVertexShader(); + var shaderText = source.createCombinedVertexShader(false); expect(shaderText).toContain('varying vec4 czm_pickColor;'); expect(shaderText).toContain('gl_FragColor = czm_pickColor;'); }); From 9f5361dfc117593de729924307ea0f615938305d Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Wed, 12 Jul 2017 14:25:12 -0400 Subject: [PATCH 017/132] Extension/capability flags style fix --- Source/Renderer/Context.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/Source/Renderer/Context.js b/Source/Renderer/Context.js index e8af2d025cf2..5110b4265d48 100644 --- a/Source/Renderer/Context.js +++ b/Source/Renderer/Context.js @@ -268,16 +268,14 @@ define([ this._antialias = gl.getContextAttributes().antialias; // Query and initialize extensions - this._standardDerivatives = !!getExtension(gl, ['OES_standard_derivatives']) || this._webgl2; - this._elementIndexUint = !!getExtension(gl, ['OES_element_index_uint']) || this._webgl2; - this._depthTexture = !!getExtension(gl, ['WEBGL_depth_texture', 'WEBKIT_WEBGL_depth_texture']) || this._webgl2; - this._textureFloat = !!getExtension(gl, ['OES_texture_float']) || this._webgl2; - this._fragDepth = !!getExtension(gl, ['EXT_frag_depth']) || this._webgl2; + this._standardDerivatives = !!getExtension(gl, ['OES_standard_derivatives']); + this._elementIndexUint = !!getExtension(gl, ['OES_element_index_uint']); + this._depthTexture = !!getExtension(gl, ['WEBGL_depth_texture', 'WEBKIT_WEBGL_depth_texture']); + this._textureFloat = !!getExtension(gl, ['OES_texture_float']); + this._fragDepth = !!getExtension(gl, ['EXT_frag_depth']); this._debugShaders = getExtension(gl, ['WEBGL_debug_shaders']); - if (this._webgl2) { - this._colorBufferFloat = !!getExtension(gl, ['EXT_color_buffer_float']); - } + this._colorBufferFloat = this._webgl2 && !!getExtension(gl, ['EXT_color_buffer_float']); this._s3tc = !!getExtension(gl, ['WEBGL_compressed_texture_s3tc', 'MOZ_WEBGL_compressed_texture_s3tc', 'WEBKIT_WEBGL_compressed_texture_s3tc']); this._pvrtc = !!getExtension(gl, ['WEBGL_compressed_texture_pvrtc', 'WEBKIT_WEBGL_compressed_texture_pvrtc']); @@ -487,7 +485,7 @@ define([ */ standardDerivatives : { get : function() { - return this._standardDerivatives; + return this._standardDerivatives || this._webgl2; } }, @@ -514,7 +512,7 @@ define([ */ depthTexture : { get : function() { - return this._depthTexture; + return this._depthTexture || this._webgl2; } }, @@ -527,7 +525,7 @@ define([ */ floatingPointTexture : { get : function() { - return this._textureFloat; + return this._textureFloat || this._webgl2; } }, @@ -601,7 +599,7 @@ define([ */ fragmentDepth : { get : function() { - return this._fragDepth; + return this._fragDepth || this._webgl2; } }, From a67ee53eb4ff0da5c4ef8618974895456a8a30ed Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Wed, 12 Jul 2017 14:28:24 -0400 Subject: [PATCH 018/132] Formatting changes for defines --- Source/Renderer/GLSLModernizer.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Source/Renderer/GLSLModernizer.js b/Source/Renderer/GLSLModernizer.js index 95c373455510..0e4efe038d6b 100644 --- a/Source/Renderer/GLSLModernizer.js +++ b/Source/Renderer/GLSLModernizer.js @@ -1,8 +1,7 @@ -/*global define*/ define([ '../Core/DeveloperError', - ], function( - DeveloperError) { + ], function( + DeveloperError) { 'use strict'; /** From 31077665374167ca764e5b57b81eb12ee6e21c80 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Wed, 12 Jul 2017 14:37:09 -0400 Subject: [PATCH 019/132] Replaces exampleVariable++ with ++exampleVariable in for loops --- Source/Renderer/GLSLModernizer.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Source/Renderer/GLSLModernizer.js b/Source/Renderer/GLSLModernizer.js index 0e4efe038d6b..9fe358bfd6d2 100644 --- a/Source/Renderer/GLSLModernizer.js +++ b/Source/Renderer/GLSLModernizer.js @@ -34,7 +34,7 @@ define([ var outputDeclarationLine = -1; var number; - for (number = 0; number < splitSource.length; number++) { + for (number = 0; number < splitSource.length; ++number) { var line = splitSource[number]; if (outputDeclarationRegex.exec(line)) { outputDeclarationLine = number; @@ -43,7 +43,7 @@ define([ }; if (outputDeclarationLine == -1) { - for (number = 0; number < splitSource.length; number++) { + for (number = 0; number < splitSource.length; ++number) { var line = splitSource[number]; if (mainFunctionRegex.exec(line)) { outputDeclarationLine = number; @@ -110,13 +110,13 @@ define([ } function replaceInSource(regex, replacement) { - for (var number = 0; number < splitSource.length; number++) { + for (var number = 0; number < splitSource.length; ++number) { splitSource[number] = safeNameReplace(regex, splitSource[number], replacement); } } function findInSource(regex) { - for (var number = 0; number < splitSource.length; number++) { + for (var number = 0; number < splitSource.length; ++number) { var line = splitSource[number]; if (safeNameFind(regex, line) !== -1) { return true; @@ -127,7 +127,7 @@ define([ function compileSource() { var wholeSource = ""; - for (var number = 0; number < splitSource.length; number++) { + for (var number = 0; number < splitSource.length; ++number) { wholeSource += splitSource[number] + "\n"; } return wholeSource; @@ -139,7 +139,7 @@ define([ } function setUnion(set1, set2) { - for (var a = 0; a < set2.length; a++) { + for (var a = 0; a < set2.length; ++a) { setAdd(set2[a], set1); } } @@ -148,13 +148,13 @@ define([ var variableMap = {}; var negativeMap = {}; - for (var a = 0; a < variablesThatWeCareAbout.length; a++) { + for (var a = 0; a < variablesThatWeCareAbout.length; ++a) { var variableThatWeCareAbout = variablesThatWeCareAbout[a]; variableMap[variableThatWeCareAbout] = [null]; } var stack = []; - for (var i = 0; i < splitSource.length; i++) { + for (var i = 0; i < splitSource.length; ++i) { var line = splitSource[i]; var hasIF = line.search(/(#ifdef|#if)/g) !== -1; var hasELSE = line.search(/#else/g) !== -1; @@ -176,7 +176,7 @@ define([ } else if (hasENDIF) { stack.pop(); } else if (line.search(/layout/g) === -1) { - for (a = 0; a < variablesThatWeCareAbout.length; a++) { + for (a = 0; a < variablesThatWeCareAbout.length; ++a) { var care = variablesThatWeCareAbout[a]; if (line.indexOf(care) !== -1) { if (variableMap[care].length === 1 && @@ -197,7 +197,7 @@ define([ if (variableMap.hasOwnProperty(care)) { var entry = variableMap[care]; var toDelete = []; - for (var b = 0; b < entry.length; b++) { + for (var b = 0; b < entry.length; ++b) { var item = entry[b]; if (entry.indexOf(negativeMap[item]) !== -1) { toDelete.push(item); @@ -205,7 +205,7 @@ define([ } } - for (var c = 0; c < toDelete.length; c++) { + for (var c = 0; c < toDelete.length; ++c) { var ind = entry.indexOf(toDelete[c]); if (ind !== -1) { entry.splice(ind, 1); From 15433f3f190392be1d62ef81cd14fe875c394673 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Wed, 12 Jul 2017 14:41:14 -0400 Subject: [PATCH 020/132] No more "x characters per line" rule --- Source/Renderer/GLSLModernizer.js | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/Source/Renderer/GLSLModernizer.js b/Source/Renderer/GLSLModernizer.js index 9fe358bfd6d2..a06fa7f1eb62 100644 --- a/Source/Renderer/GLSLModernizer.js +++ b/Source/Renderer/GLSLModernizer.js @@ -14,8 +14,7 @@ define([ */ function glslModernizeShaderSource(shaderSource, isFragmentShader) { for (var i = 0; i < shaderSource.sources.length; i++) { - shaderSource.sources[i] = - glslModernizeShaderText(shaderSource.sources[i], isFragmentShader, i === 0); + shaderSource.sources[i] = glslModernizeShaderText(shaderSource.sources[i], isFragmentShader, i === 0); } shaderSource.defines.push("MODERNIZED"); } @@ -52,9 +51,7 @@ define([ } if (outputDeclarationLine == -1) { - throw new DeveloperError('Could not find a ' + - '#define OUTPUT_DECLARATION ' + - 'nor a main function!'); + throw new DeveloperError('Could not find a #define OUTPUT_DECLARATION nor a main function!'); } function safeNameFalseNegative(regex, region) { @@ -101,11 +98,9 @@ define([ var possiblyFalseNegative = safeNameFalseNegative(regex, region); if (possiblyFalseNegative) { - return region.replace(regex, replacement) + - safeNameReplace(regex, str.substr(endPos), replacement); + return region.replace(regex, replacement) + safeNameReplace(regex, str.substr(endPos), replacement); } else { - return region + - safeNameReplace(regex, str.substr(endPos), replacement); + return region + safeNameReplace(regex, str.substr(endPos), replacement); } } @@ -179,12 +174,10 @@ define([ for (a = 0; a < variablesThatWeCareAbout.length; ++a) { var care = variablesThatWeCareAbout[a]; if (line.indexOf(care) !== -1) { - if (variableMap[care].length === 1 && - variableMap[care][0] === null) { + if (variableMap[care].length === 1 && variableMap[care][0] === null) { variableMap[care] = stack.slice(); } else { - variableMap[care] = variableMap[care].filter( - function(x) { return stack.indexOf(x) >= 0; }); + variableMap[care] = variableMap[care].filter(function(x) { return stack.indexOf(x) >= 0; }); } } } @@ -216,8 +209,7 @@ define([ for (var care in variableMap) { if (variableMap.hasOwnProperty(care)) { - if (variableMap.length === 1 && - variableMap[0] === null) { + if (variableMap.length === 1 && variableMap[0] === null) { variableMap.splice(0, 1); } } @@ -240,9 +232,7 @@ define([ if (source.search(fragDataString) != -1) { setAdd(newOutput, variableSet); replaceInSource(regex, newOutput); - splitSource.splice(outputDeclarationLine, 0, - "layout(location = " + i + ") out vec4 " + - newOutput + ";"); + splitSource.splice(outputDeclarationLine, 0, "layout(location = " + i + ") out vec4 " + newOutput + ";"); outputDeclarationLine += 1; } } @@ -261,8 +251,7 @@ define([ var l = splitSource[c]; for (var care in variableMap) { if (variableMap.hasOwnProperty(care)) { - var matchVar = - new RegExp("(layout)[^]+(out)[^]+(" + care + ")[^]+", "g"); + var matchVar = new RegExp("(layout)[^]+(out)[^]+(" + care + ")[^]+", "g"); if (matchVar.exec(l) !== null) { lineAdds[l] = care; } From ab57d694b6c063efe06db720d036a755f4d2eba7 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Wed, 12 Jul 2017 15:03:54 -0400 Subject: [PATCH 021/132] Removes the MODERNIZED flag --- Source/Renderer/GLSLModernizer.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/Renderer/GLSLModernizer.js b/Source/Renderer/GLSLModernizer.js index a06fa7f1eb62..9ff9999a5b00 100644 --- a/Source/Renderer/GLSLModernizer.js +++ b/Source/Renderer/GLSLModernizer.js @@ -16,7 +16,6 @@ define([ for (var i = 0; i < shaderSource.sources.length; i++) { shaderSource.sources[i] = glslModernizeShaderText(shaderSource.sources[i], isFragmentShader, i === 0); } - shaderSource.defines.push("MODERNIZED"); } // Note that this function requires the presence of the From cf3aaece8f60f1843d7983f96c8f7a90a732cac3 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Wed, 12 Jul 2017 15:06:35 -0400 Subject: [PATCH 022/132] Removes unnecessary console.log --- Source/Renderer/GLSLModernizer.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/Renderer/GLSLModernizer.js b/Source/Renderer/GLSLModernizer.js index 9ff9999a5b00..811620d07a14 100644 --- a/Source/Renderer/GLSLModernizer.js +++ b/Source/Renderer/GLSLModernizer.js @@ -275,8 +275,6 @@ define([ } } - console.log(compileSource()); - if (first === true) { var versionThree = "#version 300 es"; var foundVersion = false; From 3932bf30a76c158de72ac1e27d5819d9717e8413 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Wed, 12 Jul 2017 15:21:20 -0400 Subject: [PATCH 023/132] Replaces search() with test() --- Source/Renderer/GLSLModernizer.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/Renderer/GLSLModernizer.js b/Source/Renderer/GLSLModernizer.js index 811620d07a14..4eee386f89f6 100644 --- a/Source/Renderer/GLSLModernizer.js +++ b/Source/Renderer/GLSLModernizer.js @@ -150,16 +150,16 @@ define([ var stack = []; for (var i = 0; i < splitSource.length; ++i) { var line = splitSource[i]; - var hasIF = line.search(/(#ifdef|#if)/g) !== -1; - var hasELSE = line.search(/#else/g) !== -1; - var hasENDIF = line.search(/#endif/g) !== -1; + var hasIF = /(#ifdef|#if)/g.test(line); + var hasELSE = /#else/g.test(line); + var hasENDIF = /#endif/g.test(line); if (hasIF) { stack.push(line); } else if (hasELSE) { var top = stack[stack.length - 1]; var op = top.replace("ifdef", "ifndef"); - if (op.search(/if/g) !== -1) { + if (/if/g.test(op)) { op = op.replace(/(#if\s+)(\S*)([^]*)/, "$1!($2)$3"); } stack.pop(); @@ -169,7 +169,7 @@ define([ negativeMap[op] = top; } else if (hasENDIF) { stack.pop(); - } else if (line.search(/layout/g) === -1) { + } else if (!/layout/g.test(line)) { for (a = 0; a < variablesThatWeCareAbout.length; ++a) { var care = variablesThatWeCareAbout[a]; if (line.indexOf(care) !== -1) { @@ -228,7 +228,7 @@ define([ var fragDataString = "gl_FragData\\[" + i + "\\]"; var newOutput = 'czm_out' + i; var regex = new RegExp(fragDataString, "g"); - if (source.search(fragDataString) != -1) { + if (regex.test(source)) { setAdd(newOutput, variableSet); replaceInSource(regex, newOutput); splitSource.splice(outputDeclarationLine, 0, "layout(location = " + i + ") out vec4 " + newOutput + ";"); @@ -279,7 +279,7 @@ define([ var versionThree = "#version 300 es"; var foundVersion = false; for (number = 0; number < splitSource.length; number++) { - if (splitSource[number].search(/#version/) != -1) { + if (/#version/.test(splitSource[number])) { splitSource[number] = versionThree; foundVersion = true; } From 2f45796f7aa86df24f666b5aaa042436a8541d06 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 12 Jul 2017 15:26:03 -0400 Subject: [PATCH 024/132] Refactor duplicate code from ClassificationPrimitive and GroundPrimitive. --- Source/Scene/ClassificationPrimitive.js | 104 ++++- Source/Scene/GroundPrimitive.js | 479 ++---------------------- 2 files changed, 122 insertions(+), 461 deletions(-) diff --git a/Source/Scene/ClassificationPrimitive.js b/Source/Scene/ClassificationPrimitive.js index e1319a78f5f6..82955303ab94 100644 --- a/Source/Scene/ClassificationPrimitive.js +++ b/Source/Scene/ClassificationPrimitive.js @@ -168,6 +168,9 @@ define([ this.debugShowShadowVolume = defaultValue(options.debugShowShadowVolume, false); this._debugShowShadowVolume = false; + this._extruded = defaultValue(options._extruded, false); + this._uniformMap = options._uniformMap; + this._sp = undefined; this._spPick = undefined; @@ -180,7 +183,7 @@ define([ this._readyPromise = when.defer(); this._primitive = undefined; - this._pickPrimitive = options.pickPrimitive; + this._pickPrimitive = options._pickPrimitive; var appearance = new PerInstanceColorAppearance({ flat : true @@ -191,6 +194,9 @@ define([ readOnlyAttributes = readOnlyInstanceAttributesScratch; } + this._createBoundingVolumeFunction = options._createBoundingVolumeFunction; + this._updateAndQueueCommandsFunction = options._updateAndQueueCommandsFunction; + this._primitiveOptions = { geometryInstances : undefined, appearance : appearance, @@ -201,9 +207,11 @@ define([ asynchronous : defaultValue(options.asynchronous, true), compressVertices : defaultValue(options.compressVertices, true), _readOnlyInstanceAttributes : readOnlyAttributes, + _createBoundingVolumeFunction : undefined, _createRenderStatesFunction : undefined, _createShaderProgramFunction : undefined, _createCommandsFunction : undefined, + _updateAndQueueCommandsFunction : undefined, _createPickOffsets : true }; } @@ -473,6 +481,34 @@ define([ groundPrimitive._rsPickPass = RenderState.fromCache(pickRenderState); } + function modifyForEncodedNormals(primitive, vertexShaderSource) { + if (!primitive.compressVertices) { + return vertexShaderSource; + } + + if (vertexShaderSource.search(/attribute\s+vec3\s+extrudeDirection;/g) !== -1) { + var attributeName = 'compressedAttributes'; + + //only shadow volumes use extrudeDirection, and shadow volumes use vertexFormat: POSITION_ONLY so we don't need to check other attributes + var attributeDecl = 'attribute vec2 ' + attributeName + ';'; + + var globalDecl = 'vec3 extrudeDirection;\n'; + var decode = ' extrudeDirection = czm_octDecode(' + attributeName + ', 65535.0);\n'; + + var modifiedVS = vertexShaderSource; + modifiedVS = modifiedVS.replace(/attribute\s+vec3\s+extrudeDirection;/g, ''); + modifiedVS = ShaderSource.replaceMain(modifiedVS, 'czm_non_compressed_main'); + var compressedMain = + 'void main() \n' + + '{ \n' + + decode + + ' czm_non_compressed_main(); \n' + + '}'; + + return [attributeDecl, globalDecl, modifiedVS, compressedMain].join('\n'); + } + } + function createShaderProgram(groundPrimitive, frameState, appearance) { if (defined(groundPrimitive._sp)) { return; @@ -487,14 +523,26 @@ define([ vs = Primitive._modifyShaderPosition(groundPrimitive, vs, frameState.scene3DOnly); vs = Primitive._updateColorAttribute(primitive, vs); - var fs = ShadowVolumeFS; + if (groundPrimitive._extruded) { + vs = modifyForEncodedNormals(primitive, vs); + } + + var extrudedDefine = groundPrimitive._extruded ? 'EXTRUDED_GEOMETRY' : ''; + + var vsSource = new ShaderSource({ + defines : [extrudedDefine], + sources : [vs] + }); + var fsSource = new ShaderSource({ + sources : [ShadowVolumeFS] + }); var attributeLocations = groundPrimitive._primitive._attributeLocations; groundPrimitive._sp = ShaderProgram.replaceCache({ context : context, shaderProgram : groundPrimitive._sp, - vertexShaderSource : vs, - fragmentShaderSource : fs, + vertexShaderSource : vsSource, + fragmentShaderSource : fsSource, attributeLocations : attributeLocations }); @@ -502,22 +550,28 @@ define([ var vsPick = ShaderSource.createPickVertexShaderSource(vs); vsPick = Primitive._updatePickColorAttribute(vsPick); + var pickVS = new ShaderSource({ + defines : [extrudedDefine], + sources : [vsPick] + }); + var pickFS = new ShaderSource({ - sources : [fs], + sources : [ShadowVolumeFS], pickColorQualifier : 'varying' }); + groundPrimitive._spPick = ShaderProgram.replaceCache({ context : context, shaderProgram : groundPrimitive._spPick, - vertexShaderSource : vsPick, + vertexShaderSource : pickVS, fragmentShaderSource : pickFS, attributeLocations : attributeLocations }); } else { groundPrimitive._spPick = ShaderProgram.fromCache({ context : context, - vertexShaderSource : vs, - fragmentShaderSource : fs, + vertexShaderSource : vsSource, + fragmentShaderSource : fsSource, attributeLocations : attributeLocations }); } @@ -529,7 +583,7 @@ define([ colorCommands.length = length; var vaIndex = 0; - var uniformMap = primitive._batchTable.getUniformMapCallback()(); + var uniformMap = primitive._batchTable.getUniformMapCallback()(groundPrimitive._uniformMap); for (var i = 0; i < length; i += 3) { var vertexArray = primitive._va[vaIndex++]; @@ -588,7 +642,7 @@ define([ pickCommands.length = length; var pickIndex = 0; - var uniformMap = primitive._batchTable.getUniformMapCallback()(); + var uniformMap = primitive._batchTable.getUniformMapCallback()(groundPrimitive._uniformMap); for (var j = 0; j < length; j += 3) { var pickOffset = pickOffsets[pickIndex++]; @@ -656,8 +710,10 @@ define([ } function updateAndQueueCommands(groundPrimitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { - var boundingVolumes; var primitive = groundPrimitive._primitive; + + /* + var boundingVolumes; if (frameState.mode === SceneMode.SCENE3D) { boundingVolumes = primitive._boundingSphereWC; } else if (frameState.mode === SceneMode.COLUMBUS_VIEW) { @@ -667,6 +723,7 @@ define([ } else if (defined(primitive._boundingSphereMorph)) { boundingVolumes = primitive._boundingSphereMorph; } + */ var commandList = frameState.commandList; var passes = frameState.passes; @@ -689,12 +746,10 @@ define([ pickCommands.length = length; for (var j = 0; j < length; ++j) { - var pickOffset = pickOffsets[Math.floor(j / 3)]; - var bv = boundingVolumes[pickOffset.index]; - + //var pickOffset = pickOffsets[Math.floor(j / 3)]; var pickCommand = pickCommands[j]; pickCommand.modelMatrix = modelMatrix; - pickCommand.boundingVolume = undefined;//bv; + pickCommand.boundingVolume = undefined;//boundingVolumes[pickOffset.index]; pickCommand.cull = cull; commandList.push(pickCommand); @@ -757,6 +812,12 @@ define([ primitiveOptions.geometryInstances = geometryInstances; + if (defined(this._createBoundingVolumeFunction)) { + primitiveOptions._createBoundingVolumeFunction = function(frameState, geometry) { + that._createBoundingVolumeFunction(frameState, geometry); + }; + } + primitiveOptions._createRenderStatesFunction = function(primitive, context, appearance, twoPasses) { createRenderStates(that, context); }; @@ -766,9 +827,16 @@ define([ primitiveOptions._createCommandsFunction = function(primitive, appearance, material, translucent, twoPasses, colorCommands, pickCommands) { createCommands(that, undefined, undefined, true, false, colorCommands, pickCommands); }; - primitiveOptions._updateAndQueueCommandsFunction = function(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { - updateAndQueueCommands(that, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses); - }; + + if (defined(this._updateAndQueueCommandsFunction)) { + primitiveOptions._updateAndQueueCommandsFunction = function(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { + that._updateAndQueueCommandsFunction(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses); + }; + } else { + primitiveOptions._updateAndQueueCommandsFunction = function(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { + updateAndQueueCommands(that, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses); + }; + } this._primitive = new Primitive(primitiveOptions); this._primitive.readyPromise.then(function(primitive) { diff --git a/Source/Scene/GroundPrimitive.js b/Source/Scene/GroundPrimitive.js index de1327c1e2cc..2c8b21276278 100644 --- a/Source/Scene/GroundPrimitive.js +++ b/Source/Scene/GroundPrimitive.js @@ -26,6 +26,7 @@ define([ '../Shaders/ShadowVolumeVS', '../ThirdParty/when', './BlendingState', + './ClassificationPrimitive', './DepthFunction', './PerInstanceColorAppearance', './Primitive', @@ -60,6 +61,7 @@ define([ ShadowVolumeVS, when, BlendingState, + ClassificationPrimitive, DepthFunction, PerInstanceColorAppearance, Primitive, @@ -68,7 +70,12 @@ define([ StencilOperation) { 'use strict'; - var readOnlyInstanceAttributesScratch = ['color']; + var GroundPrimitiveReadOnlyInstanceAttributes = ['color']; + var GroundPrimitiveUniformMap = { + u_globeMinimumAltitude: function() { + return 55000.0; + } + }; /** * A ground primitive represents geometry draped over the terrain in the {@link Scene}. The geometry must be from a single {@link GeometryInstance}. @@ -202,21 +209,6 @@ define([ * @default false */ this.debugShowShadowVolume = defaultValue(options.debugShowShadowVolume, false); - this._debugShowShadowVolume = false; - - this._sp = undefined; - this._spPick = undefined; - - this._rsStencilPreloadPass = undefined; - this._rsStencilDepthPass = undefined; - this._rsColorPass = undefined; - this._rsPickPass = undefined; - - this._uniformMap = { - u_globeMinimumAltitude: function() { - return 55000.0; - } - }; this._boundingVolumes = []; this._boundingVolumes2D = []; @@ -235,18 +227,14 @@ define([ this._boundingSpheresKeys = []; this._boundingSpheres = []; - var appearance = new PerInstanceColorAppearance({ - flat : true - }); - var readOnlyAttributes; if (defined(this.geometryInstances) && isArray(this.geometryInstances) && this.geometryInstances.length > 1) { - readOnlyAttributes = readOnlyInstanceAttributesScratch; + readOnlyAttributes = GroundPrimitiveReadOnlyInstanceAttributes; } + var that = this; this._primitiveOptions = { geometryInstances : undefined, - appearance : appearance, vertexCacheOptimize : defaultValue(options.vertexCacheOptimize, false), interleave : defaultValue(options.interleave, false), releaseGeometryInstances : defaultValue(options.releaseGeometryInstances, true), @@ -254,10 +242,11 @@ define([ asynchronous : defaultValue(options.asynchronous, true), compressVertices : defaultValue(options.compressVertices, true), _readOnlyInstanceAttributes : readOnlyAttributes, - _createRenderStatesFunction : undefined, - _createShaderProgramFunction : undefined, - _createCommandsFunction : undefined, - _createPickOffsets : true + _createBoundingVolumeFunction : undefined, + _updateAndQueueCommandsFunction : undefined, + _pickPrimitive : that, + _extruded : true, + _uniformMap : GroundPrimitiveUniformMap }; } @@ -393,9 +382,7 @@ define([ * @param {Scene} scene The scene. * @returns {Boolean} true if GroundPrimitives are supported; otherwise, returns false */ - GroundPrimitive.isSupported = function(scene) { - return scene.context.stencilBuffer; - }; + GroundPrimitive.isSupported = ClassificationPrimitive.isSupported; GroundPrimitive._defaultMaxTerrainHeight = 9000.0; GroundPrimitive._defaultMinTerrainHeight = -100000.0; @@ -417,123 +404,6 @@ define([ }; } - function getStencilPreloadRenderState(enableStencil) { - return { - colorMask : { - red : false, - green : false, - blue : false, - alpha : false - }, - stencilTest : { - enabled : enableStencil, - frontFunction : StencilFunction.ALWAYS, - frontOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.DECREMENT_WRAP, - zPass : StencilOperation.DECREMENT_WRAP - }, - backFunction : StencilFunction.ALWAYS, - backOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.INCREMENT_WRAP, - zPass : StencilOperation.INCREMENT_WRAP - }, - reference : 0, - mask : ~0 - }, - depthTest : { - enabled : false - }, - depthMask : false - }; - } - - function getStencilDepthRenderState(enableStencil) { - return { - colorMask : { - red : false, - green : false, - blue : false, - alpha : false - }, - stencilTest : { - enabled : enableStencil, - frontFunction : StencilFunction.ALWAYS, - frontOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.INCREMENT_WRAP - }, - backFunction : StencilFunction.ALWAYS, - backOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.DECREMENT_WRAP - }, - reference : 0, - mask : ~0 - }, - depthTest : { - enabled : true, - func : DepthFunction.LESS_OR_EQUAL - }, - depthMask : false - }; - } - - - function getColorRenderState(enableStencil) { - return { - stencilTest : { - enabled : enableStencil, - frontFunction : StencilFunction.NOT_EQUAL, - frontOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.DECREMENT_WRAP - }, - backFunction : StencilFunction.NOT_EQUAL, - backOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.DECREMENT_WRAP - }, - reference : 0, - mask : ~0 - }, - depthTest : { - enabled : false - }, - depthMask : false, - blending : BlendingState.ALPHA_BLEND - }; - } - - var pickRenderState = { - stencilTest : { - enabled : true, - frontFunction : StencilFunction.NOT_EQUAL, - frontOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.DECREMENT_WRAP - }, - backFunction : StencilFunction.NOT_EQUAL, - backOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.DECREMENT_WRAP - }, - reference : 0, - mask : ~0 - }, - depthTest : { - enabled : false - }, - depthMask : false - }; - var scratchBVCartesianHigh = new Cartesian3(); var scratchBVCartesianLow = new Cartesian3(); var scratchBVCartesian = new Cartesian3(); @@ -717,240 +587,6 @@ define([ } } - function createRenderStates(groundPrimitive, context, appearance, twoPasses) { - if (defined(groundPrimitive._rsStencilPreloadPass)) { - return; - } - var stencilEnabled = !groundPrimitive.debugShowShadowVolume; - - groundPrimitive._rsStencilPreloadPass = RenderState.fromCache(getStencilPreloadRenderState(stencilEnabled)); - groundPrimitive._rsStencilDepthPass = RenderState.fromCache(getStencilDepthRenderState(stencilEnabled)); - groundPrimitive._rsColorPass = RenderState.fromCache(getColorRenderState(stencilEnabled)); - groundPrimitive._rsPickPass = RenderState.fromCache(pickRenderState); - } - - function modifyForEncodedNormals(primitive, vertexShaderSource) { - if (!primitive.compressVertices) { - return vertexShaderSource; - } - - if (vertexShaderSource.search(/attribute\s+vec3\s+extrudeDirection;/g) !== -1) { - var attributeName = 'compressedAttributes'; - - //only shadow volumes use extrudeDirection, and shadow volumes use vertexFormat: POSITION_ONLY so we don't need to check other attributes - var attributeDecl = 'attribute vec2 ' + attributeName + ';'; - - var globalDecl = 'vec3 extrudeDirection;\n'; - var decode = ' extrudeDirection = czm_octDecode(' + attributeName + ', 65535.0);\n'; - - var modifiedVS = vertexShaderSource; - modifiedVS = modifiedVS.replace(/attribute\s+vec3\s+extrudeDirection;/g, ''); - modifiedVS = ShaderSource.replaceMain(modifiedVS, 'czm_non_compressed_main'); - var compressedMain = - 'void main() \n' + - '{ \n' + - decode + - ' czm_non_compressed_main(); \n' + - '}'; - - return [attributeDecl, globalDecl, modifiedVS, compressedMain].join('\n'); - } - } - - function createShaderProgram(groundPrimitive, frameState, appearance) { - if (defined(groundPrimitive._sp)) { - return; - } - - var context = frameState.context; - var primitive = groundPrimitive._primitive; - var vs = ShadowVolumeVS; - vs = groundPrimitive._primitive._batchTable.getVertexShaderCallback()(vs); - vs = Primitive._appendShowToShader(primitive, vs); - vs = Primitive._appendDistanceDisplayConditionToShader(primitive, vs); - vs = Primitive._modifyShaderPosition(groundPrimitive, vs, frameState.scene3DOnly); - vs = Primitive._updateColorAttribute(primitive, vs); - vs = modifyForEncodedNormals(primitive, vs); - - var vsSource = new ShaderSource({ - defines : ['EXTRUDED_GEOMETRY'], - sources : [vs] - }); - var fsSource = new ShaderSource({ - sources : [ShadowVolumeFS] - }); - var attributeLocations = groundPrimitive._primitive._attributeLocations; - - groundPrimitive._sp = ShaderProgram.replaceCache({ - context : context, - shaderProgram : groundPrimitive._sp, - vertexShaderSource : vsSource, - fragmentShaderSource : fsSource, - attributeLocations : attributeLocations - }); - - if (groundPrimitive._primitive.allowPicking) { - var vsPick = ShaderSource.createPickVertexShaderSource(vs); - vsPick = Primitive._updatePickColorAttribute(vsPick); - - var pickVS = new ShaderSource({ - defines : ['EXTRUDED_GEOMETRY'], - sources : [vsPick] - }); - - var pickFS = new ShaderSource({ - sources : [ShadowVolumeFS], - pickColorQualifier : 'varying' - }); - groundPrimitive._spPick = ShaderProgram.replaceCache({ - context : context, - shaderProgram : groundPrimitive._spPick, - vertexShaderSource : pickVS, - fragmentShaderSource : pickFS, - attributeLocations : attributeLocations - }); - } else { - groundPrimitive._spPick = ShaderProgram.fromCache({ - context : context, - vertexShaderSource : vsSource, - fragmentShaderSource : fsSource, - attributeLocations : attributeLocations - }); - } - } - - function createColorCommands(groundPrimitive, colorCommands) { - var primitive = groundPrimitive._primitive; - var length = primitive._va.length * 3; - colorCommands.length = length; - - var vaIndex = 0; - var uniformMap = primitive._batchTable.getUniformMapCallback()(groundPrimitive._uniformMap); - - for (var i = 0; i < length; i += 3) { - var vertexArray = primitive._va[vaIndex++]; - - // stencil preload command - var command = colorCommands[i]; - if (!defined(command)) { - command = colorCommands[i] = new DrawCommand({ - owner : groundPrimitive, - primitiveType : primitive._primitiveType - }); - } - - command.vertexArray = vertexArray; - command.renderState = groundPrimitive._rsStencilPreloadPass; - command.shaderProgram = groundPrimitive._sp; - command.uniformMap = uniformMap; - command.pass = Pass.GROUND; - - // stencil depth command - command = colorCommands[i + 1]; - if (!defined(command)) { - command = colorCommands[i + 1] = new DrawCommand({ - owner : groundPrimitive, - primitiveType : primitive._primitiveType - }); - } - - command.vertexArray = vertexArray; - command.renderState = groundPrimitive._rsStencilDepthPass; - command.shaderProgram = groundPrimitive._sp; - command.uniformMap = uniformMap; - command.pass = Pass.GROUND; - - // color command - command = colorCommands[i + 2]; - if (!defined(command)) { - command = colorCommands[i + 2] = new DrawCommand({ - owner : groundPrimitive, - primitiveType : primitive._primitiveType - }); - } - - command.vertexArray = vertexArray; - command.renderState = groundPrimitive._rsColorPass; - command.shaderProgram = groundPrimitive._sp; - command.uniformMap = uniformMap; - command.pass = Pass.GROUND; - } - } - - function createPickCommands(groundPrimitive, pickCommands) { - var primitive = groundPrimitive._primitive; - var pickOffsets = primitive._pickOffsets; - var length = pickOffsets.length * 3; - pickCommands.length = length; - - var pickIndex = 0; - var uniformMap = primitive._batchTable.getUniformMapCallback()(groundPrimitive._uniformMap); - - for (var j = 0; j < length; j += 3) { - var pickOffset = pickOffsets[pickIndex++]; - - var offset = pickOffset.offset; - var count = pickOffset.count; - var vertexArray = primitive._va[pickOffset.index]; - - // stencil preload command - var command = pickCommands[j]; - if (!defined(command)) { - command = pickCommands[j] = new DrawCommand({ - owner : groundPrimitive, - primitiveType : primitive._primitiveType - }); - } - - command.vertexArray = vertexArray; - command.offset = offset; - command.count = count; - command.renderState = groundPrimitive._rsStencilPreloadPass; - command.shaderProgram = groundPrimitive._sp; - command.uniformMap = uniformMap; - command.pass = Pass.GROUND; - - // stencil depth command - command = pickCommands[j + 1]; - if (!defined(command)) { - command = pickCommands[j + 1] = new DrawCommand({ - owner : groundPrimitive, - primitiveType : primitive._primitiveType - }); - } - - command.vertexArray = vertexArray; - command.offset = offset; - command.count = count; - command.renderState = groundPrimitive._rsStencilDepthPass; - command.shaderProgram = groundPrimitive._sp; - command.uniformMap = uniformMap; - command.pass = Pass.GROUND; - - // color command - command = pickCommands[j + 2]; - if (!defined(command)) { - command = pickCommands[j + 2] = new DrawCommand({ - owner : groundPrimitive, - primitiveType : primitive._primitiveType - }); - } - - command.vertexArray = vertexArray; - command.offset = offset; - command.count = count; - command.renderState = groundPrimitive._rsPickPass; - command.shaderProgram = groundPrimitive._spPick; - command.uniformMap = uniformMap; - command.pass = Pass.GROUND; - } - } - - function createCommands(groundPrimitive, appearance, material, translucent, twoPasses, colorCommands, pickCommands) { - createColorCommands(groundPrimitive, colorCommands); - createPickCommands(groundPrimitive, pickCommands); - } - function updateAndQueueCommands(groundPrimitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { var boundingVolumes; if (frameState.mode === SceneMode.SCENE3D) { @@ -963,40 +599,33 @@ define([ var passes = frameState.passes; if (passes.render) { var colorLength = colorCommands.length; - for (var j = 0; j < colorLength; ++j) { - colorCommands[j].modelMatrix = modelMatrix; - colorCommands[j].boundingVolume = boundingVolumes[Math.floor(j / 3)]; - colorCommands[j].cull = cull; - colorCommands[j].debugShowBoundingVolume = debugShowBoundingVolume; - - commandList.push(colorCommands[j]); + for (var i = 0; i < colorLength; ++i) { + var colorCommand = colorCommands[i]; + colorCommand.modelMatrix = modelMatrix; + colorCommand.boundingVolume = boundingVolumes[Math.floor(i / 3)]; + colorCommand.cull = cull; + colorCommand.debugShowBoundingVolume = debugShowBoundingVolume; + + commandList.push(colorCommand); } } if (passes.pick) { - var primitive = groundPrimitive._primitive; + var primitive = groundPrimitive._primitive._primitive; var pickOffsets = primitive._pickOffsets; var length = pickOffsets.length * 3; pickCommands.length = length; - var pickIndex = 0; - for (var k = 0; k < length; k += 3) { - var pickOffset = pickOffsets[pickIndex++]; + for (var j = 0; j < length; ++j) { + var pickOffset = pickOffsets[Math.floor(j / 3)]; var bv = boundingVolumes[pickOffset.index]; - pickCommands[k].modelMatrix = modelMatrix; - pickCommands[k].boundingVolume = bv; - pickCommands[k].cull = cull; - - pickCommands[k + 1].modelMatrix = modelMatrix; - pickCommands[k + 1].boundingVolume = bv; - pickCommands[k + 1].cull = cull; - - pickCommands[k + 2].modelMatrix = modelMatrix; - pickCommands[k + 2].boundingVolume = bv; - pickCommands[k + 2].cull = cull; + var pickCommand = pickCommands[j]; + pickCommand.modelMatrix = modelMatrix; + pickCommand.boundingVolume = bv; + pickCommand.cull = cull; - commandList.push(pickCommands[k], pickCommands[k + 1], pickCommands[k + 2]); + commandList.push(pickCommand); } } } @@ -1068,7 +697,6 @@ define([ var groundInstances = new Array(length); var i; - var color; var rectangle; for (i = 0; i < length; ++i) { instance = instances[i]; @@ -1088,19 +716,7 @@ define([ } instanceType = geometry.constructor; - if (defined(instanceType) && defined(instanceType.createShadowVolume)) { - var attributes = instance.attributes; - - //>>includeStart('debug', pragmas.debug); - if (!defined(attributes) || !defined(attributes.color)) { - throw new DeveloperError('Not all of the geometry instances have the same color attribute.'); - } else if (defined(color) && !ColorGeometryInstanceAttribute.equals(color, attributes.color)) { - throw new DeveloperError('Not all of the geometry instances have the same color attribute.'); - } else if (!defined(color)) { - color = attributes.color; - } - //>>includeEnd('debug'); - } else { + if (!defined(instanceType) || !defined(instanceType.createShadowVolume)) { //>>includeStart('debug', pragmas.debug); throw new DeveloperError('Not all of the geometry instances have GroundPrimitive support.'); //>>includeEnd('debug'); @@ -1121,8 +737,7 @@ define([ geometry : instanceType.createShadowVolume(geometry, getComputeMinimumHeightFunction(this), getComputeMaximumHeightFunction(this)), attributes : instance.attributes, - id : instance.id, - pickPrimitive : this + id : instance.id }); } @@ -1131,20 +746,11 @@ define([ primitiveOptions._createBoundingVolumeFunction = function(frameState, geometry) { createBoundingVolume(that, frameState, geometry); }; - primitiveOptions._createRenderStatesFunction = function(primitive, context, appearance, twoPasses) { - createRenderStates(that, context); - }; - primitiveOptions._createShaderProgramFunction = function(primitive, frameState, appearance) { - createShaderProgram(that, frameState); - }; - primitiveOptions._createCommandsFunction = function(primitive, appearance, material, translucent, twoPasses, colorCommands, pickCommands) { - createCommands(that, undefined, undefined, true, false, colorCommands, pickCommands); - }; primitiveOptions._updateAndQueueCommandsFunction = function(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { updateAndQueueCommands(that, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses); }; - this._primitive = new Primitive(primitiveOptions); + this._primitive = new ClassificationPrimitive(primitiveOptions); this._primitive.readyPromise.then(function(primitive) { that._ready = true; @@ -1161,18 +767,7 @@ define([ }); } - if (this.debugShowShadowVolume && !this._debugShowShadowVolume && this._ready) { - this._debugShowShadowVolume = true; - this._rsStencilPreloadPass = RenderState.fromCache(getStencilPreloadRenderState(false)); - this._rsStencilDepthPass = RenderState.fromCache(getStencilDepthRenderState(false)); - this._rsColorPass = RenderState.fromCache(getColorRenderState(false)); - } else if (!this.debugShowShadowVolume && this._debugShowShadowVolume) { - this._debugShowShadowVolume = false; - this._rsStencilPreloadPass = RenderState.fromCache(getStencilPreloadRenderState(true)); - this._rsStencilDepthPass = RenderState.fromCache(getStencilDepthRenderState(true)); - this._rsColorPass = RenderState.fromCache(getColorRenderState(true)); - } - + this._primitive.debugShowShadowVolume = this.debugShowShadowVolume; this._primitive.debugShowBoundingVolume = this.debugShowBoundingVolume; this._primitive.update(frameState); }; @@ -1246,8 +841,6 @@ define([ */ GroundPrimitive.prototype.destroy = function() { this._primitive = this._primitive && this._primitive.destroy(); - this._sp = this._sp && this._sp.destroy(); - this._spPick = this._spPick && this._spPick.destroy(); return destroyObject(this); }; From 7a844e10dbfa4b61343d8fcf7c30998c445d1bc1 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Wed, 12 Jul 2017 15:33:48 -0400 Subject: [PATCH 025/132] Now passing context into ShaderSource instead of context.webgl2 --- Source/Renderer/ShaderCache.js | 8 ++++---- Source/Renderer/ShaderSource.js | 16 ++++++++-------- Specs/Renderer/ShaderSourceSpec.js | 24 ++++++++++++++++++------ 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/Source/Renderer/ShaderCache.js b/Source/Renderer/ShaderCache.js index 1720fd5c3f51..70092c6954f0 100644 --- a/Source/Renderer/ShaderCache.js +++ b/Source/Renderer/ShaderCache.js @@ -96,8 +96,8 @@ define([ }); } - var vertexShaderText = vertexShaderSource.createCombinedVertexShader(this._context.webgl2); - var fragmentShaderText = fragmentShaderSource.createCombinedFragmentShader(this._context.webgl2); + var vertexShaderText = vertexShaderSource.createCombinedVertexShader(this._context); + var fragmentShaderText = fragmentShaderSource.createCombinedFragmentShader(this._context); var keyword = vertexShaderText + fragmentShaderText + JSON.stringify(attributeLocations); var cachedShader; @@ -171,8 +171,8 @@ define([ var context = this._context; - var vertexShaderText = vertexShaderSource.createCombinedVertexShader(context.webgl2); - var fragmentShaderText = fragmentShaderSource.createCombinedFragmentShader(context.webgl2); + var vertexShaderText = vertexShaderSource.createCombinedVertexShader(context); + var fragmentShaderText = fragmentShaderSource.createCombinedFragmentShader(context); var derivedShaderProgram = new ShaderProgram({ gl : context._gl, diff --git a/Source/Renderer/ShaderSource.js b/Source/Renderer/ShaderSource.js index b99ff5ee75ec..f8f9b9e843b3 100644 --- a/Source/Renderer/ShaderSource.js +++ b/Source/Renderer/ShaderSource.js @@ -153,7 +153,7 @@ define([ return builtinsSource.replace(root.glslSource, ''); } - function combineShader(shaderSource, isFragmentShader, webgl2) { + function combineShader(shaderSource, isFragmentShader, context) { var i; var length; @@ -255,7 +255,7 @@ define([ result += combinedSources; // modernize the source - if (webgl2) { + if (context.webgl2) { result = GLSLModernizer.glslModernizeShaderText(result, isFragmentShader, true); @@ -323,23 +323,23 @@ define([ /** * Create a single string containing the full, combined vertex shader with all dependencies and defines. * - * @param {Boolean} [webgl2] A boolean parameter which is true if the context is using WebGL 2, false otherwise + * @param {Object} [context] The current rendering context * * @returns {String} The combined shader string. */ - ShaderSource.prototype.createCombinedVertexShader = function(webgl2) { - return combineShader(this, false, webgl2); + ShaderSource.prototype.createCombinedVertexShader = function(context) { + return combineShader(this, false, context); }; /** * Create a single string containing the full, combined fragment shader with all dependencies and defines. * - * @param {Boolean} [webgl2] A boolean parameter which is true if the context is using WebGL 2, false otherwise + * @param {Object} [context] The current rendering context * * @returns {String} The combined shader string. */ - ShaderSource.prototype.createCombinedFragmentShader = function(webgl2) { - return combineShader(this, true, webgl2); + ShaderSource.prototype.createCombinedFragmentShader = function(context) { + return combineShader(this, true, context); }; /** diff --git a/Specs/Renderer/ShaderSourceSpec.js b/Specs/Renderer/ShaderSourceSpec.js index 3fa7fbaef0e5..912d45c5d05f 100644 --- a/Specs/Renderer/ShaderSourceSpec.js +++ b/Specs/Renderer/ShaderSourceSpec.js @@ -9,7 +9,9 @@ defineSuite([ defines : ['A', 'B', ''] }); - var shaderText = source.createCombinedVertexShader(false); + var shaderText = source.createCombinedVertexShader({ + webgl2: false + }); expect(shaderText).toContain('#define A'); expect(shaderText).toContain('#define B'); expect(shaderText.match(/#define/g).length).toEqual(2); @@ -19,7 +21,9 @@ defineSuite([ var source = new ShaderSource({ sources : ['void func() {}', 'void main() {}'] }); - var shaderText = source.createCombinedVertexShader(false); + var shaderText = source.createCombinedVertexShader({ + webgl2: false + }); expect(shaderText).toContain('#line 0\nvoid func() {}'); expect(shaderText).toContain('#line 0\nvoid main() {}'); }); @@ -29,7 +33,9 @@ defineSuite([ defines : ['A', 'B', ''], sources : ['void func() {}', 'void main() {}'] }); - var shaderText = source.createCombinedVertexShader(false); + var shaderText = source.createCombinedVertexShader({ + webgl2: false + }); expect(shaderText).toContain('#define A'); expect(shaderText).toContain('#define B'); expect(shaderText.match(/#define/g).length).toEqual(2); @@ -42,7 +48,9 @@ defineSuite([ sources : ['void main() { gl_FragColor = vec4(1.0); }'], pickColorQualifier : 'uniform' }); - var shaderText = source.createCombinedVertexShader(false); + var shaderText = source.createCombinedVertexShader({ + webgl2: false + }); expect(shaderText).toContain('uniform vec4 czm_pickColor;'); expect(shaderText).toContain('gl_FragColor = czm_pickColor;'); }); @@ -52,7 +60,9 @@ defineSuite([ sources : ['void main() { gl_FragColor = vec4(1.0); }'], pickColorQualifier : 'varying' }); - var shaderText = source.createCombinedVertexShader(false); + var shaderText = source.createCombinedVertexShader({ + webgl2: false + }); expect(shaderText).toContain('varying vec4 czm_pickColor;'); expect(shaderText).toContain('gl_FragColor = czm_pickColor;'); }); @@ -69,7 +79,9 @@ defineSuite([ var source = new ShaderSource({ sources : ['#version 300 es\nvoid main() {gl_FragColor = vec4(1.0); }'] }); - var shaderText = source.createCombinedVertexShader(); + var shaderText = source.createCombinedVertexShader(({ + webgl2: false + }); expect(shaderText).toStartWith('#version 300 es\n'); }); }); From a16652fc034e9aa986c8a57e7386bbbfe7ea7d41 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Wed, 12 Jul 2017 15:35:18 -0400 Subject: [PATCH 026/132] Fixes comment --- Source/Renderer/ShaderSource.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Renderer/ShaderSource.js b/Source/Renderer/ShaderSource.js index f8f9b9e843b3..1d58052b4853 100644 --- a/Source/Renderer/ShaderSource.js +++ b/Source/Renderer/ShaderSource.js @@ -188,7 +188,7 @@ define([ return '\n'; }); - // Extract existing shader version from sources + // Extract shader extensions from sources var extensions = []; combinedSources = combinedSources.replace(/#extension\s+(.*?)\n/gm, function(match, group1) { // Extract extension to put at the top From 9b076e74aff15f65d5dec58723e4ca9e7f75a88d Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Wed, 12 Jul 2017 15:39:33 -0400 Subject: [PATCH 027/132] Slightly more concise regex --- Source/Renderer/ShaderSource.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Renderer/ShaderSource.js b/Source/Renderer/ShaderSource.js index 1d58052b4853..4b67f0b34e2e 100644 --- a/Source/Renderer/ShaderSource.js +++ b/Source/Renderer/ShaderSource.js @@ -190,7 +190,7 @@ define([ // Extract shader extensions from sources var extensions = []; - combinedSources = combinedSources.replace(/#extension\s+(.*?)\n/gm, function(match, group1) { + combinedSources = combinedSources.replace(/#extension.*\n/gm, function(match) { // Extract extension to put at the top extensions.push(match); From 0901e1d082b481e0d5c04e64028b1b76c949310f Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Wed, 12 Jul 2017 15:40:40 -0400 Subject: [PATCH 028/132] Fixes length check --- Source/Renderer/ShaderSource.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Renderer/ShaderSource.js b/Source/Renderer/ShaderSource.js index 4b67f0b34e2e..972621f188e4 100644 --- a/Source/Renderer/ShaderSource.js +++ b/Source/Renderer/ShaderSource.js @@ -217,7 +217,8 @@ define([ result = '#version ' + version + '\n'; } - for (i = 0; i < extensions.length; i++) { + var extensionsLength = extensions.length; + for (i = 0; i < extensionsLength; i++) { result += extensions[i]; } From 97db097ff3a51395b8601de4fe93b58c86a916af Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Wed, 12 Jul 2017 15:41:26 -0400 Subject: [PATCH 029/132] Formatting fixes --- Source/Renderer/ShaderSource.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Source/Renderer/ShaderSource.js b/Source/Renderer/ShaderSource.js index 972621f188e4..c69a6b38e35c 100644 --- a/Source/Renderer/ShaderSource.js +++ b/Source/Renderer/ShaderSource.js @@ -257,9 +257,7 @@ define([ // modernize the source if (context.webgl2) { - result = GLSLModernizer.glslModernizeShaderText(result, - isFragmentShader, - true); + result = GLSLModernizer.glslModernizeShaderText(result, isFragmentShader, true); } return result; From 78fa9bb0369ae92373066bd3f9bc1499e4070275 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Wed, 12 Jul 2017 15:42:30 -0400 Subject: [PATCH 030/132] Fixes switch statement case indentation --- Source/Renderer/Texture.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Source/Renderer/Texture.js b/Source/Renderer/Texture.js index 915e73c6d389..910ed3369a87 100644 --- a/Source/Renderer/Texture.js +++ b/Source/Renderer/Texture.js @@ -74,15 +74,15 @@ define([ if (pixelDatatype == PixelDatatype.FLOAT) { switch (pixelFormat) { - case PixelFormat.RGBA: - internalFormat = WebGLConstants.RGBA32F; - break; - case PixelFormat.RG: - internalFormat = WebGLConstants.RG32F; - break; - case PixelFormat.R: - internalFormat = WebGLConstants.R32F; - break; + case PixelFormat.RGBA: + internalFormat = WebGLConstants.RGBA32F; + break; + case PixelFormat.RG: + internalFormat = WebGLConstants.RG32F; + break; + case PixelFormat.R: + internalFormat = WebGLConstants.R32F; + break; } } } From bf07d1c178f1a85c1db6e505f2842255fca79789 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Wed, 12 Jul 2017 15:43:54 -0400 Subject: [PATCH 031/132] Changes the last few == operators to === operators --- Source/Renderer/GLSLModernizer.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Renderer/GLSLModernizer.js b/Source/Renderer/GLSLModernizer.js index 4eee386f89f6..f387459fa069 100644 --- a/Source/Renderer/GLSLModernizer.js +++ b/Source/Renderer/GLSLModernizer.js @@ -40,7 +40,7 @@ define([ } }; - if (outputDeclarationLine == -1) { + if (outputDeclarationLine === -1) { for (number = 0; number < splitSource.length; ++number) { var line = splitSource[number]; if (mainFunctionRegex.exec(line)) { @@ -49,7 +49,7 @@ define([ }; } - if (outputDeclarationLine == -1) { + if (outputDeclarationLine === -1) { throw new DeveloperError('Could not find a #define OUTPUT_DECLARATION nor a main function!'); } @@ -68,7 +68,7 @@ define([ function safeNameFind(regex, str) { var originalMatch = regex.exec(str); - if (originalMatch == null) { + if (originalMatch === null) { return -1; } var endPos = originalMatch.index + originalMatch[0].length; @@ -79,7 +79,7 @@ define([ return endPos; } else { var childResult = safeNameFind(regex, str.substring(endPos)); - if (childResult == -1) { + if (childResult === -1) { return -1; } else { return endPos + childResult; @@ -89,7 +89,7 @@ define([ function safeNameReplace(regex, str, replacement) { var originalMatch = regex.exec(str); - if (originalMatch == null) { + if (originalMatch === null) { return str; } var endPos = originalMatch.index + originalMatch[0].length; From 3d1ddc06bf97204a17ad1ab8000e25e8e25949c5 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 12 Jul 2017 15:49:19 -0400 Subject: [PATCH 032/132] Clean up requires and variable renames. --- Source/Scene/ClassificationPrimitive.js | 124 ++++++++++-------------- Source/Scene/GroundPrimitive.js | 41 +------- 2 files changed, 56 insertions(+), 109 deletions(-) diff --git a/Source/Scene/ClassificationPrimitive.js b/Source/Scene/ClassificationPrimitive.js index 82955303ab94..fd5da594cba2 100644 --- a/Source/Scene/ClassificationPrimitive.js +++ b/Source/Scene/ClassificationPrimitive.js @@ -1,23 +1,13 @@ /*global define*/ define([ - '../Core/BoundingSphere', - '../Core/buildModuleUrl', - '../Core/Cartesian2', - '../Core/Cartesian3', - '../Core/Cartographic', '../Core/ColorGeometryInstanceAttribute', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/destroyObject', '../Core/DeveloperError', - '../Core/GeographicTilingScheme', '../Core/GeometryInstance', '../Core/isArray', - '../Core/loadJson', - '../Core/Math', - '../Core/OrientedBoundingBox', - '../Core/Rectangle', '../Renderer/DrawCommand', '../Renderer/Pass', '../Renderer/RenderState', @@ -34,24 +24,14 @@ define([ './StencilFunction', './StencilOperation' ], function( - BoundingSphere, - buildModuleUrl, - Cartesian2, - Cartesian3, - Cartographic, ColorGeometryInstanceAttribute, defaultValue, defined, defineProperties, destroyObject, DeveloperError, - GeographicTilingScheme, GeometryInstance, isArray, - loadJson, - CesiumMath, - OrientedBoundingBox, - Rectangle, DrawCommand, Pass, RenderState, @@ -69,7 +49,7 @@ define([ StencilOperation) { 'use strict'; - var readOnlyInstanceAttributesScratch = ['color']; + var ClassificationPrimitiveReadOnlyInstanceAttributes = ['color']; /** * A classification primitive represents a volume enclosing geometry in the {@link Scene} to be highlighted. The geometry must be from a single {@link GeometryInstance}. @@ -191,7 +171,7 @@ define([ var readOnlyAttributes; if (defined(this.geometryInstances) && isArray(this.geometryInstances) && this.geometryInstances.length > 1) { - readOnlyAttributes = readOnlyInstanceAttributesScratch; + readOnlyAttributes = ClassificationPrimitiveReadOnlyInstanceAttributes; } this._createBoundingVolumeFunction = options._createBoundingVolumeFunction; @@ -469,16 +449,16 @@ define([ depthMask : false }; - function createRenderStates(groundPrimitive, context, appearance, twoPasses) { - if (defined(groundPrimitive._rsStencilPreloadPass)) { + function createRenderStates(classificationPrimitive, context, appearance, twoPasses) { + if (defined(classificationPrimitive._rsStencilPreloadPass)) { return; } - var stencilEnabled = !groundPrimitive.debugShowShadowVolume; + var stencilEnabled = !classificationPrimitive.debugShowShadowVolume; - groundPrimitive._rsStencilPreloadPass = RenderState.fromCache(getStencilPreloadRenderState(stencilEnabled)); - groundPrimitive._rsStencilDepthPass = RenderState.fromCache(getStencilDepthRenderState(stencilEnabled)); - groundPrimitive._rsColorPass = RenderState.fromCache(getColorRenderState(stencilEnabled)); - groundPrimitive._rsPickPass = RenderState.fromCache(pickRenderState); + classificationPrimitive._rsStencilPreloadPass = RenderState.fromCache(getStencilPreloadRenderState(stencilEnabled)); + classificationPrimitive._rsStencilDepthPass = RenderState.fromCache(getStencilDepthRenderState(stencilEnabled)); + classificationPrimitive._rsColorPass = RenderState.fromCache(getColorRenderState(stencilEnabled)); + classificationPrimitive._rsPickPass = RenderState.fromCache(pickRenderState); } function modifyForEncodedNormals(primitive, vertexShaderSource) { @@ -509,25 +489,25 @@ define([ } } - function createShaderProgram(groundPrimitive, frameState, appearance) { - if (defined(groundPrimitive._sp)) { + function createShaderProgram(classificationPrimitive, frameState, appearance) { + if (defined(classificationPrimitive._sp)) { return; } var context = frameState.context; - var primitive = groundPrimitive._primitive; + var primitive = classificationPrimitive._primitive; var vs = ShadowVolumeVS; - vs = groundPrimitive._primitive._batchTable.getVertexShaderCallback()(vs); + vs = classificationPrimitive._primitive._batchTable.getVertexShaderCallback()(vs); vs = Primitive._appendShowToShader(primitive, vs); vs = Primitive._appendDistanceDisplayConditionToShader(primitive, vs); - vs = Primitive._modifyShaderPosition(groundPrimitive, vs, frameState.scene3DOnly); + vs = Primitive._modifyShaderPosition(classificationPrimitive, vs, frameState.scene3DOnly); vs = Primitive._updateColorAttribute(primitive, vs); - if (groundPrimitive._extruded) { + if (classificationPrimitive._extruded) { vs = modifyForEncodedNormals(primitive, vs); } - var extrudedDefine = groundPrimitive._extruded ? 'EXTRUDED_GEOMETRY' : ''; + var extrudedDefine = classificationPrimitive._extruded ? 'EXTRUDED_GEOMETRY' : ''; var vsSource = new ShaderSource({ defines : [extrudedDefine], @@ -536,17 +516,17 @@ define([ var fsSource = new ShaderSource({ sources : [ShadowVolumeFS] }); - var attributeLocations = groundPrimitive._primitive._attributeLocations; + var attributeLocations = classificationPrimitive._primitive._attributeLocations; - groundPrimitive._sp = ShaderProgram.replaceCache({ + classificationPrimitive._sp = ShaderProgram.replaceCache({ context : context, - shaderProgram : groundPrimitive._sp, + shaderProgram : classificationPrimitive._sp, vertexShaderSource : vsSource, fragmentShaderSource : fsSource, attributeLocations : attributeLocations }); - if (groundPrimitive._primitive.allowPicking) { + if (classificationPrimitive._primitive.allowPicking) { var vsPick = ShaderSource.createPickVertexShaderSource(vs); vsPick = Primitive._updatePickColorAttribute(vsPick); @@ -560,15 +540,15 @@ define([ pickColorQualifier : 'varying' }); - groundPrimitive._spPick = ShaderProgram.replaceCache({ + classificationPrimitive._spPick = ShaderProgram.replaceCache({ context : context, - shaderProgram : groundPrimitive._spPick, + shaderProgram : classificationPrimitive._spPick, vertexShaderSource : pickVS, fragmentShaderSource : pickFS, attributeLocations : attributeLocations }); } else { - groundPrimitive._spPick = ShaderProgram.fromCache({ + classificationPrimitive._spPick = ShaderProgram.fromCache({ context : context, vertexShaderSource : vsSource, fragmentShaderSource : fsSource, @@ -577,13 +557,13 @@ define([ } } - function createColorCommands(groundPrimitive, colorCommands) { - var primitive = groundPrimitive._primitive; + function createColorCommands(classificationPrimitive, colorCommands) { + var primitive = classificationPrimitive._primitive; var length = primitive._va.length * 3; colorCommands.length = length; var vaIndex = 0; - var uniformMap = primitive._batchTable.getUniformMapCallback()(groundPrimitive._uniformMap); + var uniformMap = primitive._batchTable.getUniformMapCallback()(classificationPrimitive._uniformMap); for (var i = 0; i < length; i += 3) { var vertexArray = primitive._va[vaIndex++]; @@ -592,14 +572,14 @@ define([ var command = colorCommands[i]; if (!defined(command)) { command = colorCommands[i] = new DrawCommand({ - owner : groundPrimitive, + owner : classificationPrimitive, primitiveType : primitive._primitiveType }); } command.vertexArray = vertexArray; - command.renderState = groundPrimitive._rsStencilPreloadPass; - command.shaderProgram = groundPrimitive._sp; + command.renderState = classificationPrimitive._rsStencilPreloadPass; + command.shaderProgram = classificationPrimitive._sp; command.uniformMap = uniformMap; command.pass = Pass.GROUND; @@ -607,14 +587,14 @@ define([ command = colorCommands[i + 1]; if (!defined(command)) { command = colorCommands[i + 1] = new DrawCommand({ - owner : groundPrimitive, + owner : classificationPrimitive, primitiveType : primitive._primitiveType }); } command.vertexArray = vertexArray; - command.renderState = groundPrimitive._rsStencilDepthPass; - command.shaderProgram = groundPrimitive._sp; + command.renderState = classificationPrimitive._rsStencilDepthPass; + command.shaderProgram = classificationPrimitive._sp; command.uniformMap = uniformMap; command.pass = Pass.GROUND; @@ -622,27 +602,27 @@ define([ command = colorCommands[i + 2]; if (!defined(command)) { command = colorCommands[i + 2] = new DrawCommand({ - owner : groundPrimitive, + owner : classificationPrimitive, primitiveType : primitive._primitiveType }); } command.vertexArray = vertexArray; - command.renderState = groundPrimitive._rsColorPass; - command.shaderProgram = groundPrimitive._sp; + command.renderState = classificationPrimitive._rsColorPass; + command.shaderProgram = classificationPrimitive._sp; command.uniformMap = uniformMap; command.pass = Pass.GROUND; } } - function createPickCommands(groundPrimitive, pickCommands) { - var primitive = groundPrimitive._primitive; + function createPickCommands(classificationPrimitive, pickCommands) { + var primitive = classificationPrimitive._primitive; var pickOffsets = primitive._pickOffsets; var length = pickOffsets.length * 3; pickCommands.length = length; var pickIndex = 0; - var uniformMap = primitive._batchTable.getUniformMapCallback()(groundPrimitive._uniformMap); + var uniformMap = primitive._batchTable.getUniformMapCallback()(classificationPrimitive._uniformMap); for (var j = 0; j < length; j += 3) { var pickOffset = pickOffsets[pickIndex++]; @@ -655,7 +635,7 @@ define([ var command = pickCommands[j]; if (!defined(command)) { command = pickCommands[j] = new DrawCommand({ - owner : groundPrimitive, + owner : classificationPrimitive, primitiveType : primitive._primitiveType }); } @@ -663,8 +643,8 @@ define([ command.vertexArray = vertexArray; command.offset = offset; command.count = count; - command.renderState = groundPrimitive._rsStencilPreloadPass; - command.shaderProgram = groundPrimitive._sp; + command.renderState = classificationPrimitive._rsStencilPreloadPass; + command.shaderProgram = classificationPrimitive._sp; command.uniformMap = uniformMap; command.pass = Pass.GROUND; @@ -672,7 +652,7 @@ define([ command = pickCommands[j + 1]; if (!defined(command)) { command = pickCommands[j + 1] = new DrawCommand({ - owner : groundPrimitive, + owner : classificationPrimitive, primitiveType : primitive._primitiveType }); } @@ -680,8 +660,8 @@ define([ command.vertexArray = vertexArray; command.offset = offset; command.count = count; - command.renderState = groundPrimitive._rsStencilDepthPass; - command.shaderProgram = groundPrimitive._sp; + command.renderState = classificationPrimitive._rsStencilDepthPass; + command.shaderProgram = classificationPrimitive._sp; command.uniformMap = uniformMap; command.pass = Pass.GROUND; @@ -689,7 +669,7 @@ define([ command = pickCommands[j + 2]; if (!defined(command)) { command = pickCommands[j + 2] = new DrawCommand({ - owner : groundPrimitive, + owner : classificationPrimitive, primitiveType : primitive._primitiveType }); } @@ -697,20 +677,20 @@ define([ command.vertexArray = vertexArray; command.offset = offset; command.count = count; - command.renderState = groundPrimitive._rsPickPass; - command.shaderProgram = groundPrimitive._spPick; + command.renderState = classificationPrimitive._rsPickPass; + command.shaderProgram = classificationPrimitive._spPick; command.uniformMap = uniformMap; command.pass = Pass.GROUND; } } - function createCommands(groundPrimitive, appearance, material, translucent, twoPasses, colorCommands, pickCommands) { - createColorCommands(groundPrimitive, colorCommands); - createPickCommands(groundPrimitive, pickCommands); + function createCommands(classificationPrimitive, appearance, material, translucent, twoPasses, colorCommands, pickCommands) { + createColorCommands(classificationPrimitive, colorCommands); + createPickCommands(classificationPrimitive, pickCommands); } - function updateAndQueueCommands(groundPrimitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { - var primitive = groundPrimitive._primitive; + function updateAndQueueCommands(classificationPrimitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { + var primitive = classificationPrimitive._primitive; /* var boundingVolumes; diff --git a/Source/Scene/GroundPrimitive.js b/Source/Scene/GroundPrimitive.js index 2c8b21276278..e918e836d6ba 100644 --- a/Source/Scene/GroundPrimitive.js +++ b/Source/Scene/GroundPrimitive.js @@ -4,7 +4,6 @@ define([ '../Core/Cartesian2', '../Core/Cartesian3', '../Core/Cartographic', - '../Core/ColorGeometryInstanceAttribute', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', @@ -17,29 +16,15 @@ define([ '../Core/Math', '../Core/OrientedBoundingBox', '../Core/Rectangle', - '../Renderer/DrawCommand', - '../Renderer/Pass', - '../Renderer/RenderState', - '../Renderer/ShaderProgram', - '../Renderer/ShaderSource', - '../Shaders/ShadowVolumeFS', - '../Shaders/ShadowVolumeVS', '../ThirdParty/when', - './BlendingState', './ClassificationPrimitive', - './DepthFunction', - './PerInstanceColorAppearance', - './Primitive', - './SceneMode', - './StencilFunction', - './StencilOperation' + './SceneMode' ], function( BoundingSphere, buildModuleUrl, Cartesian2, Cartesian3, Cartographic, - ColorGeometryInstanceAttribute, defaultValue, defined, defineProperties, @@ -52,25 +37,11 @@ define([ CesiumMath, OrientedBoundingBox, Rectangle, - DrawCommand, - Pass, - RenderState, - ShaderProgram, - ShaderSource, - ShadowVolumeFS, - ShadowVolumeVS, when, - BlendingState, ClassificationPrimitive, - DepthFunction, - PerInstanceColorAppearance, - Primitive, - SceneMode, - StencilFunction, - StencilOperation) { + SceneMode) { 'use strict'; - var GroundPrimitiveReadOnlyInstanceAttributes = ['color']; var GroundPrimitiveUniformMap = { u_globeMinimumAltitude: function() { return 55000.0; @@ -227,11 +198,6 @@ define([ this._boundingSpheresKeys = []; this._boundingSpheres = []; - var readOnlyAttributes; - if (defined(this.geometryInstances) && isArray(this.geometryInstances) && this.geometryInstances.length > 1) { - readOnlyAttributes = GroundPrimitiveReadOnlyInstanceAttributes; - } - var that = this; this._primitiveOptions = { geometryInstances : undefined, @@ -241,7 +207,6 @@ define([ allowPicking : defaultValue(options.allowPicking, true), asynchronous : defaultValue(options.asynchronous, true), compressVertices : defaultValue(options.compressVertices, true), - _readOnlyInstanceAttributes : readOnlyAttributes, _createBoundingVolumeFunction : undefined, _updateAndQueueCommandsFunction : undefined, _pickPrimitive : that, @@ -601,6 +566,7 @@ define([ var colorLength = colorCommands.length; for (var i = 0; i < colorLength; ++i) { var colorCommand = colorCommands[i]; + colorCommand.owner = groundPrimitive; colorCommand.modelMatrix = modelMatrix; colorCommand.boundingVolume = boundingVolumes[Math.floor(i / 3)]; colorCommand.cull = cull; @@ -621,6 +587,7 @@ define([ var bv = boundingVolumes[pickOffset.index]; var pickCommand = pickCommands[j]; + pickCommand.owner = groundPrimitive; pickCommand.modelMatrix = modelMatrix; pickCommand.boundingVolume = bv; pickCommand.cull = cull; From 5ddf222170ea254b36ad76b4cb241c0c4c3aecfb Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Wed, 12 Jul 2017 15:50:42 -0400 Subject: [PATCH 033/132] Comment and CHANGES.md --- CHANGES.md | 1 + Source/Workers/transcodeCRNToDXT.js | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 28ac687b486d..8c590428f55d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ Change Log ### 1.36 - 2017-08-01 * Added ability to show tile urls in the 3D Tiles Inspector. [#5592](https://github.com/AnalyticalGraphicsInc/cesium/pull/5592) +* Fixed a bug when reading CRN compressed textures with multiple mip levels. [#5618](https://github.com/AnalyticalGraphicsInc/cesium/pull/5618) ### 1.35.2 - 2017-07-11 diff --git a/Source/Workers/transcodeCRNToDXT.js b/Source/Workers/transcodeCRNToDXT.js index c643c0de9832..2d058b700e30 100644 --- a/Source/Workers/transcodeCRNToDXT.js +++ b/Source/Workers/transcodeCRNToDXT.js @@ -133,6 +133,7 @@ define([ // When mipmaps are supported, a copy will still be necessary as dxtData is a view on the heap. var length = PixelFormat.compressedTextureSizeInBytes(format, width, height); + // Get a copy of the 0th mip level. dxtData will exceed length when there are more mip levels. // Equivalent to dxtData.slice(0, length), which is not supported in IE11 var level0DXTDataView = dxtData.subarray(0, length); var level0DXTData = new Uint8Array(length); From 5ad9b82e3c2e17f4c328e841b111d2e2966652ee Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Wed, 12 Jul 2017 15:50:45 -0400 Subject: [PATCH 034/132] Adds support for PixelFormat.RGB textures --- Source/Renderer/Texture.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/Renderer/Texture.js b/Source/Renderer/Texture.js index 910ed3369a87..2edf6062ecfd 100644 --- a/Source/Renderer/Texture.js +++ b/Source/Renderer/Texture.js @@ -77,6 +77,9 @@ define([ case PixelFormat.RGBA: internalFormat = WebGLConstants.RGBA32F; break; + case PixelFormat.RGB: + internalFormat = WebGLConstants.RGB32F; + break; case PixelFormat.RG: internalFormat = WebGLConstants.RG32F; break; From 0ef293938f9193629220124a19d96d8a7c8f2955 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 10:05:42 -0400 Subject: [PATCH 035/132] Creates mockContext variable --- Specs/Renderer/ShaderSourceSpec.js | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/Specs/Renderer/ShaderSourceSpec.js b/Specs/Renderer/ShaderSourceSpec.js index 912d45c5d05f..461819a070f1 100644 --- a/Specs/Renderer/ShaderSourceSpec.js +++ b/Specs/Renderer/ShaderSourceSpec.js @@ -4,14 +4,16 @@ defineSuite([ ShaderSource) { 'use strict'; + var mockContext = { + webgl2 : false + }; + it('combines #defines', function() { var source = new ShaderSource({ defines : ['A', 'B', ''] }); - var shaderText = source.createCombinedVertexShader({ - webgl2: false - }); + var shaderText = source.createCombinedVertexShader(mockContext); expect(shaderText).toContain('#define A'); expect(shaderText).toContain('#define B'); expect(shaderText.match(/#define/g).length).toEqual(2); @@ -21,9 +23,7 @@ defineSuite([ var source = new ShaderSource({ sources : ['void func() {}', 'void main() {}'] }); - var shaderText = source.createCombinedVertexShader({ - webgl2: false - }); + var shaderText = source.createCombinedVertexShader(mockContext); expect(shaderText).toContain('#line 0\nvoid func() {}'); expect(shaderText).toContain('#line 0\nvoid main() {}'); }); @@ -33,9 +33,7 @@ defineSuite([ defines : ['A', 'B', ''], sources : ['void func() {}', 'void main() {}'] }); - var shaderText = source.createCombinedVertexShader({ - webgl2: false - }); + var shaderText = source.createCombinedVertexShader(mockContext); expect(shaderText).toContain('#define A'); expect(shaderText).toContain('#define B'); expect(shaderText.match(/#define/g).length).toEqual(2); @@ -48,9 +46,7 @@ defineSuite([ sources : ['void main() { gl_FragColor = vec4(1.0); }'], pickColorQualifier : 'uniform' }); - var shaderText = source.createCombinedVertexShader({ - webgl2: false - }); + var shaderText = source.createCombinedVertexShader(mockContext); expect(shaderText).toContain('uniform vec4 czm_pickColor;'); expect(shaderText).toContain('gl_FragColor = czm_pickColor;'); }); @@ -60,9 +56,7 @@ defineSuite([ sources : ['void main() { gl_FragColor = vec4(1.0); }'], pickColorQualifier : 'varying' }); - var shaderText = source.createCombinedVertexShader({ - webgl2: false - }); + var shaderText = source.createCombinedVertexShader(mockContext); expect(shaderText).toContain('varying vec4 czm_pickColor;'); expect(shaderText).toContain('gl_FragColor = czm_pickColor;'); }); @@ -79,9 +73,7 @@ defineSuite([ var source = new ShaderSource({ sources : ['#version 300 es\nvoid main() {gl_FragColor = vec4(1.0); }'] }); - var shaderText = source.createCombinedVertexShader(({ - webgl2: false - }); + var shaderText = source.createCombinedVertexShader(mockContext); expect(shaderText).toStartWith('#version 300 es\n'); }); }); From da577015d57eafea94d95e3ec44f4be37ec474d4 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 10:06:35 -0400 Subject: [PATCH 036/132] Now passing in context rather than context.webgl2 for test in ShaderProgramSpec --- Specs/Renderer/ShaderProgramSpec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Specs/Renderer/ShaderProgramSpec.js b/Specs/Renderer/ShaderProgramSpec.js index bf52c55a8c8e..dc5a9b5e190d 100644 --- a/Specs/Renderer/ShaderProgramSpec.js +++ b/Specs/Renderer/ShaderProgramSpec.js @@ -65,7 +65,7 @@ defineSuite([ var expectedVSText = new ShaderSource({ sources : [vs] - }).createCombinedVertexShader(context.webgl2); + }).createCombinedVertexShader(context); expect(sp._vertexShaderText).toEqual(expectedVSText); From fe785356d1be97d85bb0125101ca99453bb9c802 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 10:07:04 -0400 Subject: [PATCH 037/132] Fixes equality operator --- Source/Renderer/Texture.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Renderer/Texture.js b/Source/Renderer/Texture.js index 2edf6062ecfd..34d71a6d56a6 100644 --- a/Source/Renderer/Texture.js +++ b/Source/Renderer/Texture.js @@ -72,7 +72,7 @@ define([ } } - if (pixelDatatype == PixelDatatype.FLOAT) { + if (pixelDatatype === PixelDatatype.FLOAT) { switch (pixelFormat) { case PixelFormat.RGBA: internalFormat = WebGLConstants.RGBA32F; From 2ddc44201617843252cb6f548133849b5e3bf55d Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 10:09:17 -0400 Subject: [PATCH 038/132] Adds explanatory comment for OUTPUT_DECLARATION --- Source/Renderer/ShaderSource.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Renderer/ShaderSource.js b/Source/Renderer/ShaderSource.js index c69a6b38e35c..5eb6bdd5cb5e 100644 --- a/Source/Renderer/ShaderSource.js +++ b/Source/Renderer/ShaderSource.js @@ -242,6 +242,8 @@ define([ } } + // GLSLModernizer inserts its own layout qualifiers + // at this position in the source result += '#define OUTPUT_DECLARATION\n\n'; // append built-ins From f76f1998bd617c3623b221df9e69a5a34cb49e39 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 10:15:02 -0400 Subject: [PATCH 039/132] Removes unnecessary functions in GLSLModernizer --- Source/Renderer/GLSLModernizer.js | 61 ++++++++----------------------- Source/Renderer/ShaderSource.js | 4 +- 2 files changed, 17 insertions(+), 48 deletions(-) diff --git a/Source/Renderer/GLSLModernizer.js b/Source/Renderer/GLSLModernizer.js index f387459fa069..66f3f814cd58 100644 --- a/Source/Renderer/GLSLModernizer.js +++ b/Source/Renderer/GLSLModernizer.js @@ -10,18 +10,13 @@ define([ * This function is nowhere near comprehensive or complete. It just * handles some common cases. * + * Note that this function requires the presence of the + * "#define OUTPUT_DECLARATION" line that is appended + * by ShaderSource. + * * @private */ - function glslModernizeShaderSource(shaderSource, isFragmentShader) { - for (var i = 0; i < shaderSource.sources.length; i++) { - shaderSource.sources[i] = glslModernizeShaderText(shaderSource.sources[i], isFragmentShader, i === 0); - } - } - - // Note that this function requires the presence of the - // "#define OUTPUT_DECLARATION" line that is appended - // by ShaderSource - function glslModernizeShaderText(source, isFragmentShader, first) { + function glslModernizeShaderText(source, isFragmentShader) { var mainFunctionRegex = /void\s+main\s*\((void)?\)/; var outputDeclarationRegex = /#define OUTPUT_DECLARATION/; var splitSource = source.split('\n'); @@ -275,19 +270,17 @@ define([ } } - if (first === true) { - var versionThree = "#version 300 es"; - var foundVersion = false; - for (number = 0; number < splitSource.length; number++) { - if (/#version/.test(splitSource[number])) { - splitSource[number] = versionThree; - foundVersion = true; - } + var versionThree = "#version 300 es"; + var foundVersion = false; + for (number = 0; number < splitSource.length; number++) { + if (/#version/.test(splitSource[number])) { + splitSource[number] = versionThree; + foundVersion = true; } + } - if (!foundVersion) { - splitSource.splice(0, 0, versionThree); - } + if (!foundVersion) { + splitSource.splice(0, 0, versionThree); } removeExtension("EXT_draw_buffers"); @@ -308,29 +301,5 @@ define([ return compileSource(); } - function glslModernizeShaderProgram(context, shaderProgram) { - var vsSource = shaderProgram.vertexShaderSource.clone(); - var fsSource = shaderProgram.fragmentShaderSource.clone(); - - glslModernizeShaderSource(vsSource, false); - glslModernizeShaderSource(fsSource, true); - - var newShaderProgramOptions = { - vertexShaderSource : vsSource, - fragmentShaderSource : fsSource, - gl : shaderProgram._gl, - logShaderCompilation : shaderProgram._logShaderCompilation, - attributeLocations : shaderProgram._attributeLocations - }; - - return context.shaderCache.getShaderProgram(newShaderProgramOptions); - } - - var GLSLModernizer = { - glslModernizeShaderText : glslModernizeShaderText, - glslModernizeShaderSource : glslModernizeShaderSource, - glslModernizeShaderProgram : glslModernizeShaderProgram - }; - - return GLSLModernizer; + return glslModernizeShaderText; }); diff --git a/Source/Renderer/ShaderSource.js b/Source/Renderer/ShaderSource.js index 5eb6bdd5cb5e..283f21732642 100644 --- a/Source/Renderer/ShaderSource.js +++ b/Source/Renderer/ShaderSource.js @@ -9,7 +9,7 @@ define([ defaultValue, defined, DeveloperError, - GLSLModernizer, + glslModernizeShaderText, CzmBuiltins, AutomaticUniforms) { 'use strict'; @@ -259,7 +259,7 @@ define([ // modernize the source if (context.webgl2) { - result = GLSLModernizer.glslModernizeShaderText(result, isFragmentShader, true); + result = glslModernizeShaderText(result, isFragmentShader, true); } return result; From ffc01096baff07aad12b8eb445cef1c94d2fac09 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 10:17:03 -0400 Subject: [PATCH 040/132] Fixes some documenation for ShaderSource --- Source/Renderer/ShaderSource.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Renderer/ShaderSource.js b/Source/Renderer/ShaderSource.js index 283f21732642..642cdc15e0d3 100644 --- a/Source/Renderer/ShaderSource.js +++ b/Source/Renderer/ShaderSource.js @@ -324,7 +324,7 @@ define([ /** * Create a single string containing the full, combined vertex shader with all dependencies and defines. * - * @param {Object} [context] The current rendering context + * @param {Context} context The current rendering context * * @returns {String} The combined shader string. */ @@ -335,7 +335,7 @@ define([ /** * Create a single string containing the full, combined fragment shader with all dependencies and defines. * - * @param {Object} [context] The current rendering context + * @param {Context} context The current rendering context * * @returns {String} The combined shader string. */ From f54c550270bf31ed18387aaedd40a8a8b0bfa246 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 10:17:41 -0400 Subject: [PATCH 041/132] Fixes typo in documentation --- Source/Renderer/GLSLModernizer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Renderer/GLSLModernizer.js b/Source/Renderer/GLSLModernizer.js index 66f3f814cd58..1955c9c439bb 100644 --- a/Source/Renderer/GLSLModernizer.js +++ b/Source/Renderer/GLSLModernizer.js @@ -5,7 +5,7 @@ define([ 'use strict'; /** - * A function to port GLSL shaders from GLSL ES 1.00 to GLSL ES 2.00 + * A function to port GLSL shaders from GLSL ES 1.00 to GLSL ES 3.00 * * This function is nowhere near comprehensive or complete. It just * handles some common cases. From f0c20d8282ebc5fee199d41c0ccc7111c0cd1beb Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 10:21:58 -0400 Subject: [PATCH 042/132] Removes check for main() --- Source/Renderer/GLSLModernizer.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Source/Renderer/GLSLModernizer.js b/Source/Renderer/GLSLModernizer.js index 1955c9c439bb..fa5a25acccf6 100644 --- a/Source/Renderer/GLSLModernizer.js +++ b/Source/Renderer/GLSLModernizer.js @@ -17,7 +17,6 @@ define([ * @private */ function glslModernizeShaderText(source, isFragmentShader) { - var mainFunctionRegex = /void\s+main\s*\((void)?\)/; var outputDeclarationRegex = /#define OUTPUT_DECLARATION/; var splitSource = source.split('\n'); @@ -34,15 +33,6 @@ define([ break; } }; - - if (outputDeclarationLine === -1) { - for (number = 0; number < splitSource.length; ++number) { - var line = splitSource[number]; - if (mainFunctionRegex.exec(line)) { - outputDeclarationLine = number; - } - }; - } if (outputDeclarationLine === -1) { throw new DeveloperError('Could not find a #define OUTPUT_DECLARATION nor a main function!'); From 4679559cf5f367859a61674c6bfbdff94505324b Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 11:45:17 -0400 Subject: [PATCH 043/132] Trying to remove all the safeName* --- Source/Renderer/GLSLModernizer.js | 50 ++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/Source/Renderer/GLSLModernizer.js b/Source/Renderer/GLSLModernizer.js index fa5a25acccf6..22fe87c225ce 100644 --- a/Source/Renderer/GLSLModernizer.js +++ b/Source/Renderer/GLSLModernizer.js @@ -1,6 +1,8 @@ define([ + '../Core/defined', '../Core/DeveloperError', ], function( + defined, DeveloperError) { 'use strict'; @@ -88,16 +90,35 @@ define([ } } - function replaceInSource(regex, replacement) { + function replaceInSource(str, replacement, strIsRegex) { + var replaceAll = function(target, search, replacement) { + return target.split(search).join(replacement); + }; + + var regex = str; + if (!defined(strIsRegex) || strIsRegex === false) { + /*var regexStr = "(?:^.*[^\\w](" + str + + ")[^\\w].*$|^(" + str + + ")[^\\w].*$|^.*[^\\w](" + str + + ")$|^(" + str + ")$)"; + regex = new RegExp(regexStr, 'g');*/ + regex = new RegExp(str, 'g'); + } for (var number = 0; number < splitSource.length; ++number) { splitSource[number] = safeNameReplace(regex, splitSource[number], replacement); + //splitSource[number] = replaceAll(splitSource[number], regex, replacement); } } - function findInSource(regex) { + function findInSource(str) { + var regexStr = "(^.*[^\\w](" + str + + ")[^\\w].*$|^(" + str + + ")[^\\w].*$|^.*[^\\w](" + str + + ")$|^(" + str + ")$)"; + var regex = new RegExp(regexStr, 'g'); for (var number = 0; number < splitSource.length; ++number) { var line = splitSource[number]; - if (safeNameFind(regex, line) !== -1) { + if (regex.test(line)) { return true; } } @@ -204,7 +225,7 @@ define([ function removeExtension(name) { var regex = "#extension\\s+GL_" + name + "\\s+:\\s+[a-zA-Z0-9]+\\s*$"; - replaceInSource(new RegExp(regex, "g"), ""); + replaceInSource(new RegExp(regex, "g"), "", true); } var variableSet = []; @@ -215,16 +236,16 @@ define([ var regex = new RegExp(fragDataString, "g"); if (regex.test(source)) { setAdd(newOutput, variableSet); - replaceInSource(regex, newOutput); + replaceInSource(fragDataString, newOutput); splitSource.splice(outputDeclarationLine, 0, "layout(location = " + i + ") out vec4 " + newOutput + ";"); outputDeclarationLine += 1; } } var czmFragColor = "czm_fragColor"; - if (findInSource(/gl_FragColor/)) { + if (findInSource("gl_FragColor")) { setAdd(czmFragColor, variableSet); - replaceInSource(/gl_FragColor/, czmFragColor); + replaceInSource("gl_FragColor", czmFragColor); splitSource.splice(outputDeclarationLine, 0, "layout(location = 0) out vec4 czm_fragColor;"); outputDeclarationLine += 1; } @@ -276,18 +297,19 @@ define([ removeExtension("EXT_draw_buffers"); removeExtension("EXT_frag_depth"); - replaceInSource(/texture2D/, "texture"); - replaceInSource(/texture3D/, "texture"); - replaceInSource(/textureCube/, "texture"); - replaceInSource(/gl_FragDepthEXT/, "gl_FragDepth"); + replaceInSource("texture2D", "texture"); + replaceInSource("texture3D", "texture"); + replaceInSource("textureCube", "texture"); + replaceInSource("gl_FragDepthEXT", "gl_FragDepth"); if (isFragmentShader) { - replaceInSource(/varying/, "in"); + replaceInSource("varying", "in"); } else { - replaceInSource(/attribute/, "in"); - replaceInSource(/varying/, "out"); + replaceInSource("attribute", "in"); + replaceInSource("varying", "out"); } + console.log(compileSource()); return compileSource(); } From 974218c2c7fe7b245d70da9de0ae1cc6dabe578c Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 13 Jul 2017 14:31:04 -0400 Subject: [PATCH 044/132] Fix bounding volumes and add tests. --- Source/Scene/ClassificationPrimitive.js | 9 +- Source/Scene/Primitive.js | 38 +- Specs/Scene/ClassificationPrimitiveSpec.js | 909 +++++++++++++++++++++ Specs/Scene/GroundPrimitiveSpec.js | 5 +- 4 files changed, 938 insertions(+), 23 deletions(-) create mode 100644 Specs/Scene/ClassificationPrimitiveSpec.js diff --git a/Source/Scene/ClassificationPrimitive.js b/Source/Scene/ClassificationPrimitive.js index fd5da594cba2..6ebdb850d0d5 100644 --- a/Source/Scene/ClassificationPrimitive.js +++ b/Source/Scene/ClassificationPrimitive.js @@ -691,8 +691,8 @@ define([ function updateAndQueueCommands(classificationPrimitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { var primitive = classificationPrimitive._primitive; + Primitive._updateBoundingVolumes(primitive, frameState, modelMatrix); - /* var boundingVolumes; if (frameState.mode === SceneMode.SCENE3D) { boundingVolumes = primitive._boundingSphereWC; @@ -703,7 +703,6 @@ define([ } else if (defined(primitive._boundingSphereMorph)) { boundingVolumes = primitive._boundingSphereMorph; } - */ var commandList = frameState.commandList; var passes = frameState.passes; @@ -712,7 +711,7 @@ define([ for (var i = 0; i < colorLength; ++i) { var colorCommand = colorCommands[i]; colorCommand.modelMatrix = modelMatrix; - colorCommand.boundingVolume = undefined;//boundingVolumes[Math.floor(i / 3)]; + colorCommand.boundingVolume = boundingVolumes[Math.floor(i / 3)]; colorCommand.cull = cull; colorCommand.debugShowBoundingVolume = debugShowBoundingVolume; @@ -726,10 +725,10 @@ define([ pickCommands.length = length; for (var j = 0; j < length; ++j) { - //var pickOffset = pickOffsets[Math.floor(j / 3)]; + var pickOffset = pickOffsets[Math.floor(j / 3)]; var pickCommand = pickCommands[j]; pickCommand.modelMatrix = modelMatrix; - pickCommand.boundingVolume = undefined;//boundingVolumes[pickOffset.index]; + pickCommand.boundingVolume = boundingVolumes[pickOffset.index]; pickCommand.cull = cull; commandList.push(pickCommand); diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index a872bef41470..425bb9d19a89 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -1622,36 +1622,30 @@ define([ } } - function updateBoundingVolumes(primitive, frameState) { + Primitive._updateBoundingVolumes = function(primitive, frameState, modelMatrix) { + var i; + var length; + var boundingSphere; + // Update bounding volumes for primitives that are sized in pixels. // The pixel size in meters varies based on the distance from the camera. var pixelSize = primitive.appearance.pixelSize; if (defined(pixelSize)) { - var length = primitive._boundingSpheres.length; - for (var i = 0; i < length; ++i) { - var boundingSphere = primitive._boundingSpheres[i]; + length = primitive._boundingSpheres.length; + for (i = 0; i < length; ++i) { + boundingSphere = primitive._boundingSpheres[i]; var boundingSphereWC = primitive._boundingSphereWC[i]; var pixelSizeInMeters = frameState.camera.getPixelSize(boundingSphere, frameState.context.drawingBufferWidth, frameState.context.drawingBufferHeight); var sizeInMeters = pixelSizeInMeters * pixelSize; boundingSphereWC.radius = boundingSphere.radius + sizeInMeters; } } - } - - function updateAndQueueCommands(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { - //>>includeStart('debug', pragmas.debug); - if (frameState.mode !== SceneMode.SCENE3D && !Matrix4.equals(modelMatrix, Matrix4.IDENTITY)) { - throw new DeveloperError('Primitive.modelMatrix is only supported in 3D mode.'); - } - //>>includeEnd('debug'); - - updateBoundingVolumes(primitive, frameState); if (!Matrix4.equals(modelMatrix, primitive._modelMatrix)) { Matrix4.clone(modelMatrix, primitive._modelMatrix); - var length = primitive._boundingSpheres.length; - for (var i = 0; i < length; ++i) { - var boundingSphere = primitive._boundingSpheres[i]; + length = primitive._boundingSpheres.length; + for (i = 0; i < length; ++i) { + boundingSphere = primitive._boundingSpheres[i]; if (defined(boundingSphere)) { primitive._boundingSphereWC[i] = BoundingSphere.transform(boundingSphere, modelMatrix, primitive._boundingSphereWC[i]); if (!frameState.scene3DOnly) { @@ -1662,6 +1656,16 @@ define([ } } } + }; + + function updateAndQueueCommands(primitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume, twoPasses) { + //>>includeStart('debug', pragmas.debug); + if (frameState.mode !== SceneMode.SCENE3D && !Matrix4.equals(modelMatrix, Matrix4.IDENTITY)) { + throw new DeveloperError('Primitive.modelMatrix is only supported in 3D mode.'); + } + //>>includeEnd('debug'); + + Primitive._updateBoundingVolumes(primitive, frameState, modelMatrix); var boundingSpheres; if (frameState.mode === SceneMode.SCENE3D) { diff --git a/Specs/Scene/ClassificationPrimitiveSpec.js b/Specs/Scene/ClassificationPrimitiveSpec.js new file mode 100644 index 000000000000..0bbbba8058ad --- /dev/null +++ b/Specs/Scene/ClassificationPrimitiveSpec.js @@ -0,0 +1,909 @@ +defineSuite([ + 'Scene/ClassificationPrimitive', + 'Core/BoxGeometry', + 'Core/Cartesian3', + 'Core/Color', + 'Core/ColorGeometryInstanceAttribute', + 'Core/destroyObject', + 'Core/DistanceDisplayConditionGeometryInstanceAttribute', + 'Core/Ellipsoid', + 'Core/GeometryInstance', + 'Core/HeadingPitchRange', + 'Core/Math', + 'Core/Matrix4', + 'Core/PolygonGeometry', + 'Core/Rectangle', + 'Core/RectangleGeometry', + 'Core/ShowGeometryInstanceAttribute', + 'Core/Transforms', + 'Renderer/Pass', + 'Scene/PerInstanceColorAppearance', + 'Scene/Primitive', + 'Specs/createScene', + 'Specs/pollToPromise' + ], function( + ClassificationPrimitive, + BoxGeometry, + Cartesian3, + Color, + ColorGeometryInstanceAttribute, + destroyObject, + DistanceDisplayConditionGeometryInstanceAttribute, + Ellipsoid, + GeometryInstance, + HeadingPitchRange, + CesiumMath, + Matrix4, + PolygonGeometry, + Rectangle, + RectangleGeometry, + ShowGeometryInstanceAttribute, + Transforms, + Pass, + PerInstanceColorAppearance, + Primitive, + createScene, + pollToPromise) { + 'use strict'; + + var scene; + + var ellipsoid; + var rectangle; + + var depthColor; + var boxColor; + + var boxInstance; + var primitive; + var depthPrimitive; + + beforeAll(function() { + scene = createScene(); + scene.fxaa = false; + + ellipsoid = Ellipsoid.WGS84; + }); + + afterAll(function() { + scene.destroyForSpecs(); + }); + + function MockGlobePrimitive(primitive) { + this._primitive = primitive; + } + MockGlobePrimitive.prototype.update = function(frameState) { + var commandList = frameState.commandList; + var startLength = commandList.length; + this._primitive.update(frameState); + + for (var i = startLength; i < commandList.length; ++i) { + var command = commandList[i]; + command.pass = Pass.GLOBE; + } + }; + + MockGlobePrimitive.prototype.isDestroyed = function() { + return false; + }; + + MockGlobePrimitive.prototype.destroy = function() { + this._primitive.destroy(); + return destroyObject(this); + }; + + beforeEach(function() { + scene.morphTo3D(0); + + rectangle = Rectangle.fromDegrees(-80.0, 20.0, -70.0, 30.0); + + var depthColorAttribute = ColorGeometryInstanceAttribute.fromColor(new Color(0.0, 0.0, 1.0, 1.0)); + depthColor = depthColorAttribute.value; + var primitive = new Primitive({ + geometryInstances : new GeometryInstance({ + geometry : new RectangleGeometry({ + ellipsoid : ellipsoid, + rectangle : rectangle + }), + id : 'depth rectangle', + attributes : { + color : depthColorAttribute + } + }), + appearance : new PerInstanceColorAppearance({ + translucent : false, + flat : true + }), + asynchronous : false + }); + + // wrap rectangle primitive so it gets executed during the globe pass to lay down depth + depthPrimitive = new MockGlobePrimitive(primitive); + + var center = Rectangle.center(rectangle); + var origin = ellipsoid.cartographicToCartesian(center); + var modelMatrix = Transforms.eastNorthUpToFixedFrame(origin); + + var dimensions = new Cartesian3(1000000.0, 1000000.0, 1000000.0); + + var boxColorAttribute = ColorGeometryInstanceAttribute.fromColor(new Color(1.0, 1.0, 0.0, 1.0)); + boxColor = boxColorAttribute.value; + boxInstance = new GeometryInstance({ + geometry : BoxGeometry.fromDimensions({ + dimensions : dimensions + }), + modelMatrix : modelMatrix, + id : 'box', + attributes : { + color : boxColorAttribute + } + }); + }); + + afterEach(function() { + scene.groundPrimitives.removeAll(); + primitive = primitive && !primitive.isDestroyed() && primitive.destroy(); + depthPrimitive = depthPrimitive && !depthPrimitive.isDestroyed() && depthPrimitive.destroy(); + }); + + it('default constructs', function() { + primitive = new ClassificationPrimitive(); + expect(primitive.geometryInstances).not.toBeDefined(); + expect(primitive.show).toEqual(true); + expect(primitive.vertexCacheOptimize).toEqual(false); + expect(primitive.interleave).toEqual(false); + expect(primitive.compressVertices).toEqual(true); + expect(primitive.releaseGeometryInstances).toEqual(true); + expect(primitive.allowPicking).toEqual(true); + expect(primitive.asynchronous).toEqual(true); + expect(primitive.debugShowBoundingVolume).toEqual(false); + expect(primitive.debugShowShadowVolume).toEqual(false); + }); + + it('constructs with options', function() { + var geometryInstances = []; + + primitive = new ClassificationPrimitive({ + geometryInstances : geometryInstances, + show : false, + vertexCacheOptimize : true, + interleave : true, + compressVertices : false, + releaseGeometryInstances : false, + allowPicking : false, + asynchronous : false, + debugShowBoundingVolume : true, + debugShowShadowVolume : true + }); + + expect(primitive.geometryInstances).toEqual(geometryInstances); + expect(primitive.show).toEqual(false); + expect(primitive.vertexCacheOptimize).toEqual(true); + expect(primitive.interleave).toEqual(true); + expect(primitive.compressVertices).toEqual(false); + expect(primitive.releaseGeometryInstances).toEqual(false); + expect(primitive.allowPicking).toEqual(false); + expect(primitive.asynchronous).toEqual(false); + expect(primitive.debugShowBoundingVolume).toEqual(true); + expect(primitive.debugShowShadowVolume).toEqual(true); + }); + + it('releases geometry instances when releaseGeometryInstances is true', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + releaseGeometryInstances : true, + asynchronous : false + }); + + expect(primitive.geometryInstances).toBeDefined(); + scene.groundPrimitives.add(primitive); + scene.renderForSpecs(); + expect(primitive.geometryInstances).not.toBeDefined(); + }); + + it('does not release geometry instances when releaseGeometryInstances is false', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + releaseGeometryInstances : false, + asynchronous : false + }); + + expect(primitive.geometryInstances).toBeDefined(); + scene.groundPrimitives.add(primitive); + scene.renderForSpecs(); + expect(primitive.geometryInstances).toBeDefined(); + }); + + it('adds afterRender promise to frame state', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + releaseGeometryInstances : false, + asynchronous : false + }); + + scene.groundPrimitives.add(primitive); + scene.renderForSpecs(); + + return primitive.readyPromise.then(function(param) { + expect(param.ready).toBe(true); + }); + }); + + it('does not render when geometryInstances is undefined', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : undefined, + appearance : new PerInstanceColorAppearance(), + asynchronous : false + }); + + var frameState = scene.frameState; + frameState.commandList.length = 0; + + primitive.update(frameState); + expect(frameState.commandList.length).toEqual(0); + }); + + it('does not render when show is false', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false + }); + + var frameState = scene.frameState; + + frameState.commandList.length = 0; + primitive.update(frameState); + expect(frameState.afterRender.length).toEqual(1); + + frameState.afterRender[0](); + frameState.commandList.length = 0; + primitive.update(frameState); + expect(frameState.commandList.length).toBeGreaterThan(0); + + frameState.commandList.length = 0; + primitive.show = false; + primitive.update(frameState); + expect(frameState.commandList.length).toEqual(0); + }); + + it('does not render other than for the color or pick pass', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false + }); + + var frameState = scene.frameState; + frameState.passes.render = false; + frameState.passes.pick = false; + + primitive.update(frameState); + expect(frameState.commandList.length).toEqual(0); + }); + + function verifyClassificationPrimitiveRender(primitive, color) { + scene.camera.setView({ destination : rectangle }); + + scene.groundPrimitives.add(depthPrimitive); + expect(scene).toRenderAndCall(function(rgba) { + expect(rgba).not.toEqual([0, 0, 0, 255]); + expect(rgba[0]).toEqual(0); + }); + + scene.groundPrimitives.add(primitive); + expect(scene).toRender(color); + } + + it('renders in 3D', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false + }); + + verifyClassificationPrimitiveRender(primitive, boxColor); + }); + + it('renders in Columbus view when scene3DOnly is false', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false + }); + + scene.morphToColumbusView(0); + verifyClassificationPrimitiveRender(primitive, boxColor); + }); + + it('renders in 2D when scene3DOnly is false', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false + }); + + scene.morphTo2D(0); + verifyClassificationPrimitiveRender(primitive, boxColor); + }); + + it('renders batched instances', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + var neCarto = Rectangle.northeast(rectangle); + var nwCarto = Rectangle.northwest(rectangle); + + var ne = ellipsoid.cartographicToCartesian(neCarto); + var nw = ellipsoid.cartographicToCartesian(nwCarto); + + var direction = Cartesian3.subtract(ne, nw, new Cartesian3()); + var distance = Cartesian3.magnitude(direction) * 0.25; + Cartesian3.normalize(direction, direction); + Cartesian3.multiplyByScalar(direction, distance, direction); + + var center = Rectangle.center(rectangle); + var origin = ellipsoid.cartographicToCartesian(center); + + var origin1 = Cartesian3.add(origin, direction, new Cartesian3()); + var modelMatrix = Transforms.eastNorthUpToFixedFrame(origin1); + + var dimensions = new Cartesian3(500000.0, 1000000.0, 1000000.0); + + var boxColorAttribute = ColorGeometryInstanceAttribute.fromColor(new Color(0.0, 1.0, 1.0, 1.0)); + var boxInstance1 = new GeometryInstance({ + geometry : BoxGeometry.fromDimensions({ + dimensions : dimensions + }), + modelMatrix : modelMatrix, + id : 'box1', + attributes : { + color : boxColorAttribute + } + }); + + Cartesian3.negate(direction, direction); + var origin2 = Cartesian3.add(origin, direction, new Cartesian3()); + modelMatrix = Transforms.eastNorthUpToFixedFrame(origin2); + + var boxInstance2 = new GeometryInstance({ + geometry : BoxGeometry.fromDimensions({ + dimensions : dimensions + }), + modelMatrix : modelMatrix, + id : 'box2', + attributes : { + color : boxColorAttribute + } + }); + + primitive = new ClassificationPrimitive({ + geometryInstances : [boxInstance1, boxInstance2], + asynchronous : false + }); + verifyClassificationPrimitiveRender(primitive, boxColorAttribute.value); + }); + + it('renders bounding volume with debugShowBoundingVolume', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false, + debugShowBoundingVolume : true + }); + + scene.groundPrimitives.add(primitive); + scene.camera.setView({ destination : rectangle }); + expect(scene).toRenderAndCall(function(rgba) { + expect(rgba[1]).toBeGreaterThanOrEqualTo(0); + expect(rgba[1]).toBeGreaterThanOrEqualTo(0); + expect(rgba[2]).toBeGreaterThanOrEqualTo(0); + expect(rgba[3]).toEqual(255); + }); + }); + + it('renders shadow volume with debugShowShadowVolume', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false, + debugShowShadowVolume : true + }); + + scene.groundPrimitives.add(primitive); + scene.camera.setView({ destination : rectangle }); + expect(scene).toRenderAndCall(function(rgba) { + expect(rgba[1]).toBeGreaterThanOrEqualTo(0); + expect(rgba[1]).toBeGreaterThanOrEqualTo(0); + expect(rgba[2]).toBeGreaterThanOrEqualTo(0); + expect(rgba[3]).toEqual(255); + }); + }); + + it('get per instance attributes', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false + }); + + verifyClassificationPrimitiveRender(primitive, boxColor); + + var attributes = primitive.getGeometryInstanceAttributes('box'); + expect(attributes.color).toBeDefined(); + }); + + it('modify color instance attribute', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false + }); + + verifyClassificationPrimitiveRender(primitive, boxColor); + + scene.groundPrimitives.destroyPrimitives = false; + scene.groundPrimitives.removeAll(); + scene.groundPrimitives.destroyPrimitives = true; + + var newColor = [255, 255, 255, 255]; + var attributes = primitive.getGeometryInstanceAttributes('box'); + expect(attributes.color).toBeDefined(); + attributes.color = newColor; + + verifyClassificationPrimitiveRender(primitive, newColor); + }); + + it('modify show instance attribute', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + boxInstance.attributes.show = new ShowGeometryInstanceAttribute(true); + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false + }); + + verifyClassificationPrimitiveRender(primitive, boxColor); + + scene.groundPrimitives.destroyPrimitives = false; + scene.groundPrimitives.removeAll(); + scene.groundPrimitives.destroyPrimitives = true; + + var attributes = primitive.getGeometryInstanceAttributes('box'); + expect(attributes.show).toBeDefined(); + attributes.show = [0]; + + verifyClassificationPrimitiveRender(primitive, depthColor); + }); + + it('get bounding sphere from per instance attribute', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false + }); + + verifyClassificationPrimitiveRender(primitive, boxColor); + + var attributes = primitive.getGeometryInstanceAttributes('box'); + expect(attributes.boundingSphere).toBeDefined(); + }); + + it('getGeometryInstanceAttributes returns same object each time', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false + }); + + verifyClassificationPrimitiveRender(primitive, boxColor); + + var attributes = primitive.getGeometryInstanceAttributes('box'); + var attributes2 = primitive.getGeometryInstanceAttributes('box'); + expect(attributes).toBe(attributes2); + }); + + it('picking', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false + }); + + verifyClassificationPrimitiveRender(primitive, boxColor); + + expect(scene).toPickAndCall(function(result) { + expect(result.id).toEqual('box'); + }); + }); + + it('does not pick when allowPicking is false', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + allowPicking : false, + asynchronous : false + }); + + verifyClassificationPrimitiveRender(primitive, boxColor); + + expect(scene).notToPick(); + }); + + it('internally invalid asynchronous geometry resolves promise and sets ready', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : new GeometryInstance({ + geometry : PolygonGeometry.fromPositions({ + positions : [] + }), + attributes: { + color: ColorGeometryInstanceAttribute.fromColor(Color.RED) + } + }), + compressVertices : false + }); + + var frameState = scene.frameState; + frameState.afterRender.length = 0; + return pollToPromise(function() { + if (frameState.afterRender.length > 0) { + frameState.afterRender[0](); + return true; + } + primitive.update(frameState); + return false; + }).then(function() { + return primitive.readyPromise.then(function(arg) { + expect(arg).toBe(primitive); + expect(primitive.ready).toBe(true); + }); + }); + }); + + it('internally invalid synchronous geometry resolves promise and sets ready', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : new GeometryInstance({ + geometry : PolygonGeometry.fromPositions({ + positions : [] + }), + attributes: { + color: ColorGeometryInstanceAttribute.fromColor(Color.RED) + } + }), + asynchronous : false, + compressVertices : false + }); + + var frameState = scene.frameState; + frameState.afterRender.length = 0; + return pollToPromise(function() { + if (frameState.afterRender.length > 0) { + frameState.afterRender[0](); + return true; + } + primitive.update(frameState); + return false; + }).then(function() { + return primitive.readyPromise.then(function(arg) { + expect(arg).toBe(primitive); + expect(primitive.ready).toBe(true); + }); + }); + }); + + it('update throws when batched instance colors are different', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + var neCarto = Rectangle.northeast(rectangle); + var nwCarto = Rectangle.northwest(rectangle); + + var ne = ellipsoid.cartographicToCartesian(neCarto); + var nw = ellipsoid.cartographicToCartesian(nwCarto); + + var direction = Cartesian3.subtract(ne, nw, new Cartesian3()); + var distance = Cartesian3.magnitude(direction) * 0.25; + Cartesian3.normalize(direction, direction); + Cartesian3.multiplyByScalar(direction, distance, direction); + + var center = Rectangle.center(rectangle); + var origin = ellipsoid.cartographicToCartesian(center); + + var origin1 = Cartesian3.add(origin, direction, new Cartesian3()); + var modelMatrix = Transforms.eastNorthUpToFixedFrame(origin1); + + var dimensions = new Cartesian3(500000.0, 1000000.0, 1000000.0); + + var boxColorAttribute = ColorGeometryInstanceAttribute.fromColor(new Color(0.0, 1.0, 1.0, 1.0)); + var boxInstance1 = new GeometryInstance({ + geometry : BoxGeometry.fromDimensions({ + dimensions : dimensions + }), + modelMatrix : modelMatrix, + id : 'box1', + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(new Color(0.0, 1.0, 1.0, 1.0)) + } + }); + + Cartesian3.negate(direction, direction); + var origin2 = Cartesian3.add(origin, direction, new Cartesian3()); + modelMatrix = Transforms.eastNorthUpToFixedFrame(origin2); + + var boxInstance2 = new GeometryInstance({ + geometry : BoxGeometry.fromDimensions({ + dimensions : dimensions + }), + modelMatrix : modelMatrix, + id : 'box2', + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(new Color(1.0, 0.0, 1.0, 1.0)) + } + }); + + primitive = new ClassificationPrimitive({ + geometryInstances : [boxInstance1, boxInstance2], + asynchronous : false + }); + + expect(function() { + verifyClassificationPrimitiveRender(primitive, boxColorAttribute.value); + }).toThrowDeveloperError(); + }); + + it('update throws when one batched instance color is undefined', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + var neCarto = Rectangle.northeast(rectangle); + var nwCarto = Rectangle.northwest(rectangle); + + var ne = ellipsoid.cartographicToCartesian(neCarto); + var nw = ellipsoid.cartographicToCartesian(nwCarto); + + var direction = Cartesian3.subtract(ne, nw, new Cartesian3()); + var distance = Cartesian3.magnitude(direction) * 0.25; + Cartesian3.normalize(direction, direction); + Cartesian3.multiplyByScalar(direction, distance, direction); + + var center = Rectangle.center(rectangle); + var origin = ellipsoid.cartographicToCartesian(center); + + var origin1 = Cartesian3.add(origin, direction, new Cartesian3()); + var modelMatrix = Transforms.eastNorthUpToFixedFrame(origin1); + + var dimensions = new Cartesian3(500000.0, 1000000.0, 1000000.0); + + var boxColorAttribute = ColorGeometryInstanceAttribute.fromColor(new Color(0.0, 1.0, 1.0, 1.0)); + var boxInstance1 = new GeometryInstance({ + geometry : BoxGeometry.fromDimensions({ + dimensions : dimensions + }), + modelMatrix : modelMatrix, + id : 'box1', + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(new Color(0.0, 1.0, 1.0, 1.0)) + } + }); + + Cartesian3.negate(direction, direction); + var origin2 = Cartesian3.add(origin, direction, new Cartesian3()); + modelMatrix = Transforms.eastNorthUpToFixedFrame(origin2); + + var boxInstance2 = new GeometryInstance({ + geometry : BoxGeometry.fromDimensions({ + dimensions : dimensions + }), + modelMatrix : modelMatrix, + id : 'box2' + }); + + primitive = new ClassificationPrimitive({ + geometryInstances : [boxInstance1, boxInstance2], + asynchronous : false + }); + + expect(function() { + verifyClassificationPrimitiveRender(primitive, boxColorAttribute.value); + }).toThrowDeveloperError(); + }); + + it('setting per instance attribute throws when value is undefined', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false + }); + + verifyClassificationPrimitiveRender(primitive, boxColor); + + var attributes = primitive.getGeometryInstanceAttributes('box'); + + expect(function() { + attributes.color = undefined; + }).toThrowDeveloperError(); + }); + + it('can disable picking when asynchronous', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : true, + allowPicking : false + }); + + var frameState = scene.frameState; + + return pollToPromise(function() { + primitive.update(frameState); + if (frameState.afterRender.length > 0) { + frameState.afterRender[0](); + } + return primitive.ready; + }).then(function() { + var attributes = primitive.getGeometryInstanceAttributes('box'); + expect(function() { + attributes.color = undefined; + }).toThrowDeveloperError(); + }); + }); + + it('getGeometryInstanceAttributes throws without id', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false + }); + + verifyClassificationPrimitiveRender(primitive, boxColor); + + expect(function() { + primitive.getGeometryInstanceAttributes(); + }).toThrowDeveloperError(); + }); + + it('getGeometryInstanceAttributes throws if update was not called', function() { + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false + }); + + expect(function() { + primitive.getGeometryInstanceAttributes('box'); + }).toThrowDeveloperError(); + }); + + it('getGeometryInstanceAttributes returns undefined if id does not exist', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance, + asynchronous : false + }); + + verifyClassificationPrimitiveRender(primitive, boxColor); + + expect(primitive.getGeometryInstanceAttributes('unknown')).not.toBeDefined(); + }); + + it('isDestroyed', function() { + primitive = new ClassificationPrimitive(); + expect(primitive.isDestroyed()).toEqual(false); + primitive.destroy(); + expect(primitive.isDestroyed()).toEqual(true); + }); + + it('renders when using asynchronous pipeline', function() { + if (!ClassificationPrimitive.isSupported(scene)) { + return; + } + + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance + }); + + var frameState = scene.frameState; + + return pollToPromise(function() { + primitive.update(frameState); + if (frameState.afterRender.length > 0) { + frameState.afterRender[0](); + } + return primitive.ready; + }).then(function() { + verifyClassificationPrimitiveRender(primitive, boxColor); + }); + }); + + it('destroy before asynchonous pipeline is complete', function() { + primitive = new ClassificationPrimitive({ + geometryInstances : boxInstance + }); + + var frameState = scene.frameState; + primitive.update(frameState); + + primitive.destroy(); + expect(primitive.isDestroyed()).toEqual(true); + }); +}, 'WebGL'); diff --git a/Specs/Scene/GroundPrimitiveSpec.js b/Specs/Scene/GroundPrimitiveSpec.js index 54c22f83c35a..f80c0fcdb7fa 100644 --- a/Specs/Scene/GroundPrimitiveSpec.js +++ b/Specs/Scene/GroundPrimitiveSpec.js @@ -152,6 +152,7 @@ defineSuite([ expect(primitive.allowPicking).toEqual(true); expect(primitive.asynchronous).toEqual(true); expect(primitive.debugShowBoundingVolume).toEqual(false); + expect(primitive.debugShowShadowVolume).toEqual(false); }); it('constructs with options', function() { @@ -166,7 +167,8 @@ defineSuite([ releaseGeometryInstances : false, allowPicking : false, asynchronous : false, - debugShowBoundingVolume : true + debugShowBoundingVolume : true, + debugShowShadowVolume : true }); expect(primitive.geometryInstances).toEqual(geometryInstances); @@ -178,6 +180,7 @@ defineSuite([ expect(primitive.allowPicking).toEqual(false); expect(primitive.asynchronous).toEqual(false); expect(primitive.debugShowBoundingVolume).toEqual(true); + expect(primitive.debugShowShadowVolume).toEqual(true); }); it('releases geometry instances when releaseGeometryInstances is true', function() { From 217acfefee123561f4738505e62c2ed7cd9093c1 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 14:37:42 -0400 Subject: [PATCH 045/132] Now using a more comprehensive regex rather than the old recursive solution --- Source/Renderer/GLSLModernizer.js | 75 ++++--------------------------- 1 file changed, 8 insertions(+), 67 deletions(-) diff --git a/Source/Renderer/GLSLModernizer.js b/Source/Renderer/GLSLModernizer.js index 22fe87c225ce..32efe943a6f3 100644 --- a/Source/Renderer/GLSLModernizer.js +++ b/Source/Renderer/GLSLModernizer.js @@ -39,82 +39,24 @@ define([ if (outputDeclarationLine === -1) { throw new DeveloperError('Could not find a #define OUTPUT_DECLARATION nor a main function!'); } - - function safeNameFalseNegative(regex, region) { - var regExpStr = regex.toString(); - regExpStr = regExpStr.match(/\/([^\/]+)(\/.)?/)[1]; - var somethingBadInString = - new RegExp("[a-zA-Z0-9_]+" + regExpStr, 'g'); - var searchResult = region.search(somethingBadInString); - if (searchResult === -1) { - return true; - } else { - return false; - } - } - - function safeNameFind(regex, str) { - var originalMatch = regex.exec(str); - if (originalMatch === null) { - return -1; - } - var endPos = originalMatch.index + originalMatch[0].length; - var region = str.substring(0, endPos); - - var possiblyFalseNegative = safeNameFalseNegative(regex, region); - if (possiblyFalseNegative) { - return endPos; - } else { - var childResult = safeNameFind(regex, str.substring(endPos)); - if (childResult === -1) { - return -1; - } else { - return endPos + childResult; - } - } - } - - function safeNameReplace(regex, str, replacement) { - var originalMatch = regex.exec(str); - if (originalMatch === null) { - return str; - } - var endPos = originalMatch.index + originalMatch[0].length; - var region = str.substring(0, endPos); - - var possiblyFalseNegative = safeNameFalseNegative(regex, region); - if (possiblyFalseNegative) { - return region.replace(regex, replacement) + safeNameReplace(regex, str.substr(endPos), replacement); - } else { - return region + safeNameReplace(regex, str.substr(endPos), replacement); - } - } + // Note that this fails if your string looks like + // searchString[singleCharacter]searchString function replaceInSource(str, replacement, strIsRegex) { - var replaceAll = function(target, search, replacement) { - return target.split(search).join(replacement); - }; - var regex = str; if (!defined(strIsRegex) || strIsRegex === false) { - /*var regexStr = "(?:^.*[^\\w](" + str + - ")[^\\w].*$|^(" + str + - ")[^\\w].*$|^.*[^\\w](" + str + - ")$|^(" + str + ")$)"; - regex = new RegExp(regexStr, 'g');*/ - regex = new RegExp(str, 'g'); + var regexStr = "(^|[^\\w])(" + str + ")($|[^\\w])"; + regex = new RegExp(regexStr, 'g'); } for (var number = 0; number < splitSource.length; ++number) { - splitSource[number] = safeNameReplace(regex, splitSource[number], replacement); - //splitSource[number] = replaceAll(splitSource[number], regex, replacement); + splitSource[number] = splitSource[number].replace(regex, function (match, group1, group2, group3) { + return group1 + replacement + group2; + }); } } function findInSource(str) { - var regexStr = "(^.*[^\\w](" + str + - ")[^\\w].*$|^(" + str + - ")[^\\w].*$|^.*[^\\w](" + str + - ")$|^(" + str + ")$)"; + var regexStr = "(^|[^\\w])(" + str + ")($|[^\\w])"; var regex = new RegExp(regexStr, 'g'); for (var number = 0; number < splitSource.length; ++number) { var line = splitSource[number]; @@ -309,7 +251,6 @@ define([ replaceInSource("varying", "out"); } - console.log(compileSource()); return compileSource(); } From 21a5fc96a1d7ea94b81204a523940d0f01eca4bc Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 13 Jul 2017 14:37:59 -0400 Subject: [PATCH 046/132] Update Sandcastle example. --- .../ClassificationPrimitive.html | 4 ++-- .../development/ClassificationPrimitive.jpg | Bin 0 -> 22152 bytes 2 files changed, 2 insertions(+), 2 deletions(-) rename Apps/Sandcastle/gallery/{ => development}/ClassificationPrimitive.html (95%) create mode 100644 Apps/Sandcastle/gallery/development/ClassificationPrimitive.jpg diff --git a/Apps/Sandcastle/gallery/ClassificationPrimitive.html b/Apps/Sandcastle/gallery/development/ClassificationPrimitive.html similarity index 95% rename from Apps/Sandcastle/gallery/ClassificationPrimitive.html rename to Apps/Sandcastle/gallery/development/ClassificationPrimitive.html index bee4474bad45..c74dd18f2905 100644 --- a/Apps/Sandcastle/gallery/ClassificationPrimitive.html +++ b/Apps/Sandcastle/gallery/development/ClassificationPrimitive.html @@ -4,8 +4,8 @@ - - + + Cesium Demo diff --git a/Apps/Sandcastle/gallery/development/ClassificationPrimitive.jpg b/Apps/Sandcastle/gallery/development/ClassificationPrimitive.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ae698066ca15b19307a2fe1079488df399d6f08f GIT binary patch literal 22152 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 literal 0 HcmV?d00001 From bb54839390964d9fabc063e64ce6428c9bf351fb Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 13 Jul 2017 14:44:10 -0400 Subject: [PATCH 047/132] Update CHANGES.md. --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 28ac687b486d..9942ba9b27b0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ Change Log ### 1.36 - 2017-08-01 * Added ability to show tile urls in the 3D Tiles Inspector. [#5592](https://github.com/AnalyticalGraphicsInc/cesium/pull/5592) +* Added `ClassificationPrimitive` which defines a volume and draws the intersection of the volume and terrain or 3D Tiles. [#5625](https://github.com/AnalyticalGraphicsInc/cesium/pull/5625) ### 1.35.2 - 2017-07-11 From 39c2c2a851881b87c06214e91df229b78c3cfb01 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 15:37:16 -0400 Subject: [PATCH 048/132] Bugfix in replaceInSource --- Source/Renderer/GLSLModernizer.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Source/Renderer/GLSLModernizer.js b/Source/Renderer/GLSLModernizer.js index 32efe943a6f3..4050067df2b5 100644 --- a/Source/Renderer/GLSLModernizer.js +++ b/Source/Renderer/GLSLModernizer.js @@ -44,14 +44,18 @@ define([ // searchString[singleCharacter]searchString function replaceInSource(str, replacement, strIsRegex) { var regex = str; - if (!defined(strIsRegex) || strIsRegex === false) { + if ((strIsRegex === undefined) || strIsRegex === false) { var regexStr = "(^|[^\\w])(" + str + ")($|[^\\w])"; regex = new RegExp(regexStr, 'g'); } + for (var number = 0; number < splitSource.length; ++number) { - splitSource[number] = splitSource[number].replace(regex, function (match, group1, group2, group3) { - return group1 + replacement + group2; - }); + var line = splitSource[number]; + if (strIsRegex) { + splitSource[number] = line.replace(regex, replacement); + } else { + splitSource[number] = line.replace(regex, "$1" + replacement + "$3"); + } } } From 405951dc135db42cda920ecd778a2b836e544d35 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 15:40:38 -0400 Subject: [PATCH 049/132] Fixes floatingPointTexture flag false positive in WebGL 2 --- Source/Renderer/Context.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Renderer/Context.js b/Source/Renderer/Context.js index 5110b4265d48..b92bfa2e916c 100644 --- a/Source/Renderer/Context.js +++ b/Source/Renderer/Context.js @@ -525,7 +525,7 @@ define([ */ floatingPointTexture : { get : function() { - return this._textureFloat || this._webgl2; + return this._textureFloat || this._colorBufferFloat; } }, From 9f4f84c0b3c088cdbeec87bcd9db15e0c28541e2 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 16:13:18 -0400 Subject: [PATCH 050/132] Adds first test for GLSLModernizer --- Specs/Renderer/GLSLModernizerSpec.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 Specs/Renderer/GLSLModernizerSpec.js diff --git a/Specs/Renderer/GLSLModernizerSpec.js b/Specs/Renderer/GLSLModernizerSpec.js new file mode 100644 index 000000000000..1d7e8618f5e4 --- /dev/null +++ b/Specs/Renderer/GLSLModernizerSpec.js @@ -0,0 +1,21 @@ +defineSuite([ + 'Renderer/GLSLModernizer' + ], function( + glslModernizeShaderText) { + 'use strict'; + + it ('adds version string', function() { + var simple = '#define OUTPUT_DECLARATION \n' + + 'void main() \n' + + '{ \n' + + '} \n'; + var output = glslModernizeShaderText(simple, true); + var expected = '#version 300 es\n' + + '#define OUTPUT_DECLARATION \n' + + 'void main() \n' + + '{ \n' + + '} \n' + + '\n'; + expect(output).toEqual(expected); + }); +}); From 4745e84b498cac1ee05bcd67f2f569a48e48ead9 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 16:34:05 -0400 Subject: [PATCH 051/132] Adds a few more tests, mostly for layout qualifiers --- Specs/Renderer/GLSLModernizerSpec.js | 85 ++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/Specs/Renderer/GLSLModernizerSpec.js b/Specs/Renderer/GLSLModernizerSpec.js index 1d7e8618f5e4..837a545bef22 100644 --- a/Specs/Renderer/GLSLModernizerSpec.js +++ b/Specs/Renderer/GLSLModernizerSpec.js @@ -5,17 +5,92 @@ defineSuite([ 'use strict'; it ('adds version string', function() { - var simple = '#define OUTPUT_DECLARATION \n' + + var simple = + '#define OUTPUT_DECLARATION \n' + 'void main() \n' + '{ \n' + '} \n'; var output = glslModernizeShaderText(simple, true); - var expected = '#version 300 es\n' + + var expected = '#version 300 es'; + expect(output.split('\n')[0]).toEqual(expected); + }); + + it ('removes extensions', function() { + var extensions = '#define OUTPUT_DECLARATION \n' + + '#extension GL_EXT_draw_buffers : enable \n' + 'void main() \n' + '{ \n' + - '} \n' + - '\n'; - expect(output).toEqual(expected); + '} \n'; + var output = glslModernizeShaderText(extensions, true); + var notExpected = '#extension GL_EXT_draw_buffers : enable \n'; + expect(output).not.toContain(notExpected); + }); + + it ('throws exception if no output declaration', function() { + var noOutputDeclaration = + 'void main() \n' + + '{ \n' + + '} \n'; + var runFunc = function() { + glslModernizeShaderText(noOutputDeclaration, true); + }; + expect(runFunc).toThrow(); + }); + + it ('creates layout qualifier for gl_FragColor', function() { + var noQualifiers = + '#define OUTPUT_DECLARATION \n' + + 'void main() \n' + + '{ \n' + + ' gl_FragColor = vec4(0.0); \n' + + '} \n'; + var output = glslModernizeShaderText(noQualifiers, true); + var expected = 'layout(location = 0) out vec4 czm_fragColor;'; + expect(output).toContain(expected); + }); + + it ('creates layout qualifier for gl_FragData', function() { + var noQualifiers = + '#define OUTPUT_DECLARATION \n' + + 'void main() \n' + + '{ \n' + + ' gl_FragData[0] = vec4(0.0); \n' + + '} \n'; + var output = glslModernizeShaderText(noQualifiers, true); + var expected = 'layout(location = 0) out vec4 czm_out0;'; + expect(output).toContain(expected); + }); + + it ('creates layout qualifier for MRT', function() { + var noQualifiers = + '#define OUTPUT_DECLARATION \n' + + '#extension GL_EXT_draw_buffers : enable \n' + + 'void main() \n' + + '{ \n' + + ' gl_FragData[0] = vec4(0.0); \n' + + ' gl_FragData[1] = vec4(1.0); \n' + + '} \n'; + var output = glslModernizeShaderText(noQualifiers, true); + var expected0 = 'layout(location = 0) out vec4 czm_out0;'; + var expected1 = 'layout(location = 1) out vec4 czm_out1;'; + expect(output).toContain(expected0); + expect(output).toContain(expected1); + }); + + it ('creates layout qualifier under single condition', function() { + var noQualifiers = + '#define OUTPUT_DECLARATION \n' + + '#define EXAMPLE_BRANCH \n' + + 'void main() \n' + + '{ \n' + + ' #ifdef EXAMPLE_BRANCH \n' + + ' gl_FragData[0] = vec4(0.0); \n' + + ' gl_FragData[1] = vec4(1.0); \n' + + ' #endif //EXAMPLE_BRANCH \n' + + '} \n'; + var output = glslModernizeShaderText(noQualifiers, true); + var expected = '#ifdef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_out0;\n#endif'; + expect(output).toContain(expected); }); }); From 7c58a657a7e9695abef3181900a6d4b956ccd0f5 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 16:49:03 -0400 Subject: [PATCH 052/132] Adds a few more tests --- Specs/Renderer/GLSLModernizerSpec.js | 83 +++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/Specs/Renderer/GLSLModernizerSpec.js b/Specs/Renderer/GLSLModernizerSpec.js index 837a545bef22..3e9efc38a91e 100644 --- a/Specs/Renderer/GLSLModernizerSpec.js +++ b/Specs/Renderer/GLSLModernizerSpec.js @@ -78,7 +78,7 @@ defineSuite([ expect(output).toContain(expected1); }); - it ('creates layout qualifier under single condition', function() { + it ('creates single layout qualifier under single branch, single condition', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + '#define EXAMPLE_BRANCH \n' + @@ -86,11 +86,90 @@ defineSuite([ '{ \n' + ' #ifdef EXAMPLE_BRANCH \n' + ' gl_FragData[0] = vec4(0.0); \n' + - ' gl_FragData[1] = vec4(1.0); \n' + ' #endif //EXAMPLE_BRANCH \n' + '} \n'; var output = glslModernizeShaderText(noQualifiers, true); var expected = '#ifdef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_out0;\n#endif'; expect(output).toContain(expected); }); + + it ('creates multiple layout qualifiers under single branch, single condition', function() { + var noQualifiers = + '#define OUTPUT_DECLARATION \n' + + '#define EXAMPLE_BRANCH \n' + + 'void main() \n' + + '{ \n' + + ' #ifdef EXAMPLE_BRANCH \n' + + ' gl_FragData[0] = vec4(0.0); \n' + + ' gl_FragData[1] = vec4(1.0); \n' + + ' #endif //EXAMPLE_BRANCH \n' + + '} \n'; + var output = glslModernizeShaderText(noQualifiers, true); + var expected0 = '#ifdef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_out0;\n#endif'; + var expected1 = '#ifdef EXAMPLE_BRANCH \nlayout(location = 1) out vec4 czm_out1;\n#endif'; + expect(output).toContain(expected0); + expect(output).toContain(expected1); + }); + + it ('creates multiple layout qualifiers under multiple branches, single condition (cancels)', function() { + var noQualifiers = + '#define OUTPUT_DECLARATION \n' + + '#define EXAMPLE_BRANCH \n' + + 'void main() \n' + + '{ \n' + + ' #ifdef EXAMPLE_BRANCH \n' + + ' gl_FragData[0] = vec4(0.0); \n' + + ' gl_FragData[1] = vec4(1.0); \n' + + ' #endif //EXAMPLE_BRANCH \n' + + ' #ifndef EXAMPLE_BRANCH \n' + + ' gl_FragData[0] = vec4(0.0); \n' + + ' gl_FragData[1] = vec4(1.0); \n' + + ' #endif //!EXAMPLE_BRANCH \n' + + '} \n'; + var output = glslModernizeShaderText(noQualifiers, true); + var notExpected = '#ifdef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_out0;\n#endif'; + expect(output).not.toContain(notExpected); + }); + + it ('creates single layout qualifier under multiple branches, multiple conditions (cancels)', function() { + var noQualifiers = + '#define OUTPUT_DECLARATION \n' + + '#define EXAMPLE_BRANCH \n' + + '#define EXAMPLE_BRANCH1 \n' + + 'void main() \n' + + '{ \n' + + ' #ifdef EXAMPLE_BRANCH \n' + + ' gl_FragData[0] = vec4(0.0); \n' + + ' #endif //EXAMPLE_BRANCH \n' + + ' #ifdef EXAMPLE_BRANCH1 \n' + + ' gl_FragData[0] = vec4(0.0); \n' + + ' #endif //EXAMPLE_BRANCH1 \n' + + '} \n'; + var output = glslModernizeShaderText(noQualifiers, true); + var notExpected = '#ifdef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_out0;\n#endif'; + expect(output).not.toContain(notExpected); + }); + + it ('creates multiple layout qualifier under multiple branches, multiple conditions (cascades)', function() { + var noQualifiers = + '#define OUTPUT_DECLARATION \n' + + '#define EXAMPLE_BRANCH \n' + + '#define EXAMPLE_BRANCH1 \n' + + 'void main() \n' + + '{ \n' + + ' #ifdef EXAMPLE_BRANCH \n' + + ' gl_FragData[0] = vec4(0.0); \n' + + ' #ifdef EXAMPLE_BRANCH1 \n' + + ' gl_FragData[1] = vec4(0.0); \n' + + ' #endif //EXAMPLE_BRANCH1 \n' + + ' #endif //EXAMPLE_BRANCH \n' + + '} \n'; + var output = glslModernizeShaderText(noQualifiers, true); + var expected0 = '#ifdef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_out0;\n#endif'; + var expected1 = ['#ifdef EXAMPLE_BRANCH \n#ifdef EXAMPLE_BRANCH1 \nlayout(location = 0) out vec4 czm_out0;\n#endif', + '#ifdef EXAMPLE_BRANCH1 \n#ifdef EXAMPLE_BRANCH0 \nlayout(location = 0) out vec4 czm_out0;\n#endif']; + var containsExpected0 = ((output.indexOf(expected0[0]) !== -1) && (output.indexOf(expected0[1]) !== -1)); + expect(output).toContain(expected0); + expect(containsExpected0).toBe(true); + }); }); From a1d26cbf03a45901ca81cb56d794fc1e698b2da9 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 17:14:19 -0400 Subject: [PATCH 053/132] Adds even more tests --- Specs/Renderer/GLSLModernizerSpec.js | 125 ++++++++++++++++++++++++++- 1 file changed, 123 insertions(+), 2 deletions(-) diff --git a/Specs/Renderer/GLSLModernizerSpec.js b/Specs/Renderer/GLSLModernizerSpec.js index 3e9efc38a91e..cba1d738b0b4 100644 --- a/Specs/Renderer/GLSLModernizerSpec.js +++ b/Specs/Renderer/GLSLModernizerSpec.js @@ -78,6 +78,91 @@ defineSuite([ expect(output).toContain(expected1); }); + it ('creates layout qualifier with swizzle', function() { + var noQualifiers = + '#define OUTPUT_DECLARATION \n' + + '#extension GL_EXT_draw_buffers : enable \n' + + 'void main() \n' + + '{ \n' + + ' gl_FragData[0] = vec4(0.0); \n' + + ' gl_FragData[1].xyz = vec3(1.0); \n' + + '} \n'; + var output = glslModernizeShaderText(noQualifiers, true); + var expected0 = 'layout(location = 0) out vec4 czm_out0;'; + var expected1 = 'layout(location = 1) out vec4 czm_out1;'; + expect(output).toContain(expected0); + expect(output).toContain(expected1); + }); + + it ('removes old functions/variables from fragment shader', function() { + var old_fragment = + '#define OUTPUT_DECLARATION \n' + + '#extension GL_EXT_draw_buffers : enable \n' + + 'uniform sampler2D example; \n' + + 'uniform sampler2D exampleCube; \n' + + 'uniform sampler2D example3D; \n' + + 'varying vec2 v_textureCoordinates; \n' + + 'void main() \n' + + '{ \n' + + ' gl_FragData[0] = texture2D(example, v_textureCoordinates); \n' + + ' gl_FragData[1] = textureCube(exampleCube, v_textureCoordinates); \n' + + ' gl_FragData[2] = texture3D(example3D, v_textureCoordinates); \n' + + ' gl_FragDepthEXT = 0.0; \n' + + '} \n'; + + var output = glslModernizeShaderText(old_fragment, true); + + var expectedDepth = 'gl_FragDepth = 0.0;'; + var expectedTexture2D = 'texture(example, v_textureCoordinates);'; + var expectedTextureCube = 'texture(exampleCube, v_textureCoordinates);'; + var expectedTexture3D = 'texture(example3D, v_textureCoordinates);'; + var expectedIn = 'in vec2 v_textureCoordinates;'; + + var notExpectedDepth = 'gl_FragDepthEXT = 0.0;'; + var notExpectedTexture2D = 'texture2D(example, v_textureCoordinates);'; + var notExpectedTextureCube = 'textureCube(exampleCube, v_textureCoordinates);'; + var notExpectedTexture3D = 'texture3D(example3D, v_textureCoordinates);'; + var notExpectedVarying = 'varying vec2 v_textureCoordinates;'; + + expect(output).toContain(expectedDepth); + expect(output).toContain(expectedTexture2D); + expect(output).toContain(expectedTextureCube); + expect(output).toContain(expectedTexture3D); + expect(output).toContain(expectedIn); + + expect(output).not.toContain(notExpectedDepth); + expect(output).not.toContain(notExpectedTexture2D); + expect(output).not.toContain(notExpectedTextureCube); + expect(output).not.toContain(notExpectedTexture3D); + expect(output).not.toContain(notExpectedVarying); + }); + + it ('removes old functions/variables from vertex shader', function() { + var old_vertex = + '#define OUTPUT_DECLARATION \n' + + 'attribute vec4 position; \n' + + 'varying vec4 varyingVariable; \n'; + 'void main() \n' + + '{ \n' + + ' gl_Position = position; \n' + + ' varyingVariable = position.wzyx; \n' + + '} \n'; + + var output = glslModernizeShaderText(old_vertex, false); + + var expectedOut = 'out vec4 varyingVariable;'; + var expectedIn = 'in vec4 position;'; + + var notExpectedAttribute = 'attribute vec4 varyingVariable;'; + var notExpectedVarying = 'varying vec2 varyingVariable;'; + + expect(output).toContain(expectedOut); + expect(output).toContain(expectedIn); + + expect(output).not.toContain(notExpectedAttribute); + expect(output).not.toContain(notExpectedVarying); + }); + it ('creates single layout qualifier under single branch, single condition', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + @@ -150,7 +235,7 @@ defineSuite([ expect(output).not.toContain(notExpected); }); - it ('creates multiple layout qualifier under multiple branches, multiple conditions (cascades)', function() { + it ('creates multiple layout qualifiers under multiple branches, multiple conditions (cascades)', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + '#define EXAMPLE_BRANCH \n' + @@ -160,7 +245,7 @@ defineSuite([ ' #ifdef EXAMPLE_BRANCH \n' + ' gl_FragData[0] = vec4(0.0); \n' + ' #ifdef EXAMPLE_BRANCH1 \n' + - ' gl_FragData[1] = vec4(0.0); \n' + + ' gl_FragData[1] = vec4(1.0); \n' + ' #endif //EXAMPLE_BRANCH1 \n' + ' #endif //EXAMPLE_BRANCH \n' + '} \n'; @@ -172,4 +257,40 @@ defineSuite([ expect(output).toContain(expected0); expect(containsExpected0).toBe(true); }); + + it ('creates single layout qualifier under multiple branches, single condition (else)', function() { + var noQualifiers = + '#define OUTPUT_DECLARATION \n' + + '#define EXAMPLE_BRANCH \n' + + 'void main() \n' + + '{ \n' + + ' #ifdef EXAMPLE_BRANCH \n' + + ' gl_FragData[0] = vec4(0.0); \n' + + ' #else \n' + + ' gl_FragData[0] = vec4(1.0); \n' + + ' #endif //EXAMPLE_BRANCH \n' + + '} \n'; + var output = glslModernizeShaderText(noQualifiers, true); + var notExpected = '#ifdef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_out0;\n#endif'; + expect(output).not.toContain(notExpected); + }); + + it ('creates branched layout qualifiers for gl_FragColor and gl_FragData', function() { + var noQualifiers = + '#define OUTPUT_DECLARATION \n' + + '#define EXAMPLE_BRANCH \n' + + 'void main() \n' + + '{ \n' + + ' #ifdef EXAMPLE_BRANCH \n' + + ' gl_FragData[0] = vec4(0.0); \n' + + ' #else \n' + + ' gl_FragColor = vec4(1.0); \n' + + ' #endif //EXAMPLE_BRANCH \n' + + '} \n'; + var output = glslModernizeShaderText(noQualifiers, true); + var expected0 = '#ifdef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_out0;\n#endif'; + var expected1 = '#ifndef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_fragColor;\n#endif'; + expect(output).toContain(expected0); + expect(output).toContain(expected1); + }); }); From ea6c0317276b895b746d49bfe2a074d0cc69abba Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Thu, 13 Jul 2017 17:27:01 -0400 Subject: [PATCH 054/132] Adds test for poorly named variables --- Specs/Renderer/GLSLModernizerSpec.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Specs/Renderer/GLSLModernizerSpec.js b/Specs/Renderer/GLSLModernizerSpec.js index cba1d738b0b4..09935feece1d 100644 --- a/Specs/Renderer/GLSLModernizerSpec.js +++ b/Specs/Renderer/GLSLModernizerSpec.js @@ -78,6 +78,28 @@ defineSuite([ expect(output).toContain(expected1); }); + it ('does not create layout qualifier for reserved word lookalike variables functions', function() { + var noQualifiers = + '#define OUTPUT_DECLARATION \n' + + 'uniform sampler2D example; \n' + + 'void main() \n' + + '{ \n' + + ' vec4 gl_FragData_ = vec4(0.0); \n' + + ' vec4 a_gl_FragData = vec4(0.0); \n' + + ' vec2 thisIsNotAGoodNameForAtexture2D = vec2(0.0); \n' + + ' vec4 gl_FragColor = texture2D(example, thisIsNotAGoodNameForAtexture2D); \n' + + '} \n'; + var output = glslModernizeShaderText(noQualifiers, true); + var expectedBadName = 'vec2 thisIsNotAGoodNameForAtexture2D'; + var expectedVariable = 'vec4 a_gl_FragData = vec4(0.0);'; + var expectedTextureCall = 'texture(example, thisIsNotAGoodNameForAtexture2D)'; + var notExpectedLayout = 'layout(location = 0) out czm_out'; + expect(output).toContain(expectedBadName); + expect(output).toContain(expectedVariable); + expect(output).toContain(expectedTextureCall); + expect(output).not.toContain(notExpectedLayout); + }); + it ('creates layout qualifier with swizzle', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + From 15f1cbc13964110fdd328f633484ed4df28b1d3b Mon Sep 17 00:00:00 2001 From: Heiko Thiel Date: Fri, 14 Jul 2017 14:07:51 +0200 Subject: [PATCH 055/132] Added support of interpreting existing defines in Cesium3DTileStyle setter --- Source/Scene/Cesium3DTileStyle.js | 65 ++++++---------------- Specs/Scene/Cesium3DTileStyleSpec.js | 83 ++++++++++------------------ 2 files changed, 48 insertions(+), 100 deletions(-) diff --git a/Source/Scene/Cesium3DTileStyle.js b/Source/Scene/Cesium3DTileStyle.js index ee7fb02aae85..f7612bba6598 100644 --- a/Source/Scene/Cesium3DTileStyle.js +++ b/Source/Scene/Cesium3DTileStyle.js @@ -95,49 +95,17 @@ define([ styleJson = defaultValue(styleJson, defaultValue.EMPTY_OBJECT); + that.color = defaultValue(styleJson.color, DEFAULT_JSON_COLOR_EXPRESSION); + that.show = defaultValue(styleJson.show, DEFAULT_JSON_BOOLEAN_EXPRESSION); + that.pointSize = defaultValue(styleJson.pointSize, DEFAULT_JSON_NUMBER_EXPRESSION); + that._colorShaderFunctionReady = !defined(styleJson.color); that._showShaderFunctionReady = !defined(styleJson.show); that._pointSizeShaderFunctionReady = !defined(styleJson.pointSize); - var colorExpression = defaultValue(styleJson.color, DEFAULT_JSON_COLOR_EXPRESSION); - var showExpression = defaultValue(styleJson.show, DEFAULT_JSON_BOOLEAN_EXPRESSION); - var pointSizeExpression = defaultValue(styleJson.pointSize, DEFAULT_JSON_NUMBER_EXPRESSION); - - var defines = styleJson.defines; - - var color; - if (typeof colorExpression === 'string') { - color = new Expression(colorExpression, defines); - } else if (defined(colorExpression.conditions)) { - color = new ConditionsExpression(colorExpression, defines); - } - - that._color = color; - - var show; - if (typeof showExpression === 'boolean') { - show = new Expression(String(showExpression), defines); - } else if (typeof showExpression === 'string') { - show = new Expression(showExpression, defines); - } else if (defined(showExpression.conditions)) { - show = new ConditionsExpression(showExpression, defines); - } - - that._show = show; - - var pointSize; - if (typeof pointSizeExpression === 'number') { - pointSize = new Expression(String(pointSizeExpression), defines); - } else if (typeof pointSizeExpression === 'string') { - pointSize = new Expression(pointSizeExpression, defines); - } else if (defined(pointSizeExpression.conditions)) { - pointSize = new ConditionsExpression(pointSizeExpression, defines); - } - - that._pointSize = pointSize; - var meta = {}; if (defined(styleJson.meta)) { + var defines = styleJson.defines; var metaJson = defaultValue(styleJson.meta, defaultValue.EMPTY_OBJECT); for (var property in metaJson) { if (metaJson.hasOwnProperty(property)) { @@ -240,13 +208,13 @@ define([ * // Override show expression with a boolean * style.show = true; * }; - * + * * @example * var style = new Cesium.Cesium3DTileStyle(); * // Override show expression with a string * style.show = '${Height} > 0'; * }; - * + * * @example * var style = new Cesium.Cesium3DTileStyle(); * // Override show expression with a condition @@ -256,7 +224,7 @@ define([ * ['true', 'true'] * ]; * }; - */ + */ show : { get : function() { //>>includeStart('debug', pragmas.debug); @@ -268,12 +236,13 @@ define([ return this._show; }, set : function(value) { + var defines = defaultValue(this._style, defaultValue.EMPTY_OBJECT).defines; if (typeof value === 'boolean') { this._show = new Expression(String(value)); } else if (typeof value === 'string') { - this._show = new Expression(value); + this._show = new Expression(value, defines); } else if (defined(value.conditions)) { - this._show = new ConditionsExpression(value); + this._show = new ConditionsExpression(value, defines); } else { this._show = value; } @@ -334,10 +303,11 @@ define([ return this._color; }, set : function(value) { + var defines = defaultValue(this._style, defaultValue.EMPTY_OBJECT).defines; if (typeof value === 'string') { - this._color = new Expression(value); + this._color = new Expression(value, defines); } else if (defined(value.conditions)) { - this._color = new ConditionsExpression(value); + this._color = new ConditionsExpression(value, defines); } else { this._color = value; } @@ -391,7 +361,7 @@ define([ * ['true', '2.0'] * ] * }; - */ + */ pointSize : { get : function() { //>>includeStart('debug', pragmas.debug); @@ -403,12 +373,13 @@ define([ return this._pointSize; }, set : function(value) { + var defines = defaultValue(this._style, defaultValue.EMPTY_OBJECT).defines; if (typeof value === 'number') { this._pointSize = new Expression(String(value)); } else if (typeof value === 'string') { - this._pointSize = new Expression(value); + this._pointSize = new Expression(value, defines); } else if (defined(value.conditions)) { - this._pointSize = new ConditionsExpression(value); + this._pointSize = new ConditionsExpression(value, defines); } else { this._pointSize = value; } diff --git a/Specs/Scene/Cesium3DTileStyleSpec.js b/Specs/Scene/Cesium3DTileStyleSpec.js index e0005b50d272..a36bbf997a41 100644 --- a/Specs/Scene/Cesium3DTileStyleSpec.js +++ b/Specs/Scene/Cesium3DTileStyleSpec.js @@ -147,13 +147,6 @@ defineSuite([ expect(style.show).toEqual(new ConditionsExpression(jsonExp)); }); - it('sets show to undefined if not a string, boolean, or conditional', function() { - var style = new Cesium3DTileStyle({ - show : 1 - }); - expect(style.show).toEqual(undefined); - }); - it('sets show expressions in setter', function() { var style = new Cesium3DTileStyle(); @@ -173,9 +166,14 @@ defineSuite([ }); it('sets show values in setter', function() { - var style = new Cesium3DTileStyle(); + var defines = { + 'defines': { + 'showFactor': 10 + } + }; + var style = new Cesium3DTileStyle(defines); - style.show = '${height} * 10 >= 1000'; + style.show = '${height} * ${showFactor} >= 1000'; expect(style.show).toEqual(new Expression('${height} * 10 >= 1000')); style.show = false; @@ -183,24 +181,15 @@ defineSuite([ var jsonExp = { conditions : [ - ['${height} > 2', 'false'], + ['${height} > ${showFactor}', 'false'], ['true', 'true'] ] }; style.show = jsonExp; - expect(style.show).toEqual(new ConditionsExpression(jsonExp)); + expect(style.show).toEqual(new ConditionsExpression(jsonExp, defines)); }); - it('sets show to undefined if not a string, boolean or conditional in setter', function() { - var style = new Cesium3DTileStyle({ - show : true - }); - - style.show = 5; - expect(style.show).toEqual(undefined); - }); - it('sets color value to expression', function() { var style = new Cesium3DTileStyle({ color : 'color("red")' @@ -232,13 +221,6 @@ defineSuite([ expect(style.color).toEqual(new ConditionsExpression(jsonExp)); }); - it('sets color to undefined if not a string or conditional', function() { - var style = new Cesium3DTileStyle({ - color : 1 - }); - expect(style.color).toEqual(undefined); - }); - it('sets color expressions in setter', function() { var style = new Cesium3DTileStyle(); @@ -258,15 +240,20 @@ defineSuite([ }); it('sets color values in setter', function() { - var style = new Cesium3DTileStyle(); + var defines = { + 'defines': { + 'targetColor': 'red' + } + }; + var style = new Cesium3DTileStyle(defines); - style.color = 'color("red")'; + style.color = 'color("${targetColor}")'; expect(style.color).toEqual(new Expression('color("red")')); var jsonExp = { conditions : [ ['${height} > 2', 'color("cyan")'], - ['true', 'color("blue")'] + ['true', 'color("${targetColor}")'] ] }; @@ -274,15 +261,6 @@ defineSuite([ expect(style.color).toEqual(new ConditionsExpression(jsonExp)); }); - it('sets color to undefined if not a string or conditional in setter', function() { - var style = new Cesium3DTileStyle({ - color : 'color("red")' - }); - - style.color = 5; - expect(style.color).toEqual(undefined); - }); - it('sets pointSize value to expression', function() { var style = new Cesium3DTileStyle({ pointSize : '2' @@ -324,6 +302,9 @@ defineSuite([ it('sets pointSize expressions in setter', function() { var style = new Cesium3DTileStyle(); + style.pointSize = 2; + expect(style.pointSize).toEqual(new Expression('2')); + var exp = new Expression('2'); style.pointSize = exp; expect(style.pointSize).toEqual(exp); @@ -340,32 +321,28 @@ defineSuite([ }); it('sets pointSize values in setter', function() { - var style = new Cesium3DTileStyle(); + var defines = { + 'defines': { + 'targetPointSize': '2.0' + } + }; + var style = new Cesium3DTileStyle(defines); style.pointSize = 2; expect(style.pointSize).toEqual(new Expression('2')); - style.pointSize = '${height} / 10'; - expect(style.pointSize).toEqual(new Expression('${height} / 10')); + style.pointSize = '${targetPointSize} + 1.0'; + expect(style.pointSize).toEqual(new Expression('2.0 + 1.0')); var jsonExp = { conditions : [ ['${height} > 2', '1.0'], - ['true', '2.0'] + ['true', '${targetPointSize}'] ] }; style.pointSize = jsonExp; - expect(style.pointSize).toEqual(new ConditionsExpression(jsonExp)); - }); - - it('sets pointSize to undefined if not a number, string or conditional in setter', function() { - var style = new Cesium3DTileStyle({ - pointSize : true - }); - - style.pointSize = false; - expect(style.pointSize).toEqual(undefined); + expect(style.pointSize).toEqual(new ConditionsExpression(jsonExp, defines)); }); it('throws on accessing style if not ready', function() { From 201fb993ed6d8216294e029e31d4c59a1c6dd025 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Fri, 14 Jul 2017 09:27:53 -0400 Subject: [PATCH 056/132] Fixes typo --- Specs/Renderer/GLSLModernizerSpec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Specs/Renderer/GLSLModernizerSpec.js b/Specs/Renderer/GLSLModernizerSpec.js index 09935feece1d..5909bc625c24 100644 --- a/Specs/Renderer/GLSLModernizerSpec.js +++ b/Specs/Renderer/GLSLModernizerSpec.js @@ -78,7 +78,7 @@ defineSuite([ expect(output).toContain(expected1); }); - it ('does not create layout qualifier for reserved word lookalike variables functions', function() { + it ('does not create layout qualifier for reserved word lookalike variables', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + 'uniform sampler2D example; \n' + From b8a50255f097e6b24f0691efb7a958d229a8a9c3 Mon Sep 17 00:00:00 2001 From: Heiko Thiel Date: Fri, 14 Jul 2017 15:40:49 +0200 Subject: [PATCH 057/132] Fix tests --- Specs/Scene/Cesium3DTileStyleSpec.js | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/Specs/Scene/Cesium3DTileStyleSpec.js b/Specs/Scene/Cesium3DTileStyleSpec.js index a36bbf997a41..f7c88c9aa7cd 100644 --- a/Specs/Scene/Cesium3DTileStyleSpec.js +++ b/Specs/Scene/Cesium3DTileStyleSpec.js @@ -167,14 +167,12 @@ defineSuite([ it('sets show values in setter', function() { var defines = { - 'defines': { - 'showFactor': 10 - } + 'showFactor': 10 }; - var style = new Cesium3DTileStyle(defines); + var style = new Cesium3DTileStyle({ 'defines': defines }); style.show = '${height} * ${showFactor} >= 1000'; - expect(style.show).toEqual(new Expression('${height} * 10 >= 1000')); + expect(style.show).toEqual(new Expression('${height} * ${showFactor} >= 1000', defines)); style.show = false; expect(style.show).toEqual(new Expression('false')); @@ -240,12 +238,10 @@ defineSuite([ }); it('sets color values in setter', function() { - var defines = { - 'defines': { - 'targetColor': 'red' - } + var defines = + 'targetColor': 'red' }; - var style = new Cesium3DTileStyle(defines); + var style = new Cesium3DTileStyle({ 'defines': defines }); style.color = 'color("${targetColor}")'; expect(style.color).toEqual(new Expression('color("red")')); @@ -322,11 +318,9 @@ defineSuite([ it('sets pointSize values in setter', function() { var defines = { - 'defines': { - 'targetPointSize': '2.0' - } + 'targetPointSize': '2.0' }; - var style = new Cesium3DTileStyle(defines); + var style = new Cesium3DTileStyle({ 'defines': defines }); style.pointSize = 2; expect(style.pointSize).toEqual(new Expression('2')); From 8d5734819acafad6de8c45b0e978e26dfc190a46 Mon Sep 17 00:00:00 2001 From: Heiko Thiel Date: Fri, 14 Jul 2017 18:00:12 +0200 Subject: [PATCH 058/132] Changed behavior: Cesium3DTileStyle does not set default values anymore --- Source/Scene/Cesium3DTileBatchTable.js | 13 ++++++++----- Source/Scene/Cesium3DTileStyle.js | 22 +++++++++++---------- Specs/Scene/Cesium3DTileStyleSpec.js | 27 +++++++++++++++++--------- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index 79401ae40314..95f7c4a795e7 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -68,6 +68,9 @@ define([ StencilOperation) { 'use strict'; + var DEFAULT_COLOR_VALUE = Color.WHITE; + var DEFAULT_SHOW_VALUE = true; + /** * @private */ @@ -414,7 +417,7 @@ define([ Check.typeOf.object('color', color); //>>includeEnd('debug'); - if (Color.equals(color, Color.WHITE) && !defined(this._batchValues)) { + if (Color.equals(color, DEFAULT_COLOR_VALUE) && !defined(this._batchValues)) { // Avoid allocating since the default is white return; } @@ -475,7 +478,7 @@ define([ //>>includeEnd('debug'); if (!defined(this._batchValues)) { - return Color.clone(Color.WHITE, result); + return Color.clone(DEFAULT_COLOR_VALUE, result); } var batchValues = this._batchValues; @@ -495,7 +498,7 @@ define([ Cesium3DTileBatchTable.prototype.applyStyle = function(frameState, style) { if (!defined(style)) { - this.setAllColor(Color.WHITE); + this.setAllColor(DEFAULT_COLOR_VALUE); this.setAllShow(true); return; } @@ -504,8 +507,8 @@ define([ var length = this.featuresLength; for (var i = 0; i < length; ++i) { var feature = content.getFeature(i); - var color = style.color.evaluateColor(frameState, feature, scratchColor); - var show = style.show.evaluate(frameState, feature); + var color = defined(style.color) ? style.color.evaluateColor(frameState, feature, scratchColor) : DEFAULT_COLOR_VALUE; + var show = defined(style.show) ? style.show.evaluate(frameState, feature) : DEFAULT_SHOW_VALUE; this.setColor(i, color); this.setShow(i, show); } diff --git a/Source/Scene/Cesium3DTileStyle.js b/Source/Scene/Cesium3DTileStyle.js index f7612bba6598..c0a236205c8e 100644 --- a/Source/Scene/Cesium3DTileStyle.js +++ b/Source/Scene/Cesium3DTileStyle.js @@ -22,10 +22,6 @@ define([ Expression) { 'use strict'; - var DEFAULT_JSON_COLOR_EXPRESSION = 'color("#ffffff")'; - var DEFAULT_JSON_BOOLEAN_EXPRESSION = true; - var DEFAULT_JSON_NUMBER_EXPRESSION = 1.0; - /** * A style that is applied to a {@link Cesium3DTileset}. *

@@ -95,9 +91,9 @@ define([ styleJson = defaultValue(styleJson, defaultValue.EMPTY_OBJECT); - that.color = defaultValue(styleJson.color, DEFAULT_JSON_COLOR_EXPRESSION); - that.show = defaultValue(styleJson.show, DEFAULT_JSON_BOOLEAN_EXPRESSION); - that.pointSize = defaultValue(styleJson.pointSize, DEFAULT_JSON_NUMBER_EXPRESSION); + that.color = styleJson.color; + that.show = styleJson.show; + that.pointSize = styleJson.pointSize; that._colorShaderFunctionReady = !defined(styleJson.color); that._showShaderFunctionReady = !defined(styleJson.show); @@ -237,7 +233,9 @@ define([ }, set : function(value) { var defines = defaultValue(this._style, defaultValue.EMPTY_OBJECT).defines; - if (typeof value === 'boolean') { + if (!defined(value)) { + this._show = undefined; + } else if (typeof value === 'boolean') { this._show = new Expression(String(value)); } else if (typeof value === 'string') { this._show = new Expression(value, defines); @@ -304,7 +302,9 @@ define([ }, set : function(value) { var defines = defaultValue(this._style, defaultValue.EMPTY_OBJECT).defines; - if (typeof value === 'string') { + if (!defined(value)) { + this._color = undefined; + } else if (typeof value === 'string') { this._color = new Expression(value, defines); } else if (defined(value.conditions)) { this._color = new ConditionsExpression(value, defines); @@ -374,7 +374,9 @@ define([ }, set : function(value) { var defines = defaultValue(this._style, defaultValue.EMPTY_OBJECT).defines; - if (typeof value === 'number') { + if (!defined(value)) { + this._pointSize = undefined; + } else if (typeof value === 'number') { this._pointSize = new Expression(String(value)); } else if (typeof value === 'string') { this._pointSize = new Expression(value, defines); diff --git a/Specs/Scene/Cesium3DTileStyleSpec.js b/Specs/Scene/Cesium3DTileStyleSpec.js index f7c88c9aa7cd..d344898abcb9 100644 --- a/Specs/Scene/Cesium3DTileStyleSpec.js +++ b/Specs/Scene/Cesium3DTileStyleSpec.js @@ -82,28 +82,28 @@ defineSuite([ }); }); - it('sets show value to default expression', function() { + it('sets show value to undefined if value not present', function() { var style = new Cesium3DTileStyle({}); - expect(style.show).toEqual(new Expression('true')); + expect(style.show).toBeUndefined(); style = new Cesium3DTileStyle(); - expect(style.show).toEqual(new Expression('true')); + expect(style.show).toBeUndefined(); }); - it('sets color value to default expression', function() { + it('sets color value to undefined if value not present', function() { var style = new Cesium3DTileStyle({}); - expect(style.color).toEqual(new Expression('color("#ffffff")')); + expect(style.color).toBeUndefined(); style = new Cesium3DTileStyle(); - expect(style.color).toEqual(new Expression('color("#ffffff")')); + expect(style.color).toBeUndefined(); }); - it('sets pointSize value to default expression', function() { + it('sets pointSize value to undefined if value not present', function() { var style = new Cesium3DTileStyle({}); - expect(style.pointSize).toEqual(new Expression('1')); + expect(style.pointSize).toBeUndefined(); style = new Cesium3DTileStyle(); - expect(style.pointSize).toEqual(new Expression('1')); + expect(style.pointSize).toBeUndefined(); }); it('sets show value to expression', function() { @@ -186,6 +186,9 @@ defineSuite([ style.show = jsonExp; expect(style.show).toEqual(new ConditionsExpression(jsonExp, defines)); + + style.show = undefined; + expect(style.show).toBeUndefined(); }); it('sets color value to expression', function() { @@ -235,6 +238,9 @@ defineSuite([ style.color = condExp; expect(style.color).toEqual(condExp); + + style.color = undefined; + expect(style.color).toBeUndefined(); }); it('sets color values in setter', function() { @@ -314,6 +320,9 @@ defineSuite([ style.pointSize = condExp; expect(style.pointSize).toEqual(condExp); + + style.pointSize = undefined; + expect(style.pointSize).toBeUndefined(); }); it('sets pointSize values in setter', function() { From c2eea43ecde9808cc42431917dcae35214d51daa Mon Sep 17 00:00:00 2001 From: Heiko Thiel Date: Fri, 14 Jul 2017 18:02:56 +0200 Subject: [PATCH 059/132] Fix whitespaces --- Source/Scene/Cesium3DTileStyle.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Scene/Cesium3DTileStyle.js b/Source/Scene/Cesium3DTileStyle.js index c0a236205c8e..1ba4921e6df5 100644 --- a/Source/Scene/Cesium3DTileStyle.js +++ b/Source/Scene/Cesium3DTileStyle.js @@ -235,7 +235,7 @@ define([ var defines = defaultValue(this._style, defaultValue.EMPTY_OBJECT).defines; if (!defined(value)) { this._show = undefined; - } else if (typeof value === 'boolean') { + } else if (typeof value === 'boolean') { this._show = new Expression(String(value)); } else if (typeof value === 'string') { this._show = new Expression(value, defines); @@ -279,7 +279,7 @@ define([ * var style = new Cesium.Cesium3DTileStyle(); * // Override color expression with a string * style.color = 'color("blue")'; - * + * * @example * var style = new Cesium.Cesium3DTileStyle(); * // Override color expression with a condition @@ -302,9 +302,9 @@ define([ }, set : function(value) { var defines = defaultValue(this._style, defaultValue.EMPTY_OBJECT).defines; - if (!defined(value)) { + if (!defined(value)) { this._color = undefined; - } else if (typeof value === 'string') { + } else if (typeof value === 'string') { this._color = new Expression(value, defines); } else if (defined(value.conditions)) { this._color = new ConditionsExpression(value, defines); @@ -376,7 +376,7 @@ define([ var defines = defaultValue(this._style, defaultValue.EMPTY_OBJECT).defines; if (!defined(value)) { this._pointSize = undefined; - } else if (typeof value === 'number') { + } else if (typeof value === 'number') { this._pointSize = new Expression(String(value)); } else if (typeof value === 'string') { this._pointSize = new Expression(value, defines); From 9bc3764d046f8a2bbf84c5ffa9523f029f10bf72 Mon Sep 17 00:00:00 2001 From: Heiko Thiel Date: Sat, 15 Jul 2017 02:22:13 +0200 Subject: [PATCH 060/132] Fix syntax error --- Specs/Scene/Cesium3DTileStyleSpec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Specs/Scene/Cesium3DTileStyleSpec.js b/Specs/Scene/Cesium3DTileStyleSpec.js index d344898abcb9..e2466fa91211 100644 --- a/Specs/Scene/Cesium3DTileStyleSpec.js +++ b/Specs/Scene/Cesium3DTileStyleSpec.js @@ -244,7 +244,7 @@ defineSuite([ }); it('sets color values in setter', function() { - var defines = + var defines = { 'targetColor': 'red' }; var style = new Cesium3DTileStyle({ 'defines': defines }); From a40077c7aa44f6d68906fa0ee93189eedcf5204e Mon Sep 17 00:00:00 2001 From: Heiko Thiel Date: Mon, 17 Jul 2017 11:44:05 +0200 Subject: [PATCH 061/132] Fix remaining Cesium3DTileStyleSpec tests --- Specs/Scene/Cesium3DTileStyleSpec.js | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/Specs/Scene/Cesium3DTileStyleSpec.js b/Specs/Scene/Cesium3DTileStyleSpec.js index e2466fa91211..28ca9638c4fc 100644 --- a/Specs/Scene/Cesium3DTileStyleSpec.js +++ b/Specs/Scene/Cesium3DTileStyleSpec.js @@ -1,5 +1,5 @@ defineSuite([ - 'Scene/Cesium3DTileStyle', + 'Scene/Cesium3DTileStyle', 'Core/Color', 'Scene/ConditionsExpression', 'Scene/Expression' @@ -250,7 +250,7 @@ defineSuite([ var style = new Cesium3DTileStyle({ 'defines': defines }); style.color = 'color("${targetColor}")'; - expect(style.color).toEqual(new Expression('color("red")')); + expect(style.color).toEqual(new Expression('color("${targetColor}")', defines)); var jsonExp = { conditions : [ @@ -260,7 +260,7 @@ defineSuite([ }; style.color = jsonExp; - expect(style.color).toEqual(new ConditionsExpression(jsonExp)); + expect(style.color).toEqual(new ConditionsExpression(jsonExp, defines)); }); it('sets pointSize value to expression', function() { @@ -294,13 +294,6 @@ defineSuite([ expect(style.pointSize).toEqual(new ConditionsExpression(jsonExp)); }); - it('sets pointSize to undefined if not a number, string, or conditional', function() { - var style = new Cesium3DTileStyle({ - pointSize : true - }); - expect(style.pointSize).toEqual(undefined); - }); - it('sets pointSize expressions in setter', function() { var style = new Cesium3DTileStyle(); @@ -335,7 +328,7 @@ defineSuite([ expect(style.pointSize).toEqual(new Expression('2')); style.pointSize = '${targetPointSize} + 1.0'; - expect(style.pointSize).toEqual(new Expression('2.0 + 1.0')); + expect(style.pointSize).toEqual(new Expression('${targetPointSize} + 1.0', defines)); var jsonExp = { conditions : [ @@ -452,7 +445,6 @@ defineSuite([ expect(style.show.evaluate(frameState, feature1)).toEqual(true); expect(style.show.evaluate(frameState, feature2)).toEqual(false); - expect(style.color.evaluateColor(frameState, undefined)).toEqual(Color.WHITE); }); it('applies show style with regexp and variables', function() { @@ -462,7 +454,6 @@ defineSuite([ expect(style.show.evaluate(frameState, feature1)).toEqual(true); expect(style.show.evaluate(frameState, feature2)).toEqual(false); - expect(style.color.evaluateColor(frameState, undefined)).toEqual(Color.WHITE); }); it('applies show style with conditional', function() { @@ -486,7 +477,6 @@ defineSuite([ var style = new Cesium3DTileStyle({ "color" : "(${Temperature} > 90) ? color('red') : color('white')" }); - expect(style.show.evaluate(frameState, feature1)).toEqual(true); expect(style.color.evaluateColor(frameState, feature1)).toEqual(Color.WHITE); expect(style.color.evaluateColor(frameState, feature2)).toEqual(Color.RED); }); @@ -495,7 +485,6 @@ defineSuite([ var style = new Cesium3DTileStyle({ "color" : "rgba(${red}, ${green}, ${blue}, (${volume} > 100 ? 0.5 : 1.0))" }); - expect(style.show.evaluate(frameState, feature1)).toEqual(true); expect(style.color.evaluateColor(frameState, feature1)).toEqual(new Color(38/255, 255/255, 82/255, 0.5)); expect(style.color.evaluateColor(frameState, feature2)).toEqual(new Color(255/255, 30/255, 30/255, 1.0)); }); @@ -513,7 +502,6 @@ defineSuite([ ] } }); - expect(style.show.evaluate(frameState, feature1)).toEqual(true); expect(style.color.evaluateColor(frameState, feature1)).toEqual(Color.RED); expect(style.color.evaluateColor(frameState, feature2)).toEqual(Color.LIME); }); @@ -531,7 +519,6 @@ defineSuite([ ] } }); - expect(style.show.evaluate(frameState, feature1)).toEqual(true); expect(style.color.evaluateColor(frameState, feature1)).toEqual(Color.BLUE); expect(style.color.evaluateColor(frameState, feature2)).toEqual(Color.YELLOW); }); From c150bbf864f665337e9125255770faef61e81f18 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 17 Jul 2017 09:42:06 -0400 Subject: [PATCH 062/132] Fix eslint errors --- Specs/Scene/Cesium3DTileStyleSpec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Specs/Scene/Cesium3DTileStyleSpec.js b/Specs/Scene/Cesium3DTileStyleSpec.js index 28ca9638c4fc..c52940b75df4 100644 --- a/Specs/Scene/Cesium3DTileStyleSpec.js +++ b/Specs/Scene/Cesium3DTileStyleSpec.js @@ -190,7 +190,7 @@ defineSuite([ style.show = undefined; expect(style.show).toBeUndefined(); }); - + it('sets color value to expression', function() { var style = new Cesium3DTileStyle({ color : 'color("red")' @@ -262,7 +262,7 @@ defineSuite([ style.color = jsonExp; expect(style.color).toEqual(new ConditionsExpression(jsonExp, defines)); }); - + it('sets pointSize value to expression', function() { var style = new Cesium3DTileStyle({ pointSize : '2' From 585cb0fb8856d31699f4ed3ac44a61763265d9a2 Mon Sep 17 00:00:00 2001 From: Heiko Thiel Date: Mon, 17 Jul 2017 15:50:31 +0200 Subject: [PATCH 063/132] Remove obsolete code --- Source/Scene/Cesium3DTileStyle.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Source/Scene/Cesium3DTileStyle.js b/Source/Scene/Cesium3DTileStyle.js index 1ba4921e6df5..80ac74cb2e41 100644 --- a/Source/Scene/Cesium3DTileStyle.js +++ b/Source/Scene/Cesium3DTileStyle.js @@ -95,10 +95,6 @@ define([ that.show = styleJson.show; that.pointSize = styleJson.pointSize; - that._colorShaderFunctionReady = !defined(styleJson.color); - that._showShaderFunctionReady = !defined(styleJson.show); - that._pointSizeShaderFunctionReady = !defined(styleJson.pointSize); - var meta = {}; if (defined(styleJson.meta)) { var defines = styleJson.defines; From bfb7c516a08bdba5bdb9bac3b06a496b11ba3fd4 Mon Sep 17 00:00:00 2001 From: Heiko Thiel Date: Mon, 17 Jul 2017 16:12:10 +0200 Subject: [PATCH 064/132] Fix after last commit --- Source/Scene/Cesium3DTileStyle.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Scene/Cesium3DTileStyle.js b/Source/Scene/Cesium3DTileStyle.js index 80ac74cb2e41..40e13e0d7739 100644 --- a/Source/Scene/Cesium3DTileStyle.js +++ b/Source/Scene/Cesium3DTileStyle.js @@ -437,7 +437,7 @@ define([ } this._colorShaderFunctionReady = true; - this._colorShaderFunction = this.color.getShaderFunction(functionName, attributePrefix, shaderState, 'vec4'); + this._colorShaderFunction = defined(this.color) ? this.color.getShaderFunction(functionName, attributePrefix, shaderState, 'vec4') : undefined; return this._colorShaderFunction; }; @@ -459,7 +459,7 @@ define([ } this._showShaderFunctionReady = true; - this._showShaderFunction = this.show.getShaderFunction(functionName, attributePrefix, shaderState, 'bool'); + this._showShaderFunction = defined(this.show) ? this.show.getShaderFunction(functionName, attributePrefix, shaderState, 'bool') : undefined; return this._showShaderFunction; }; @@ -481,7 +481,7 @@ define([ } this._pointSizeShaderFunctionReady = true; - this._pointSizeShaderFunction = this.pointSize.getShaderFunction(functionName, attributePrefix, shaderState, 'float'); + this._pointSizeShaderFunction = defined(this.pointSize) ? this.pointSize.getShaderFunction(functionName, attributePrefix, shaderState, 'float') ? undefined; return this._pointSizeShaderFunction; }; From e47c0c691346b09e8786990be9e0d0fb241122fe Mon Sep 17 00:00:00 2001 From: Heiko Thiel Date: Mon, 17 Jul 2017 16:28:05 +0200 Subject: [PATCH 065/132] Fix syntax mistaken --- Source/Scene/Cesium3DTileStyle.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/Cesium3DTileStyle.js b/Source/Scene/Cesium3DTileStyle.js index 40e13e0d7739..a60fc7ba8b4b 100644 --- a/Source/Scene/Cesium3DTileStyle.js +++ b/Source/Scene/Cesium3DTileStyle.js @@ -481,7 +481,7 @@ define([ } this._pointSizeShaderFunctionReady = true; - this._pointSizeShaderFunction = defined(this.pointSize) ? this.pointSize.getShaderFunction(functionName, attributePrefix, shaderState, 'float') ? undefined; + this._pointSizeShaderFunction = defined(this.pointSize) ? this.pointSize.getShaderFunction(functionName, attributePrefix, shaderState, 'float') : undefined; return this._pointSizeShaderFunction; }; From 3cdf90ca0f892ec092711dc64726f0c654b9fa2a Mon Sep 17 00:00:00 2001 From: Heiko Thiel Date: Mon, 17 Jul 2017 16:41:22 +0200 Subject: [PATCH 066/132] Replace tab by whitespaces --- Specs/Scene/Cesium3DTileStyleSpec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Specs/Scene/Cesium3DTileStyleSpec.js b/Specs/Scene/Cesium3DTileStyleSpec.js index c52940b75df4..43fab6e103b1 100644 --- a/Specs/Scene/Cesium3DTileStyleSpec.js +++ b/Specs/Scene/Cesium3DTileStyleSpec.js @@ -1,5 +1,5 @@ defineSuite([ - 'Scene/Cesium3DTileStyle', + 'Scene/Cesium3DTileStyle', 'Core/Color', 'Scene/ConditionsExpression', 'Scene/Expression' From 0c6ac5b472084f706ed965ebde28b976ce5c0921 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Mon, 17 Jul 2017 10:50:27 -0400 Subject: [PATCH 067/132] No longer appending the output declaration define if the context is WebGL 1 --- Source/Renderer/ShaderSource.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/Renderer/ShaderSource.js b/Source/Renderer/ShaderSource.js index 642cdc15e0d3..409dc8097d2e 100644 --- a/Source/Renderer/ShaderSource.js +++ b/Source/Renderer/ShaderSource.js @@ -244,7 +244,9 @@ define([ // GLSLModernizer inserts its own layout qualifiers // at this position in the source - result += '#define OUTPUT_DECLARATION\n\n'; + if (context.webgl2) { + result += '#define OUTPUT_DECLARATION\n\n'; + } // append built-ins if (shaderSource.includeBuiltIns) { From 10d5c7ab605c9b880e6b071c49149d62b037495c Mon Sep 17 00:00:00 2001 From: Heiko Thiel Date: Mon, 17 Jul 2017 17:32:26 +0200 Subject: [PATCH 068/132] Fix Cesium3DTilesInspector --- .../Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js b/Source/Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js index 087e97918e5f..e9a5d9dfad75 100644 --- a/Source/Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js +++ b/Source/Widgets/Cesium3DTilesInspector/Cesium3DTilesInspectorViewModel.js @@ -974,7 +974,7 @@ define([ // Restore original color to feature that is no longer selected var frameState = this._scene.frameState; if (!this.colorize && defined(this._style)) { - currentFeature.color = this._style.color.evaluateColor(frameState, currentFeature, scratchColor); + currentFeature.color = defined(this._style.color) ? this._style.color.evaluateColor(frameState, currentFeature, scratchColor) : Color.WHITE; } else { currentFeature.color = oldColor; } From 45a8f9944cb3a188813f48ffd0fc22f65aedeefa Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Mon, 17 Jul 2017 12:12:53 -0400 Subject: [PATCH 069/132] Fixes eslint issues --- Source/Renderer/GLSLModernizer.js | 125 ++++++++++----------------- Source/Renderer/ShaderCache.js | 2 +- Specs/Renderer/GLSLModernizerSpec.js | 21 +++-- Specs/Renderer/ShaderSourceSpec.js | 2 +- 4 files changed, 60 insertions(+), 90 deletions(-) diff --git a/Source/Renderer/GLSLModernizer.js b/Source/Renderer/GLSLModernizer.js index 4050067df2b5..99509187174d 100644 --- a/Source/Renderer/GLSLModernizer.js +++ b/Source/Renderer/GLSLModernizer.js @@ -25,7 +25,7 @@ define([ if (source.search(/#version 300 es/g) !== -1) { return source; } - + var outputDeclarationLine = -1; var number; for (number = 0; number < splitSource.length; ++number) { @@ -34,7 +34,7 @@ define([ outputDeclarationLine = number; break; } - }; + } if (outputDeclarationLine === -1) { throw new DeveloperError('Could not find a #define OUTPUT_DECLARATION nor a main function!'); @@ -45,22 +45,22 @@ define([ function replaceInSource(str, replacement, strIsRegex) { var regex = str; if ((strIsRegex === undefined) || strIsRegex === false) { - var regexStr = "(^|[^\\w])(" + str + ")($|[^\\w])"; + var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; regex = new RegExp(regexStr, 'g'); } - + for (var number = 0; number < splitSource.length; ++number) { var line = splitSource[number]; if (strIsRegex) { splitSource[number] = line.replace(regex, replacement); } else { - splitSource[number] = line.replace(regex, "$1" + replacement + "$3"); + splitSource[number] = line.replace(regex, '$1' + replacement + '$3'); } } } - + function findInSource(str) { - var regexStr = "(^|[^\\w])(" + str + ")($|[^\\w])"; + var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; var regex = new RegExp(regexStr, 'g'); for (var number = 0; number < splitSource.length; ++number) { var line = splitSource[number]; @@ -72,92 +72,63 @@ define([ } function compileSource() { - var wholeSource = ""; + var wholeSource = ''; for (var number = 0; number < splitSource.length; ++number) { - wholeSource += splitSource[number] + "\n"; + wholeSource += splitSource[number] + '\n'; } return wholeSource; } - + function setAdd(variable, set1) { if (set1.indexOf(variable) === -1) - set1.push(variable); - } - - function setUnion(set1, set2) { - for (var a = 0; a < set2.length; ++a) { - setAdd(set2[a], set1); - } + {set1.push(variable);} } function getVariablePreprocessorBranch(variablesThatWeCareAbout) { var variableMap = {}; var negativeMap = {}; - + for (var a = 0; a < variablesThatWeCareAbout.length; ++a) { var variableThatWeCareAbout = variablesThatWeCareAbout[a]; variableMap[variableThatWeCareAbout] = [null]; } - + var stack = []; for (var i = 0; i < splitSource.length; ++i) { var line = splitSource[i]; var hasIF = /(#ifdef|#if)/g.test(line); var hasELSE = /#else/g.test(line); var hasENDIF = /#endif/g.test(line); - + if (hasIF) { stack.push(line); } else if (hasELSE) { var top = stack[stack.length - 1]; - var op = top.replace("ifdef", "ifndef"); + var op = top.replace('ifdef', 'ifndef'); if (/if/g.test(op)) { - op = op.replace(/(#if\s+)(\S*)([^]*)/, "$1!($2)$3"); + op = op.replace(/(#if\s+)(\S*)([^]*)/, '$1!($2)$3'); } stack.pop(); stack.push(op); - + negativeMap[top] = op; negativeMap[op] = top; } else if (hasENDIF) { stack.pop(); } else if (!/layout/g.test(line)) { - for (a = 0; a < variablesThatWeCareAbout.length; ++a) { - var care = variablesThatWeCareAbout[a]; - if (line.indexOf(care) !== -1) { - if (variableMap[care].length === 1 && variableMap[care][0] === null) { - variableMap[care] = stack.slice(); + for (var varIndex = 0; varIndex < variablesThatWeCareAbout.length; ++varIndex) { + var varName = variablesThatWeCareAbout[varIndex]; + if (line.indexOf(varName) !== -1) { + if (variableMap[varName].length === 1 && variableMap[varName][0] === null) { + variableMap[varName] = stack.slice(); } else { - variableMap[care] = variableMap[care].filter(function(x) { return stack.indexOf(x) >= 0; }); + variableMap[varName] = variableMap[varName].filter(function(x) { return stack.indexOf(x) >= 0; }); } } } } } - - // This code is probably no longer needed... it was used to handle - // removing negative conditions - for (var care in variableMap) { - if (variableMap.hasOwnProperty(care)) { - var entry = variableMap[care]; - var toDelete = []; - for (var b = 0; b < entry.length; ++b) { - var item = entry[b]; - if (entry.indexOf(negativeMap[item]) !== -1) { - toDelete.push(item); - toDelete.push(negativeMap[item]); - } - } - - for (var c = 0; c < toDelete.length; ++c) { - var ind = entry.indexOf(toDelete[c]); - if (ind !== -1) { - entry.splice(ind, 1); - } - } - } - } - + for (var care in variableMap) { if (variableMap.hasOwnProperty(care)) { if (variableMap.length === 1 && variableMap[0] === null) { @@ -165,51 +136,51 @@ define([ } } } - + return variableMap; } function removeExtension(name) { - var regex = "#extension\\s+GL_" + name + "\\s+:\\s+[a-zA-Z0-9]+\\s*$"; - replaceInSource(new RegExp(regex, "g"), "", true); + var regex = '#extension\\s+GL_' + name + '\\s+:\\s+[a-zA-Z0-9]+\\s*$'; + replaceInSource(new RegExp(regex, 'g'), '', true); } var variableSet = []; for (var i = 0; i < 10; i++) { - var fragDataString = "gl_FragData\\[" + i + "\\]"; + var fragDataString = 'gl_FragData\\[' + i + '\\]'; var newOutput = 'czm_out' + i; - var regex = new RegExp(fragDataString, "g"); + var regex = new RegExp(fragDataString, 'g'); if (regex.test(source)) { setAdd(newOutput, variableSet); replaceInSource(fragDataString, newOutput); - splitSource.splice(outputDeclarationLine, 0, "layout(location = " + i + ") out vec4 " + newOutput + ";"); + splitSource.splice(outputDeclarationLine, 0, 'layout(location = ' + i + ') out vec4 ' + newOutput + ';'); outputDeclarationLine += 1; } } - var czmFragColor = "czm_fragColor"; - if (findInSource("gl_FragColor")) { + var czmFragColor = 'czm_fragColor'; + if (findInSource('gl_FragColor')) { setAdd(czmFragColor, variableSet); - replaceInSource("gl_FragColor", czmFragColor); - splitSource.splice(outputDeclarationLine, 0, "layout(location = 0) out vec4 czm_fragColor;"); + replaceInSource('gl_FragColor', czmFragColor); + splitSource.splice(outputDeclarationLine, 0, 'layout(location = 0) out vec4 czm_fragColor;'); outputDeclarationLine += 1; } - + var variableMap = getVariablePreprocessorBranch(variableSet); var lineAdds = {}; for (var c = 0; c < splitSource.length; c++) { var l = splitSource[c]; for (var care in variableMap) { if (variableMap.hasOwnProperty(care)) { - var matchVar = new RegExp("(layout)[^]+(out)[^]+(" + care + ")[^]+", "g"); + var matchVar = new RegExp('(layout)[^]+(out)[^]+(' + care + ')[^]+', 'g'); if (matchVar.exec(l) !== null) { lineAdds[l] = care; } } } } - + for (var layoutDeclaration in lineAdds) { if (lineAdds.hasOwnProperty(layoutDeclaration)) { var variableName = lineAdds[layoutDeclaration]; @@ -222,12 +193,12 @@ define([ } lineNumber += depth + 1; for (d = depth - 1; d >= 0; d--) { - splitSource.splice(lineNumber, 0, "#endif //" + entry[d]); + splitSource.splice(lineNumber, 0, '#endif //' + entry[d]); } } } - var versionThree = "#version 300 es"; + var versionThree = '#version 300 es'; var foundVersion = false; for (number = 0; number < splitSource.length; number++) { if (/#version/.test(splitSource[number])) { @@ -240,19 +211,19 @@ define([ splitSource.splice(0, 0, versionThree); } - removeExtension("EXT_draw_buffers"); - removeExtension("EXT_frag_depth"); + removeExtension('EXT_draw_buffers'); + removeExtension('EXT_frag_depth'); - replaceInSource("texture2D", "texture"); - replaceInSource("texture3D", "texture"); - replaceInSource("textureCube", "texture"); - replaceInSource("gl_FragDepthEXT", "gl_FragDepth"); + replaceInSource('texture2D', 'texture'); + replaceInSource('texture3D', 'texture'); + replaceInSource('textureCube', 'texture'); + replaceInSource('gl_FragDepthEXT', 'gl_FragDepth'); if (isFragmentShader) { - replaceInSource("varying", "in"); + replaceInSource('varying', 'in'); } else { - replaceInSource("attribute", "in"); - replaceInSource("varying", "out"); + replaceInSource('attribute', 'in'); + replaceInSource('varying', 'out'); } return compileSource(); diff --git a/Source/Renderer/ShaderCache.js b/Source/Renderer/ShaderCache.js index 70092c6954f0..a2a9e86d7358 100644 --- a/Source/Renderer/ShaderCache.js +++ b/Source/Renderer/ShaderCache.js @@ -170,7 +170,7 @@ define([ } var context = this._context; - + var vertexShaderText = vertexShaderSource.createCombinedVertexShader(context); var fragmentShaderText = fragmentShaderSource.createCombinedFragmentShader(context); diff --git a/Specs/Renderer/GLSLModernizerSpec.js b/Specs/Renderer/GLSLModernizerSpec.js index 5909bc625c24..6d3507e257fd 100644 --- a/Specs/Renderer/GLSLModernizerSpec.js +++ b/Specs/Renderer/GLSLModernizerSpec.js @@ -129,11 +129,11 @@ defineSuite([ ' gl_FragData[0] = texture2D(example, v_textureCoordinates); \n' + ' gl_FragData[1] = textureCube(exampleCube, v_textureCoordinates); \n' + ' gl_FragData[2] = texture3D(example3D, v_textureCoordinates); \n' + - ' gl_FragDepthEXT = 0.0; \n' + + ' gl_FragDepthEXT = 0.0; \n' + '} \n'; - + var output = glslModernizeShaderText(old_fragment, true); - + var expectedDepth = 'gl_FragDepth = 0.0;'; var expectedTexture2D = 'texture(example, v_textureCoordinates);'; var expectedTextureCube = 'texture(exampleCube, v_textureCoordinates);'; @@ -145,7 +145,7 @@ defineSuite([ var notExpectedTextureCube = 'textureCube(exampleCube, v_textureCoordinates);'; var notExpectedTexture3D = 'texture3D(example3D, v_textureCoordinates);'; var notExpectedVarying = 'varying vec2 v_textureCoordinates;'; - + expect(output).toContain(expectedDepth); expect(output).toContain(expectedTexture2D); expect(output).toContain(expectedTextureCube); @@ -163,21 +163,21 @@ defineSuite([ var old_vertex = '#define OUTPUT_DECLARATION \n' + 'attribute vec4 position; \n' + - 'varying vec4 varyingVariable; \n'; + 'varying vec4 varyingVariable; \n' + 'void main() \n' + '{ \n' + ' gl_Position = position; \n' + ' varyingVariable = position.wzyx; \n' + '} \n'; - + var output = glslModernizeShaderText(old_vertex, false); - + var expectedOut = 'out vec4 varyingVariable;'; var expectedIn = 'in vec4 position;'; var notExpectedAttribute = 'attribute vec4 varyingVariable;'; var notExpectedVarying = 'varying vec2 varyingVariable;'; - + expect(output).toContain(expectedOut); expect(output).toContain(expectedIn); @@ -273,9 +273,8 @@ defineSuite([ '} \n'; var output = glslModernizeShaderText(noQualifiers, true); var expected0 = '#ifdef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_out0;\n#endif'; - var expected1 = ['#ifdef EXAMPLE_BRANCH \n#ifdef EXAMPLE_BRANCH1 \nlayout(location = 0) out vec4 czm_out0;\n#endif', - '#ifdef EXAMPLE_BRANCH1 \n#ifdef EXAMPLE_BRANCH0 \nlayout(location = 0) out vec4 czm_out0;\n#endif']; - var containsExpected0 = ((output.indexOf(expected0[0]) !== -1) && (output.indexOf(expected0[1]) !== -1)); + var expected1 = /#ifdef (EXAMPLE_BRANCH|EXAMPLE_BRANCH1)\s*\n\s*#ifdef (EXAMPLE_BRANCH1|EXAMPLE_BRANCH)\s*\n\s*layout\(location = 1\) out vec4 czm_out1;/g; + var containsExpected0 = expected1.test(output); expect(output).toContain(expected0); expect(containsExpected0).toBe(true); }); diff --git a/Specs/Renderer/ShaderSourceSpec.js b/Specs/Renderer/ShaderSourceSpec.js index 461819a070f1..80b4f4fbe9c4 100644 --- a/Specs/Renderer/ShaderSourceSpec.js +++ b/Specs/Renderer/ShaderSourceSpec.js @@ -7,7 +7,7 @@ defineSuite([ var mockContext = { webgl2 : false }; - + it('combines #defines', function() { var source = new ShaderSource({ defines : ['A', 'B', ''] From 020bba76a07dfb408a49145c06ce6c69868eb24c Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Mon, 17 Jul 2017 13:37:01 -0400 Subject: [PATCH 070/132] Fixes problem where we were passing context.webgl2 instead of context into ShaderSource.createCombinedFragmentShader --- Specs/Renderer/ShaderProgramSpec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Specs/Renderer/ShaderProgramSpec.js b/Specs/Renderer/ShaderProgramSpec.js index dc5a9b5e190d..0fe33e0acc0b 100644 --- a/Specs/Renderer/ShaderProgramSpec.js +++ b/Specs/Renderer/ShaderProgramSpec.js @@ -71,7 +71,7 @@ defineSuite([ var expectedFSText = new ShaderSource({ sources : [fs] - }).createCombinedFragmentShader(context.webgl2); + }).createCombinedFragmentShader(context); expect(sp._fragmentShaderText).toEqual(expectedFSText); }); From fd633e93a754ebcbd9e8eef037e8e3e67035a60d Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Mon, 17 Jul 2017 13:43:07 -0400 Subject: [PATCH 071/132] Renames GLSLModernizer to ModernizeShader --- .../{GLSLModernizer.js => ModernizeShader.js} | 4 +- Source/Renderer/ShaderSource.js | 6 +-- ...dernizerSpec.js => ModernizeShaderSpec.js} | 38 +++++++++---------- 3 files changed, 24 insertions(+), 24 deletions(-) rename Source/Renderer/{GLSLModernizer.js => ModernizeShader.js} (98%) rename Specs/Renderer/{GLSLModernizerSpec.js => ModernizeShaderSpec.js} (91%) diff --git a/Source/Renderer/GLSLModernizer.js b/Source/Renderer/ModernizeShader.js similarity index 98% rename from Source/Renderer/GLSLModernizer.js rename to Source/Renderer/ModernizeShader.js index 99509187174d..1d019c92b18a 100644 --- a/Source/Renderer/GLSLModernizer.js +++ b/Source/Renderer/ModernizeShader.js @@ -18,7 +18,7 @@ define([ * * @private */ - function glslModernizeShaderText(source, isFragmentShader) { + function modernizeShader(source, isFragmentShader) { var outputDeclarationRegex = /#define OUTPUT_DECLARATION/; var splitSource = source.split('\n'); @@ -229,5 +229,5 @@ define([ return compileSource(); } - return glslModernizeShaderText; + return modernizeShader; }); diff --git a/Source/Renderer/ShaderSource.js b/Source/Renderer/ShaderSource.js index 409dc8097d2e..da96cbdf4526 100644 --- a/Source/Renderer/ShaderSource.js +++ b/Source/Renderer/ShaderSource.js @@ -2,14 +2,14 @@ define([ '../Core/defaultValue', '../Core/defined', '../Core/DeveloperError', - '../Renderer/GLSLModernizer', + '../Renderer/ModernizeShader', '../Shaders/Builtin/CzmBuiltins', './AutomaticUniforms' ], function( defaultValue, defined, DeveloperError, - glslModernizeShaderText, + modernizeShader, CzmBuiltins, AutomaticUniforms) { 'use strict'; @@ -261,7 +261,7 @@ define([ // modernize the source if (context.webgl2) { - result = glslModernizeShaderText(result, isFragmentShader, true); + result = modernizeShader(result, isFragmentShader, true); } return result; diff --git a/Specs/Renderer/GLSLModernizerSpec.js b/Specs/Renderer/ModernizeShaderSpec.js similarity index 91% rename from Specs/Renderer/GLSLModernizerSpec.js rename to Specs/Renderer/ModernizeShaderSpec.js index 6d3507e257fd..89091f73c16a 100644 --- a/Specs/Renderer/GLSLModernizerSpec.js +++ b/Specs/Renderer/ModernizeShaderSpec.js @@ -1,7 +1,7 @@ defineSuite([ - 'Renderer/GLSLModernizer' + 'Renderer/ModernizeShader' ], function( - glslModernizeShaderText) { + modernizeShader) { 'use strict'; it ('adds version string', function() { @@ -10,7 +10,7 @@ defineSuite([ 'void main() \n' + '{ \n' + '} \n'; - var output = glslModernizeShaderText(simple, true); + var output = modernizeShader(simple, true); var expected = '#version 300 es'; expect(output.split('\n')[0]).toEqual(expected); }); @@ -22,7 +22,7 @@ defineSuite([ 'void main() \n' + '{ \n' + '} \n'; - var output = glslModernizeShaderText(extensions, true); + var output = modernizeShader(extensions, true); var notExpected = '#extension GL_EXT_draw_buffers : enable \n'; expect(output).not.toContain(notExpected); }); @@ -33,7 +33,7 @@ defineSuite([ '{ \n' + '} \n'; var runFunc = function() { - glslModernizeShaderText(noOutputDeclaration, true); + modernizeShader(noOutputDeclaration, true); }; expect(runFunc).toThrow(); }); @@ -45,7 +45,7 @@ defineSuite([ '{ \n' + ' gl_FragColor = vec4(0.0); \n' + '} \n'; - var output = glslModernizeShaderText(noQualifiers, true); + var output = modernizeShader(noQualifiers, true); var expected = 'layout(location = 0) out vec4 czm_fragColor;'; expect(output).toContain(expected); }); @@ -57,7 +57,7 @@ defineSuite([ '{ \n' + ' gl_FragData[0] = vec4(0.0); \n' + '} \n'; - var output = glslModernizeShaderText(noQualifiers, true); + var output = modernizeShader(noQualifiers, true); var expected = 'layout(location = 0) out vec4 czm_out0;'; expect(output).toContain(expected); }); @@ -71,7 +71,7 @@ defineSuite([ ' gl_FragData[0] = vec4(0.0); \n' + ' gl_FragData[1] = vec4(1.0); \n' + '} \n'; - var output = glslModernizeShaderText(noQualifiers, true); + var output = modernizeShader(noQualifiers, true); var expected0 = 'layout(location = 0) out vec4 czm_out0;'; var expected1 = 'layout(location = 1) out vec4 czm_out1;'; expect(output).toContain(expected0); @@ -89,7 +89,7 @@ defineSuite([ ' vec2 thisIsNotAGoodNameForAtexture2D = vec2(0.0); \n' + ' vec4 gl_FragColor = texture2D(example, thisIsNotAGoodNameForAtexture2D); \n' + '} \n'; - var output = glslModernizeShaderText(noQualifiers, true); + var output = modernizeShader(noQualifiers, true); var expectedBadName = 'vec2 thisIsNotAGoodNameForAtexture2D'; var expectedVariable = 'vec4 a_gl_FragData = vec4(0.0);'; var expectedTextureCall = 'texture(example, thisIsNotAGoodNameForAtexture2D)'; @@ -109,7 +109,7 @@ defineSuite([ ' gl_FragData[0] = vec4(0.0); \n' + ' gl_FragData[1].xyz = vec3(1.0); \n' + '} \n'; - var output = glslModernizeShaderText(noQualifiers, true); + var output = modernizeShader(noQualifiers, true); var expected0 = 'layout(location = 0) out vec4 czm_out0;'; var expected1 = 'layout(location = 1) out vec4 czm_out1;'; expect(output).toContain(expected0); @@ -132,7 +132,7 @@ defineSuite([ ' gl_FragDepthEXT = 0.0; \n' + '} \n'; - var output = glslModernizeShaderText(old_fragment, true); + var output = modernizeShader(old_fragment, true); var expectedDepth = 'gl_FragDepth = 0.0;'; var expectedTexture2D = 'texture(example, v_textureCoordinates);'; @@ -170,7 +170,7 @@ defineSuite([ ' varyingVariable = position.wzyx; \n' + '} \n'; - var output = glslModernizeShaderText(old_vertex, false); + var output = modernizeShader(old_vertex, false); var expectedOut = 'out vec4 varyingVariable;'; var expectedIn = 'in vec4 position;'; @@ -195,7 +195,7 @@ defineSuite([ ' gl_FragData[0] = vec4(0.0); \n' + ' #endif //EXAMPLE_BRANCH \n' + '} \n'; - var output = glslModernizeShaderText(noQualifiers, true); + var output = modernizeShader(noQualifiers, true); var expected = '#ifdef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_out0;\n#endif'; expect(output).toContain(expected); }); @@ -211,7 +211,7 @@ defineSuite([ ' gl_FragData[1] = vec4(1.0); \n' + ' #endif //EXAMPLE_BRANCH \n' + '} \n'; - var output = glslModernizeShaderText(noQualifiers, true); + var output = modernizeShader(noQualifiers, true); var expected0 = '#ifdef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_out0;\n#endif'; var expected1 = '#ifdef EXAMPLE_BRANCH \nlayout(location = 1) out vec4 czm_out1;\n#endif'; expect(output).toContain(expected0); @@ -233,7 +233,7 @@ defineSuite([ ' gl_FragData[1] = vec4(1.0); \n' + ' #endif //!EXAMPLE_BRANCH \n' + '} \n'; - var output = glslModernizeShaderText(noQualifiers, true); + var output = modernizeShader(noQualifiers, true); var notExpected = '#ifdef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_out0;\n#endif'; expect(output).not.toContain(notExpected); }); @@ -252,7 +252,7 @@ defineSuite([ ' gl_FragData[0] = vec4(0.0); \n' + ' #endif //EXAMPLE_BRANCH1 \n' + '} \n'; - var output = glslModernizeShaderText(noQualifiers, true); + var output = modernizeShader(noQualifiers, true); var notExpected = '#ifdef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_out0;\n#endif'; expect(output).not.toContain(notExpected); }); @@ -271,7 +271,7 @@ defineSuite([ ' #endif //EXAMPLE_BRANCH1 \n' + ' #endif //EXAMPLE_BRANCH \n' + '} \n'; - var output = glslModernizeShaderText(noQualifiers, true); + var output = modernizeShader(noQualifiers, true); var expected0 = '#ifdef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_out0;\n#endif'; var expected1 = /#ifdef (EXAMPLE_BRANCH|EXAMPLE_BRANCH1)\s*\n\s*#ifdef (EXAMPLE_BRANCH1|EXAMPLE_BRANCH)\s*\n\s*layout\(location = 1\) out vec4 czm_out1;/g; var containsExpected0 = expected1.test(output); @@ -291,7 +291,7 @@ defineSuite([ ' gl_FragData[0] = vec4(1.0); \n' + ' #endif //EXAMPLE_BRANCH \n' + '} \n'; - var output = glslModernizeShaderText(noQualifiers, true); + var output = modernizeShader(noQualifiers, true); var notExpected = '#ifdef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_out0;\n#endif'; expect(output).not.toContain(notExpected); }); @@ -308,7 +308,7 @@ defineSuite([ ' gl_FragColor = vec4(1.0); \n' + ' #endif //EXAMPLE_BRANCH \n' + '} \n'; - var output = glslModernizeShaderText(noQualifiers, true); + var output = modernizeShader(noQualifiers, true); var expected0 = '#ifdef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_out0;\n#endif'; var expected1 = '#ifndef EXAMPLE_BRANCH \nlayout(location = 0) out vec4 czm_fragColor;\n#endif'; expect(output).toContain(expected0); From 1686573ad9c2cc7fbcd7304354b2197f46d99cd7 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Mon, 17 Jul 2017 13:46:49 -0400 Subject: [PATCH 072/132] Now using .test() instead of .search and fixes a typo --- Source/Renderer/ModernizeShader.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Renderer/ModernizeShader.js b/Source/Renderer/ModernizeShader.js index 1d019c92b18a..5aff694364a2 100644 --- a/Source/Renderer/ModernizeShader.js +++ b/Source/Renderer/ModernizeShader.js @@ -22,7 +22,7 @@ define([ var outputDeclarationRegex = /#define OUTPUT_DECLARATION/; var splitSource = source.split('\n'); - if (source.search(/#version 300 es/g) !== -1) { + if (/#version 300 es/g.test(source) !== -1) { return source; } @@ -37,7 +37,7 @@ define([ } if (outputDeclarationLine === -1) { - throw new DeveloperError('Could not find a #define OUTPUT_DECLARATION nor a main function!'); + throw new DeveloperError('Could not find a #define OUTPUT_DECLARATION!'); } // Note that this fails if your string looks like From d9167a2be170c8f4156f279f1903ce5bb554ab5b Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Mon, 17 Jul 2017 13:56:37 -0400 Subject: [PATCH 073/132] Splits replace into two different functions --- Source/Renderer/ModernizeShader.js | 42 +++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/Source/Renderer/ModernizeShader.js b/Source/Renderer/ModernizeShader.js index 5aff694364a2..77d4d38d9d08 100644 --- a/Source/Renderer/ModernizeShader.js +++ b/Source/Renderer/ModernizeShader.js @@ -22,7 +22,7 @@ define([ var outputDeclarationRegex = /#define OUTPUT_DECLARATION/; var splitSource = source.split('\n'); - if (/#version 300 es/g.test(source) !== -1) { + if (/#version 300 es/g.test(source)) { return source; } @@ -42,20 +42,20 @@ define([ // Note that this fails if your string looks like // searchString[singleCharacter]searchString - function replaceInSource(str, replacement, strIsRegex) { - var regex = str; - if ((strIsRegex === undefined) || strIsRegex === false) { - var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; - regex = new RegExp(regexStr, 'g'); + function replaceInSourceString(str, replacement) { + var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; + var regex = new RegExp(regexStr, 'g'); + + for (var number = 0; number < splitSource.length; ++number) { + var line = splitSource[number]; + splitSource[number] = line.replace(regex, '$1' + replacement + '$3'); } + } + function replaceInSourceRegex(regex, replacement) { for (var number = 0; number < splitSource.length; ++number) { var line = splitSource[number]; - if (strIsRegex) { - splitSource[number] = line.replace(regex, replacement); - } else { - splitSource[number] = line.replace(regex, '$1' + replacement + '$3'); - } + splitSource[number] = line.replace(regex, replacement); } } @@ -142,7 +142,7 @@ define([ function removeExtension(name) { var regex = '#extension\\s+GL_' + name + '\\s+:\\s+[a-zA-Z0-9]+\\s*$'; - replaceInSource(new RegExp(regex, 'g'), '', true); + replaceInSourceRegex(new RegExp(regex, 'g'), '', true); } var variableSet = []; @@ -153,7 +153,7 @@ define([ var regex = new RegExp(fragDataString, 'g'); if (regex.test(source)) { setAdd(newOutput, variableSet); - replaceInSource(fragDataString, newOutput); + replaceInSourceString(fragDataString, newOutput); splitSource.splice(outputDeclarationLine, 0, 'layout(location = ' + i + ') out vec4 ' + newOutput + ';'); outputDeclarationLine += 1; } @@ -162,7 +162,7 @@ define([ var czmFragColor = 'czm_fragColor'; if (findInSource('gl_FragColor')) { setAdd(czmFragColor, variableSet); - replaceInSource('gl_FragColor', czmFragColor); + replaceInSourceString('gl_FragColor', czmFragColor); splitSource.splice(outputDeclarationLine, 0, 'layout(location = 0) out vec4 czm_fragColor;'); outputDeclarationLine += 1; } @@ -214,16 +214,16 @@ define([ removeExtension('EXT_draw_buffers'); removeExtension('EXT_frag_depth'); - replaceInSource('texture2D', 'texture'); - replaceInSource('texture3D', 'texture'); - replaceInSource('textureCube', 'texture'); - replaceInSource('gl_FragDepthEXT', 'gl_FragDepth'); + replaceInSourceString('texture2D', 'texture'); + replaceInSourceString('texture3D', 'texture'); + replaceInSourceString('textureCube', 'texture'); + replaceInSourceString('gl_FragDepthEXT', 'gl_FragDepth'); if (isFragmentShader) { - replaceInSource('varying', 'in'); + replaceInSourceString('varying', 'in'); } else { - replaceInSource('attribute', 'in'); - replaceInSource('varying', 'out'); + replaceInSourceString('attribute', 'in'); + replaceInSourceString('varying', 'out'); } return compileSource(); From 9403d8fb229cf03a97accd754087ad58fbef6767 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Mon, 17 Jul 2017 14:01:21 -0400 Subject: [PATCH 074/132] All the functions are now external --- Source/Renderer/ModernizeShader.js | 241 +++++++++++++++-------------- 1 file changed, 122 insertions(+), 119 deletions(-) diff --git a/Source/Renderer/ModernizeShader.js b/Source/Renderer/ModernizeShader.js index 77d4d38d9d08..8f5e231294bf 100644 --- a/Source/Renderer/ModernizeShader.js +++ b/Source/Renderer/ModernizeShader.js @@ -6,6 +6,114 @@ define([ DeveloperError) { 'use strict'; + // Note that this fails if your string looks like + // searchString[singleCharacter]searchString + function replaceInSourceString(str, replacement, splitSource) { + var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; + var regex = new RegExp(regexStr, 'g'); + + for (var number = 0; number < splitSource.length; ++number) { + var line = splitSource[number]; + splitSource[number] = line.replace(regex, '$1' + replacement + '$3'); + } + } + + function replaceInSourceRegex(regex, replacement, splitSource) { + for (var number = 0; number < splitSource.length; ++number) { + var line = splitSource[number]; + splitSource[number] = line.replace(regex, replacement); + } + } + + function findInSource(str, splitSource) { + var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; + var regex = new RegExp(regexStr, 'g'); + for (var number = 0; number < splitSource.length; ++number) { + var line = splitSource[number]; + if (regex.test(line)) { + return true; + } + } + return false; + } + + function compileSource(splitSource) { + var wholeSource = ''; + for (var number = 0; number < splitSource.length; ++number) { + wholeSource += splitSource[number] + '\n'; + } + return wholeSource; + } + + function setAdd(variable, set1) { + if (set1.indexOf(variable) === -1) { + set1.push(variable); + } + } + + function getVariablePreprocessorBranch(variablesThatWeCareAbout, splitSource) { + var variableMap = {}; + var negativeMap = {}; + + for (var a = 0; a < variablesThatWeCareAbout.length; ++a) { + var variableThatWeCareAbout = variablesThatWeCareAbout[a]; + variableMap[variableThatWeCareAbout] = [null]; + } + + var stack = []; + for (var i = 0; i < splitSource.length; ++i) { + var line = splitSource[i]; + var hasIF = /(#ifdef|#if)/g.test(line); + var hasELSE = /#else/g.test(line); + var hasENDIF = /#endif/g.test(line); + + if (hasIF) { + stack.push(line); + } else if (hasELSE) { + var top = stack[stack.length - 1]; + var op = top.replace('ifdef', 'ifndef'); + if (/if/g.test(op)) { + op = op.replace(/(#if\s+)(\S*)([^]*)/, '$1!($2)$3'); + } + stack.pop(); + stack.push(op); + + negativeMap[top] = op; + negativeMap[op] = top; + } else if (hasENDIF) { + stack.pop(); + } else if (!/layout/g.test(line)) { + for (var varIndex = 0; varIndex < variablesThatWeCareAbout.length; ++varIndex) { + var varName = variablesThatWeCareAbout[varIndex]; + if (line.indexOf(varName) !== -1) { + if (variableMap[varName].length === 1 && variableMap[varName][0] === null) { + variableMap[varName] = stack.slice(); + } else { + variableMap[varName] = variableMap[varName].filter(function(x) { + return stack.indexOf(x) >= 0; + }); + } + } + } + } + } + + for (var care in variableMap) { + if (variableMap.hasOwnProperty(care)) { + if (variableMap.length === 1 && variableMap[0] === null) { + variableMap.splice(0, 1); + } + } + } + + return variableMap; + } + + function removeExtension(name, splitSource) { + var regex = '#extension\\s+GL_' + name + '\\s+:\\s+[a-zA-Z0-9]+\\s*$'; + replaceInSourceRegex(new RegExp(regex, 'g'), '', splitSource); + } + /** * A function to port GLSL shaders from GLSL ES 1.00 to GLSL ES 3.00 * @@ -40,111 +148,6 @@ define([ throw new DeveloperError('Could not find a #define OUTPUT_DECLARATION!'); } - // Note that this fails if your string looks like - // searchString[singleCharacter]searchString - function replaceInSourceString(str, replacement) { - var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; - var regex = new RegExp(regexStr, 'g'); - - for (var number = 0; number < splitSource.length; ++number) { - var line = splitSource[number]; - splitSource[number] = line.replace(regex, '$1' + replacement + '$3'); - } - } - - function replaceInSourceRegex(regex, replacement) { - for (var number = 0; number < splitSource.length; ++number) { - var line = splitSource[number]; - splitSource[number] = line.replace(regex, replacement); - } - } - - function findInSource(str) { - var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; - var regex = new RegExp(regexStr, 'g'); - for (var number = 0; number < splitSource.length; ++number) { - var line = splitSource[number]; - if (regex.test(line)) { - return true; - } - } - return false; - } - - function compileSource() { - var wholeSource = ''; - for (var number = 0; number < splitSource.length; ++number) { - wholeSource += splitSource[number] + '\n'; - } - return wholeSource; - } - - function setAdd(variable, set1) { - if (set1.indexOf(variable) === -1) - {set1.push(variable);} - } - - function getVariablePreprocessorBranch(variablesThatWeCareAbout) { - var variableMap = {}; - var negativeMap = {}; - - for (var a = 0; a < variablesThatWeCareAbout.length; ++a) { - var variableThatWeCareAbout = variablesThatWeCareAbout[a]; - variableMap[variableThatWeCareAbout] = [null]; - } - - var stack = []; - for (var i = 0; i < splitSource.length; ++i) { - var line = splitSource[i]; - var hasIF = /(#ifdef|#if)/g.test(line); - var hasELSE = /#else/g.test(line); - var hasENDIF = /#endif/g.test(line); - - if (hasIF) { - stack.push(line); - } else if (hasELSE) { - var top = stack[stack.length - 1]; - var op = top.replace('ifdef', 'ifndef'); - if (/if/g.test(op)) { - op = op.replace(/(#if\s+)(\S*)([^]*)/, '$1!($2)$3'); - } - stack.pop(); - stack.push(op); - - negativeMap[top] = op; - negativeMap[op] = top; - } else if (hasENDIF) { - stack.pop(); - } else if (!/layout/g.test(line)) { - for (var varIndex = 0; varIndex < variablesThatWeCareAbout.length; ++varIndex) { - var varName = variablesThatWeCareAbout[varIndex]; - if (line.indexOf(varName) !== -1) { - if (variableMap[varName].length === 1 && variableMap[varName][0] === null) { - variableMap[varName] = stack.slice(); - } else { - variableMap[varName] = variableMap[varName].filter(function(x) { return stack.indexOf(x) >= 0; }); - } - } - } - } - } - - for (var care in variableMap) { - if (variableMap.hasOwnProperty(care)) { - if (variableMap.length === 1 && variableMap[0] === null) { - variableMap.splice(0, 1); - } - } - } - - return variableMap; - } - - function removeExtension(name) { - var regex = '#extension\\s+GL_' + name + '\\s+:\\s+[a-zA-Z0-9]+\\s*$'; - replaceInSourceRegex(new RegExp(regex, 'g'), '', true); - } - var variableSet = []; for (var i = 0; i < 10; i++) { @@ -153,21 +156,21 @@ define([ var regex = new RegExp(fragDataString, 'g'); if (regex.test(source)) { setAdd(newOutput, variableSet); - replaceInSourceString(fragDataString, newOutput); + replaceInSourceString(fragDataString, newOutput, splitSource); splitSource.splice(outputDeclarationLine, 0, 'layout(location = ' + i + ') out vec4 ' + newOutput + ';'); outputDeclarationLine += 1; } } var czmFragColor = 'czm_fragColor'; - if (findInSource('gl_FragColor')) { + if (findInSource('gl_FragColor', splitSource)) { setAdd(czmFragColor, variableSet); - replaceInSourceString('gl_FragColor', czmFragColor); + replaceInSourceString('gl_FragColor', czmFragColor, splitSource); splitSource.splice(outputDeclarationLine, 0, 'layout(location = 0) out vec4 czm_fragColor;'); outputDeclarationLine += 1; } - var variableMap = getVariablePreprocessorBranch(variableSet); + var variableMap = getVariablePreprocessorBranch(variableSet, splitSource); var lineAdds = {}; for (var c = 0; c < splitSource.length; c++) { var l = splitSource[c]; @@ -211,22 +214,22 @@ define([ splitSource.splice(0, 0, versionThree); } - removeExtension('EXT_draw_buffers'); - removeExtension('EXT_frag_depth'); + removeExtension('EXT_draw_buffers', splitSource); + removeExtension('EXT_frag_depth', splitSource); - replaceInSourceString('texture2D', 'texture'); - replaceInSourceString('texture3D', 'texture'); - replaceInSourceString('textureCube', 'texture'); - replaceInSourceString('gl_FragDepthEXT', 'gl_FragDepth'); + replaceInSourceString('texture2D', 'texture', splitSource); + replaceInSourceString('texture3D', 'texture', splitSource); + replaceInSourceString('textureCube', 'texture', splitSource); + replaceInSourceString('gl_FragDepthEXT', 'gl_FragDepth', splitSource); if (isFragmentShader) { - replaceInSourceString('varying', 'in'); + replaceInSourceString('varying', 'in', splitSource); } else { - replaceInSourceString('attribute', 'in'); - replaceInSourceString('varying', 'out'); + replaceInSourceString('attribute', 'in', splitSource); + replaceInSourceString('varying', 'out', splitSource); } - return compileSource(); + return compileSource(splitSource); } return modernizeShader; From a37d25f26ddd6b4b95317ac5cfaf220b23dfd7eb Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Mon, 17 Jul 2017 14:02:54 -0400 Subject: [PATCH 075/132] Renames length variable --- Source/Renderer/ModernizeShader.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/Renderer/ModernizeShader.js b/Source/Renderer/ModernizeShader.js index 8f5e231294bf..26fbed91fed9 100644 --- a/Source/Renderer/ModernizeShader.js +++ b/Source/Renderer/ModernizeShader.js @@ -55,7 +55,8 @@ define([ var variableMap = {}; var negativeMap = {}; - for (var a = 0; a < variablesThatWeCareAbout.length; ++a) { + var numVariablesWeCareAbout = variablesThatWeCareAbout.length; + for (var a = 0; a < numVariablesWeCareAbout; ++a) { var variableThatWeCareAbout = variablesThatWeCareAbout[a]; variableMap[variableThatWeCareAbout] = [null]; } @@ -83,7 +84,7 @@ define([ } else if (hasENDIF) { stack.pop(); } else if (!/layout/g.test(line)) { - for (var varIndex = 0; varIndex < variablesThatWeCareAbout.length; ++varIndex) { + for (var varIndex = 0; varIndex < numVariablesWeCareAbout; ++varIndex) { var varName = variablesThatWeCareAbout[varIndex]; if (line.indexOf(varName) !== -1) { if (variableMap[varName].length === 1 && variableMap[varName][0] === null) { From 361691e28f25f75f8c79bd5d16ea93876f9d0447 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Mon, 17 Jul 2017 14:04:05 -0400 Subject: [PATCH 076/132] Removes negativeMap --- Source/Renderer/ModernizeShader.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Source/Renderer/ModernizeShader.js b/Source/Renderer/ModernizeShader.js index 26fbed91fed9..a050ef5614d7 100644 --- a/Source/Renderer/ModernizeShader.js +++ b/Source/Renderer/ModernizeShader.js @@ -53,7 +53,6 @@ define([ function getVariablePreprocessorBranch(variablesThatWeCareAbout, splitSource) { var variableMap = {}; - var negativeMap = {}; var numVariablesWeCareAbout = variablesThatWeCareAbout.length; for (var a = 0; a < numVariablesWeCareAbout; ++a) { @@ -78,9 +77,6 @@ define([ } stack.pop(); stack.push(op); - - negativeMap[top] = op; - negativeMap[op] = top; } else if (hasENDIF) { stack.pop(); } else if (!/layout/g.test(line)) { From 3c80a138321119dcb5d66386e0a4ac04c620f1ae Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Mon, 17 Jul 2017 14:05:18 -0400 Subject: [PATCH 077/132] Renames variableSet to outputVariables --- Source/Renderer/ModernizeShader.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Renderer/ModernizeShader.js b/Source/Renderer/ModernizeShader.js index a050ef5614d7..40c3ffaa8c52 100644 --- a/Source/Renderer/ModernizeShader.js +++ b/Source/Renderer/ModernizeShader.js @@ -145,14 +145,14 @@ define([ throw new DeveloperError('Could not find a #define OUTPUT_DECLARATION!'); } - var variableSet = []; + var outputVariables = []; for (var i = 0; i < 10; i++) { var fragDataString = 'gl_FragData\\[' + i + '\\]'; var newOutput = 'czm_out' + i; var regex = new RegExp(fragDataString, 'g'); if (regex.test(source)) { - setAdd(newOutput, variableSet); + setAdd(newOutput, outputVariables); replaceInSourceString(fragDataString, newOutput, splitSource); splitSource.splice(outputDeclarationLine, 0, 'layout(location = ' + i + ') out vec4 ' + newOutput + ';'); outputDeclarationLine += 1; @@ -161,13 +161,13 @@ define([ var czmFragColor = 'czm_fragColor'; if (findInSource('gl_FragColor', splitSource)) { - setAdd(czmFragColor, variableSet); + setAdd(czmFragColor, outputVariables); replaceInSourceString('gl_FragColor', czmFragColor, splitSource); splitSource.splice(outputDeclarationLine, 0, 'layout(location = 0) out vec4 czm_fragColor;'); outputDeclarationLine += 1; } - var variableMap = getVariablePreprocessorBranch(variableSet, splitSource); + var variableMap = getVariablePreprocessorBranch(outputVariables, splitSource); var lineAdds = {}; for (var c = 0; c < splitSource.length; c++) { var l = splitSource[c]; From 59b140265bd8376bd3be9beaf64a232295226add Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Mon, 17 Jul 2017 14:06:14 -0400 Subject: [PATCH 078/132] Replaces RegExp.exec with RegExp.test --- Source/Renderer/ModernizeShader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Renderer/ModernizeShader.js b/Source/Renderer/ModernizeShader.js index 40c3ffaa8c52..bc078e9d5112 100644 --- a/Source/Renderer/ModernizeShader.js +++ b/Source/Renderer/ModernizeShader.js @@ -174,7 +174,7 @@ define([ for (var care in variableMap) { if (variableMap.hasOwnProperty(care)) { var matchVar = new RegExp('(layout)[^]+(out)[^]+(' + care + ')[^]+', 'g'); - if (matchVar.exec(l) !== null) { + if (matchVar.test(l)) { lineAdds[l] = care; } } From 0addb522909dcb8ba9fc6dae1163eafca0021dc3 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Mon, 17 Jul 2017 14:07:11 -0400 Subject: [PATCH 079/132] Replaces all the "it (" with "it(" --- Specs/Renderer/ModernizeShaderSpec.js | 34 +++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Specs/Renderer/ModernizeShaderSpec.js b/Specs/Renderer/ModernizeShaderSpec.js index 89091f73c16a..5e02be5d264b 100644 --- a/Specs/Renderer/ModernizeShaderSpec.js +++ b/Specs/Renderer/ModernizeShaderSpec.js @@ -4,7 +4,7 @@ defineSuite([ modernizeShader) { 'use strict'; - it ('adds version string', function() { + it('adds version string', function() { var simple = '#define OUTPUT_DECLARATION \n' + 'void main() \n' + @@ -15,7 +15,7 @@ defineSuite([ expect(output.split('\n')[0]).toEqual(expected); }); - it ('removes extensions', function() { + it('removes extensions', function() { var extensions = '#define OUTPUT_DECLARATION \n' + '#extension GL_EXT_draw_buffers : enable \n' + @@ -27,7 +27,7 @@ defineSuite([ expect(output).not.toContain(notExpected); }); - it ('throws exception if no output declaration', function() { + it('throws exception if no output declaration', function() { var noOutputDeclaration = 'void main() \n' + '{ \n' + @@ -38,7 +38,7 @@ defineSuite([ expect(runFunc).toThrow(); }); - it ('creates layout qualifier for gl_FragColor', function() { + it('creates layout qualifier for gl_FragColor', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + 'void main() \n' + @@ -50,7 +50,7 @@ defineSuite([ expect(output).toContain(expected); }); - it ('creates layout qualifier for gl_FragData', function() { + it('creates layout qualifier for gl_FragData', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + 'void main() \n' + @@ -62,7 +62,7 @@ defineSuite([ expect(output).toContain(expected); }); - it ('creates layout qualifier for MRT', function() { + it('creates layout qualifier for MRT', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + '#extension GL_EXT_draw_buffers : enable \n' + @@ -78,7 +78,7 @@ defineSuite([ expect(output).toContain(expected1); }); - it ('does not create layout qualifier for reserved word lookalike variables', function() { + it('does not create layout qualifier for reserved word lookalike variables', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + 'uniform sampler2D example; \n' + @@ -100,7 +100,7 @@ defineSuite([ expect(output).not.toContain(notExpectedLayout); }); - it ('creates layout qualifier with swizzle', function() { + it('creates layout qualifier with swizzle', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + '#extension GL_EXT_draw_buffers : enable \n' + @@ -116,7 +116,7 @@ defineSuite([ expect(output).toContain(expected1); }); - it ('removes old functions/variables from fragment shader', function() { + it('removes old functions/variables from fragment shader', function() { var old_fragment = '#define OUTPUT_DECLARATION \n' + '#extension GL_EXT_draw_buffers : enable \n' + @@ -159,7 +159,7 @@ defineSuite([ expect(output).not.toContain(notExpectedVarying); }); - it ('removes old functions/variables from vertex shader', function() { + it('removes old functions/variables from vertex shader', function() { var old_vertex = '#define OUTPUT_DECLARATION \n' + 'attribute vec4 position; \n' + @@ -185,7 +185,7 @@ defineSuite([ expect(output).not.toContain(notExpectedVarying); }); - it ('creates single layout qualifier under single branch, single condition', function() { + it('creates single layout qualifier under single branch, single condition', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + '#define EXAMPLE_BRANCH \n' + @@ -200,7 +200,7 @@ defineSuite([ expect(output).toContain(expected); }); - it ('creates multiple layout qualifiers under single branch, single condition', function() { + it('creates multiple layout qualifiers under single branch, single condition', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + '#define EXAMPLE_BRANCH \n' + @@ -218,7 +218,7 @@ defineSuite([ expect(output).toContain(expected1); }); - it ('creates multiple layout qualifiers under multiple branches, single condition (cancels)', function() { + it('creates multiple layout qualifiers under multiple branches, single condition (cancels)', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + '#define EXAMPLE_BRANCH \n' + @@ -238,7 +238,7 @@ defineSuite([ expect(output).not.toContain(notExpected); }); - it ('creates single layout qualifier under multiple branches, multiple conditions (cancels)', function() { + it('creates single layout qualifier under multiple branches, multiple conditions (cancels)', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + '#define EXAMPLE_BRANCH \n' + @@ -257,7 +257,7 @@ defineSuite([ expect(output).not.toContain(notExpected); }); - it ('creates multiple layout qualifiers under multiple branches, multiple conditions (cascades)', function() { + it('creates multiple layout qualifiers under multiple branches, multiple conditions (cascades)', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + '#define EXAMPLE_BRANCH \n' + @@ -279,7 +279,7 @@ defineSuite([ expect(containsExpected0).toBe(true); }); - it ('creates single layout qualifier under multiple branches, single condition (else)', function() { + it('creates single layout qualifier under multiple branches, single condition (else)', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + '#define EXAMPLE_BRANCH \n' + @@ -296,7 +296,7 @@ defineSuite([ expect(output).not.toContain(notExpected); }); - it ('creates branched layout qualifiers for gl_FragColor and gl_FragData', function() { + it('creates branched layout qualifiers for gl_FragColor and gl_FragData', function() { var noQualifiers = '#define OUTPUT_DECLARATION \n' + '#define EXAMPLE_BRANCH \n' + From 0b210d663e51c950a9110e3c6b1b65f6cb979af5 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Mon, 17 Jul 2017 14:07:45 -0400 Subject: [PATCH 080/132] Changes toThrow to toThrowDeveloperError --- Specs/Renderer/ModernizeShaderSpec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Specs/Renderer/ModernizeShaderSpec.js b/Specs/Renderer/ModernizeShaderSpec.js index 5e02be5d264b..ac629f78f6e3 100644 --- a/Specs/Renderer/ModernizeShaderSpec.js +++ b/Specs/Renderer/ModernizeShaderSpec.js @@ -35,7 +35,7 @@ defineSuite([ var runFunc = function() { modernizeShader(noOutputDeclaration, true); }; - expect(runFunc).toThrow(); + expect(runFunc).toThrowDeveloperError(); }); it('creates layout qualifier for gl_FragColor', function() { From f0750fecb64355366de4f0dd208c32d7c956dcf2 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Mon, 17 Jul 2017 14:12:44 -0400 Subject: [PATCH 081/132] Renames "ModernizeShader" to "modernizeShader" --- Source/Renderer/ShaderSource.js | 2 +- Source/Renderer/{ModernizeShader.js => modernizeShader.js} | 0 .../Renderer/{ModernizeShaderSpec.js => modernizeShaderSpec.js} | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename Source/Renderer/{ModernizeShader.js => modernizeShader.js} (100%) rename Specs/Renderer/{ModernizeShaderSpec.js => modernizeShaderSpec.js} (99%) diff --git a/Source/Renderer/ShaderSource.js b/Source/Renderer/ShaderSource.js index da96cbdf4526..b1f4684b93df 100644 --- a/Source/Renderer/ShaderSource.js +++ b/Source/Renderer/ShaderSource.js @@ -2,7 +2,7 @@ define([ '../Core/defaultValue', '../Core/defined', '../Core/DeveloperError', - '../Renderer/ModernizeShader', + '../Renderer/modernizeShader', '../Shaders/Builtin/CzmBuiltins', './AutomaticUniforms' ], function( diff --git a/Source/Renderer/ModernizeShader.js b/Source/Renderer/modernizeShader.js similarity index 100% rename from Source/Renderer/ModernizeShader.js rename to Source/Renderer/modernizeShader.js diff --git a/Specs/Renderer/ModernizeShaderSpec.js b/Specs/Renderer/modernizeShaderSpec.js similarity index 99% rename from Specs/Renderer/ModernizeShaderSpec.js rename to Specs/Renderer/modernizeShaderSpec.js index ac629f78f6e3..b915fd6461e7 100644 --- a/Specs/Renderer/ModernizeShaderSpec.js +++ b/Specs/Renderer/modernizeShaderSpec.js @@ -1,5 +1,5 @@ defineSuite([ - 'Renderer/ModernizeShader' + 'Renderer/modernizeShader' ], function( modernizeShader) { 'use strict'; From b82a087511d0609df4ffa46d55fbd66e40ca5893 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Mon, 17 Jul 2017 14:16:45 -0400 Subject: [PATCH 082/132] Renames "variablesThatWeCareAbout" to "layoutVariables" --- Source/Renderer/modernizeShader.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/Renderer/modernizeShader.js b/Source/Renderer/modernizeShader.js index bc078e9d5112..ba649428cb95 100644 --- a/Source/Renderer/modernizeShader.js +++ b/Source/Renderer/modernizeShader.js @@ -51,12 +51,12 @@ define([ } } - function getVariablePreprocessorBranch(variablesThatWeCareAbout, splitSource) { + function getVariablePreprocessorBranch(layoutVariables, splitSource) { var variableMap = {}; - var numVariablesWeCareAbout = variablesThatWeCareAbout.length; - for (var a = 0; a < numVariablesWeCareAbout; ++a) { - var variableThatWeCareAbout = variablesThatWeCareAbout[a]; + var numLayoutVariables = layoutVariables.length; + for (var a = 0; a < numLayoutVariables; ++a) { + var variableThatWeCareAbout = layoutVariables[a]; variableMap[variableThatWeCareAbout] = [null]; } @@ -80,8 +80,8 @@ define([ } else if (hasENDIF) { stack.pop(); } else if (!/layout/g.test(line)) { - for (var varIndex = 0; varIndex < numVariablesWeCareAbout; ++varIndex) { - var varName = variablesThatWeCareAbout[varIndex]; + for (var varIndex = 0; varIndex < numLayoutVariables; ++varIndex) { + var varName = layoutVariables[varIndex]; if (line.indexOf(varName) !== -1) { if (variableMap[varName].length === 1 && variableMap[varName][0] === null) { variableMap[varName] = stack.slice(); From f02e18e2bd99d34bcb35024086b853c4d61868b3 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 17 Jul 2017 16:23:56 -0400 Subject: [PATCH 083/132] Add FrustumGeometry. --- Source/Core/FrustumGeometry.js | 462 ++++++++++++++++++++++++ Source/Core/OrthographicFrustum.js | 41 +++ Source/Core/PerspectiveFrustum.js | 45 +++ Source/Scene/DebugCameraPrimitive.js | 2 +- Source/Workers/createFrustumGeometry.js | 17 + 5 files changed, 566 insertions(+), 1 deletion(-) create mode 100644 Source/Core/FrustumGeometry.js create mode 100644 Source/Workers/createFrustumGeometry.js diff --git a/Source/Core/FrustumGeometry.js b/Source/Core/FrustumGeometry.js new file mode 100644 index 000000000000..f876e7c0d1ac --- /dev/null +++ b/Source/Core/FrustumGeometry.js @@ -0,0 +1,462 @@ +define([ + './BoundingSphere', + './Cartesian3', + './Cartesian4', + './Check', + './ComponentDatatype', + './defaultValue', + './defined', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './Matrix3', + './Matrix4', + './OrthographicFrustum', + './PerspectiveFrustum', + './PrimitiveType', + './Quaternion', + './VertexFormat' + ], function( + BoundingSphere, + Cartesian3, + Cartesian4, + Check, + ComponentDatatype, + defaultValue, + defined, + Geometry, + GeometryAttribute, + GeometryAttributes, + Matrix3, + Matrix4, + OrthographicFrustum, + PerspectiveFrustum, + PrimitiveType, + Quaternion, + VertexFormat) { + 'use strict'; + + var PERSPECTIVE = 0; + var ORTHOGRAPHIC = 1; + + /** + * Describes a frustum at the given position and orientation. + * + * @alias FrustumGeometry + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {PerspectiveFrustum|OrthographicFrustum} options.frustum The frustum. + * @param {Cartesian3} options.position The position of the frustum. + * @param {Quaternion} options.orientation The orientation of the frustum. + * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. + */ + function FrustumGeometry(options) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object('options', options); + Check.typeOf.object('options.frustum', options.frustum); + Check.typeOf.object('options.position', options.position); + Check.typeOf.object('options.orientation', options.orientation); + //>>includeEnd('debug'); + + var frustum = options.frustum; + var orientation = options.orientation; + var position = options.position; + var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); + + var frustumType; + var frustumPackedLength; + if (frustum instanceof PerspectiveFrustum) { + frustumType = PERSPECTIVE; + frustumPackedLength = PerspectiveFrustum.packedLength; + } else if (frustum instanceof OrthographicFrustum) { + frustumType = ORTHOGRAPHIC; + frustumPackedLength = OrthographicFrustum.packedLength; + } + + this._frustumType = frustumType; + this._frustum = frustum.clone(); + this._position = Cartesian3.clone(position); + this._orientation = Quaternion.clone(orientation); + this._vertexFormat = vertexFormat; + this._workerName = 'createFrustumGeometry'; + + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + this.packedLength = 1 + frustumPackedLength + Cartesian3.packedLength + Quaternion.packedLength + VertexFormat.packedLength; + } + + /** + * Stores the provided instance into the provided array. + * + * @param {FrustumGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + FrustumGeometry.pack = function(value, array, startingIndex) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object('value', value); + Check.defined('array', array); + //>>includeEnd('debug'); + + startingIndex = defaultValue(startingIndex, 0); + + var frustumType = value._frustumType; + var frustum = value._frustum; + + array[startingIndex++] = frustumType; + + if (frustumType === PERSPECTIVE) { + PerspectiveFrustum.pack(frustum, array, startingIndex); + startingIndex += PerspectiveFrustum.packedLength; + } else { + OrthographicFrustum.pack(frustum, array, startingIndex); + startingIndex += OrthographicFrustum.packedLength; + } + + Cartesian3.pack(value._position, array, startingIndex); + startingIndex += Cartesian3.packedLength; + Quaternion.pack(value._orientation, array, startingIndex); + startingIndex += Quaternion.packedLength; + VertexFormat.pack(value._vertexFormat, array, startingIndex); + + return array; + }; + + var scratchPackPerspective = new PerspectiveFrustum(); + var scratchPackOrthographic = new OrthographicFrustum(); + var scratchPackQuaternion = new Quaternion(); + var scratchPackPosition = new Cartesian3(); + var scratchVertexFormat = new VertexFormat(); + + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {FrustumGeometry} [result] The object into which to store the result. + */ + FrustumGeometry.unpack = function(array, startingIndex, result) { + //>>includeStart('debug', pragmas.debug); + Check.defined('array', array); + //>>includeEnd('debug'); + + startingIndex = defaultValue(startingIndex, 0); + + var frustumType = array[startingIndex++]; + + var frustum; + if (frustumType === PERSPECTIVE) { + frustum = PerspectiveFrustum.unpack(array, startingIndex, scratchPackPerspective); + startingIndex += PerspectiveFrustum.packedLength; + } else { + frustum = OrthographicFrustum.unpack(array, startingIndex, scratchPackOrthographic); + startingIndex += OrthographicFrustum.packedLength; + } + + var position = Cartesian3.unpack(array, startingIndex, scratchPackPosition); + startingIndex += Cartesian3.packedLength; + var orientation = Quaternion.unpack(array, startingIndex, scratchPackQuaternion); + startingIndex += Quaternion.packedLength; + var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); + + if (!defined(result)) { + return new FrustumGeometry({ + frustum : frustum, + position : position, + orientation : orientation, + vertexFormat : vertexFormat + }); + } + + var frustumResult = frustumType === result._frustumType ? result._frustum : undefined; + result._frustum = frustum.clone(frustumResult); + + result._frustumType = frustumType; + result._position = Cartesian3.clone(position, result._position); + result._orientation = Quaternion.clone(orientation, result._orientation); + result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); + + return result; + }; + + function getAttributes(offset, normals, tangents, bitangents, st, normal, tangent, bitangent) { + var stOffset = offset / 3 * 2; + + for (var i = 0; i < 4; ++i) { + if (defined(normals)) { + normals[offset] = normal.x; + normals[offset + 1] = normal.y; + normals[offset + 2] = normal.z; + } + if (defined(tangents)) { + tangents[offset] = tangent.x; + tangents[offset + 1] = tangent.y; + tangents[offset + 2] = tangent.z; + } + if (defined(bitangents)) { + bitangents[offset] = bitangent.x; + bitangents[offset + 1] = bitangent.y; + bitangents[offset + 2] = bitangent.z; + } + offset += 3; + } + + st[stOffset] = 0.0; + st[stOffset + 1] = 0.0; + st[stOffset + 2] = 1.0; + st[stOffset + 3] = 0.0; + st[stOffset + 4] = 1.0; + st[stOffset + 5] = 1.0; + st[stOffset + 6] = 0.0; + st[stOffset + 7] = 1.0; + } + + var scratchRotationMatrix = new Matrix3(); + var scratchViewMatrix = new Matrix4(); + var scratchInverseMatrix = new Matrix4(); + + var scratchXDirection = new Cartesian3(); + var scratchYDirection = new Cartesian3(); + var scratchZDirection = new Cartesian3(); + var scratchNegativeX = new Cartesian3(); + var scratchNegativeY = new Cartesian3(); + var scratchNegativeZ = new Cartesian3(); + + var frustumSplits = new Array(3); + + var frustumCornersNDC = new Array(4); + frustumCornersNDC[0] = new Cartesian4(-1.0, -1.0, 1.0, 1.0); + frustumCornersNDC[1] = new Cartesian4(1.0, -1.0, 1.0, 1.0); + frustumCornersNDC[2] = new Cartesian4(1.0, 1.0, 1.0, 1.0); + frustumCornersNDC[3] = new Cartesian4(-1.0, 1.0, 1.0, 1.0); + + var scratchFrustumCorners = new Array(4); + for (var i = 0; i < 4; ++i) { + scratchFrustumCorners[i] = new Cartesian4(); + } + + /** + * Computes the geometric representation of a frustum, including its vertices, indices, and a bounding sphere. + * + * @param {FrustumGeometry} frustumGeometry A description of the frustum. + * @returns {Geometry|undefined} The computed vertices and indices. + */ + FrustumGeometry.createGeometry = function(frustumGeometry) { + var frustumType = frustumGeometry._frustumType; + var frustum = frustumGeometry._frustum; + var position = frustumGeometry._position; + var orientation = frustumGeometry._orientation; + var vertexFormat = frustumGeometry._vertexFormat; + + var rotationMatrix = Matrix3.fromQuaternion(orientation, scratchRotationMatrix); + var x = Matrix3.getColumn(rotationMatrix, 0, scratchXDirection); + var y = Matrix3.getColumn(rotationMatrix, 1, scratchYDirection); + var z = Matrix3.getColumn(rotationMatrix, 2, scratchZDirection); + + Cartesian3.normalize(x, x); + Cartesian3.normalize(y, y); + Cartesian3.normalize(z, z); + + Cartesian3.negate(x, x); + + var view = Matrix4.computeView(position, z, y, x, scratchViewMatrix); + + var inverseView; + var inverseViewProjection; + if (frustumType === PERSPECTIVE) { + var projection = frustum.projectionMatrix; + var viewProjection = Matrix4.multiply(projection, view, scratchInverseMatrix); + inverseViewProjection = Matrix4.inverse(viewProjection, scratchInverseMatrix); + } else { + inverseView = Matrix4.inverseTransformation(view, scratchInverseMatrix); + } + + frustumSplits[0] = frustum.near; + frustumSplits[1] = frustum.far; + frustumSplits[2] = frustum.far + 1.0; + + var i; + var positions = new Float64Array(3 * 4 * 6); + + for (i = 0; i < 2; ++i) { + for (var j = 0; j < 4; ++j) { + var corner = Cartesian4.clone(frustumCornersNDC[j], scratchFrustumCorners[j]); + + if (!defined(inverseViewProjection)) { + if (defined(frustum._offCenterFrustum)) { + frustum = frustum._offCenterFrustum; + } + + var near = frustumSplits[i]; + var far = frustumSplits[i + 1]; + + corner.x = (corner.x * (frustum.right - frustum.left) + frustum.left + frustum.right) * 0.5; + corner.y = (corner.y * (frustum.top - frustum.bottom) + frustum.bottom + frustum.top) * 0.5; + corner.z = (corner.z * (near - far) - near - far) * 0.5; + corner.w = 1.0; + + Matrix4.multiplyByVector(inverseView, corner, corner); + } else { + corner = Matrix4.multiplyByVector(inverseViewProjection, corner, corner); + + // Reverse perspective divide + var w = 1.0 / corner.w; + Cartesian3.multiplyByScalar(corner, w, corner); + + Cartesian3.subtract(corner, position, corner); + Cartesian3.normalize(corner, corner); + + var fac = Cartesian3.dot(z, corner); + Cartesian3.multiplyByScalar(corner, frustumSplits[i] / fac, corner); + Cartesian3.add(corner, position, corner); + } + + positions[12 * i + j * 3] = corner.x; + positions[12 * i + j * 3 + 1] = corner.y; + positions[12 * i + j * 3 + 2] = corner.z; + } + } + + // -x plane + var offset = 3 * 4 * 2; + positions[offset] = positions[3 * 4]; + positions[offset + 1] = positions[3 * 4 + 1]; + positions[offset + 2] = positions[3 * 4 + 2]; + positions[offset + 3] = positions[0]; + positions[offset + 4] = positions[1]; + positions[offset + 5] = positions[2]; + positions[offset + 6] = positions[3 * 3]; + positions[offset + 7] = positions[3 * 3 + 1]; + positions[offset + 8] = positions[3 * 3 + 2]; + positions[offset + 9] = positions[3 * 7]; + positions[offset + 10] = positions[3 * 7 + 1]; + positions[offset + 11] = positions[3 * 7 + 2]; + + // -y plane + offset += 3 * 4; + positions[offset] = positions[3 * 5]; + positions[offset + 1] = positions[3 * 5 + 1]; + positions[offset + 2] = positions[3 * 5 + 2]; + positions[offset + 3] = positions[3]; + positions[offset + 4] = positions[3 + 1]; + positions[offset + 5] = positions[3 + 2]; + positions[offset + 6] = positions[0]; + positions[offset + 7] = positions[1]; + positions[offset + 8] = positions[2]; + positions[offset + 9] = positions[3 * 4]; + positions[offset + 10] = positions[3 * 4 + 1]; + positions[offset + 11] = positions[3 * 4 + 2]; + + // +x plane + offset += 3 * 4; + positions[offset] = positions[3]; + positions[offset + 1] = positions[3 + 1]; + positions[offset + 2] = positions[3 + 2]; + positions[offset + 3] = positions[3 * 5]; + positions[offset + 4] = positions[3 * 5 + 1]; + positions[offset + 5] = positions[3 * 5 + 2]; + positions[offset + 6] = positions[3 * 6]; + positions[offset + 7] = positions[3 * 6 + 1]; + positions[offset + 8] = positions[3 * 6 + 2]; + positions[offset + 9] = positions[3 * 2]; + positions[offset + 10] = positions[3 * 2 + 1]; + positions[offset + 11] = positions[3 * 2 + 2]; + + // +y plane + offset += 3 * 4; + positions[offset] = positions[3 * 2]; + positions[offset + 1] = positions[3 * 2 + 1]; + positions[offset + 2] = positions[3 * 2 + 2]; + positions[offset + 3] = positions[3 * 6]; + positions[offset + 4] = positions[3 * 6 + 1]; + positions[offset + 5] = positions[3 * 6 + 2]; + positions[offset + 6] = positions[3 * 7]; + positions[offset + 7] = positions[3 * 7 + 1]; + positions[offset + 8] = positions[3 * 7 + 2]; + positions[offset + 9] = positions[3 * 3]; + positions[offset + 10] = positions[3 * 3 + 1]; + positions[offset + 11] = positions[3 * 3 + 2]; + + var attributes = new GeometryAttributes({ + position : new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positions + }) + }); + + if (defined(vertexFormat.normal) || defined(vertexFormat.tangent) || defined(vertexFormat.bitangent) || defined(vertexFormat.st)) { + var normals = defined(vertexFormat.normal) ? new Float32Array(3 * 4 * 6) : undefined; + var tangents = defined(vertexFormat.tangent) ? new Float32Array(3 * 4 * 6) : undefined; + var bitangents = defined(vertexFormat.bitangent) ? new Float32Array(3 * 4 * 6) : undefined; + var st = defined(vertexFormat.st) ? new Float32Array(2 * 4 * 6) : undefined; + + var negativeX = Cartesian3.negate(x, scratchNegativeX); + var negativeY = Cartesian3.negate(y, scratchNegativeY); + var negativeZ = Cartesian3.negate(z, scratchNegativeZ); + + getAttributes(0, normals, tangents, bitangents, st, negativeZ, x, y); // near + getAttributes(3 * 4, normals, tangents, bitangents, st, z, negativeX, y); // far + getAttributes(3 * 4 * 2, normals, tangents, bitangents, st, negativeX, negativeZ, y); // -x + getAttributes(3 * 4 * 3, normals, tangents, bitangents, st, negativeY, negativeZ, negativeX); // -y + getAttributes(3 * 4 * 4, normals, tangents, bitangents, st, x, z, y); // +x + getAttributes(3 * 4 * 5, normals, tangents, bitangents, st, y, z, negativeX); // +y + + if (defined(normals)) { + attributes.normal = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : normals + }); + } + if (defined(tangents)) { + attributes.tangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : tangents + }); + } + if (defined(bitangents)) { + attributes.bitangent = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 3, + values : bitangents + }); + } + if (defined(st)) { + attributes.st = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 2, + values : st + }); + } + } + + var indices = new Uint16Array(6 * 6); + for (i = 0; i < 6; ++i) { + var indexOffset = i * 6; + var index = i * 4; + + indices[indexOffset] = index; + indices[indexOffset + 1] = index + 1; + indices[indexOffset + 2] = index + 2; + indices[indexOffset + 3] = index; + indices[indexOffset + 4] = index + 2; + indices[indexOffset + 5] = index + 3; + } + + return new Geometry({ + attributes : attributes, + indices : indices, + primitiveType : PrimitiveType.TRIANGLES, + boundingSphere : BoundingSphere.fromVertices(positions) + }); + }; + + return FrustumGeometry; +}); diff --git a/Source/Core/OrthographicFrustum.js b/Source/Core/OrthographicFrustum.js index 0c661db836f6..c4739c4b71ca 100644 --- a/Source/Core/OrthographicFrustum.js +++ b/Source/Core/OrthographicFrustum.js @@ -1,9 +1,13 @@ define([ + './Check', + './defaultValue', './defined', './defineProperties', './DeveloperError', './OrthographicOffCenterFrustum' ], function( + Check, + defaultValue, defined, defineProperties, DeveloperError, @@ -62,6 +66,43 @@ define([ this._far = this.far; } + OrthographicFrustum.packedLength = 4; + + OrthographicFrustum.pack = function(value, array, startingIndex) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object('value', value); + Check.defined('array', array); + //>>includeEnd('debug'); + + startingIndex = defaultValue(startingIndex, 0); + + array[startingIndex++] = value.width; + array[startingIndex++] = value.aspectRatio; + array[startingIndex++] = value.near; + array[startingIndex] = value.far; + + return array; + }; + + OrthographicFrustum.unpack = function(array, startingIndex, result) { + //>>includeStart('debug', pragmas.debug); + Check.defined('array', array); + //>>includeEnd('debug'); + + startingIndex = defaultValue(startingIndex, 0); + + if (!defined(result)) { + result = new OrthographicFrustum(); + } + + result.width = array[startingIndex++]; + result.aspectRatio = array[startingIndex++]; + result.near = array[startingIndex++]; + result.far = array[startingIndex]; + + return result; + }; + function update(frustum) { //>>includeStart('debug', pragmas.debug); if (!defined(frustum.width) || !defined(frustum.aspectRatio) || !defined(frustum.near) || !defined(frustum.far)) { diff --git a/Source/Core/PerspectiveFrustum.js b/Source/Core/PerspectiveFrustum.js index b09c1f2d4da6..0701f82cec67 100644 --- a/Source/Core/PerspectiveFrustum.js +++ b/Source/Core/PerspectiveFrustum.js @@ -1,9 +1,13 @@ define([ + './Check', + './defaultValue', './defined', './defineProperties', './DeveloperError', './PerspectiveOffCenterFrustum' ], function( + Check, + defaultValue, defined, defineProperties, DeveloperError, @@ -86,6 +90,47 @@ define([ this._yOffset = this.yOffset; } + PerspectiveFrustum.packedLength = 6; + + PerspectiveFrustum.pack = function(value, array, startingIndex) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object('value', value); + Check.defined('array', array); + //>>includeEnd('debug'); + + startingIndex = defaultValue(startingIndex, 0); + + array[startingIndex++] = value.fov; + array[startingIndex++] = value.aspectRatio; + array[startingIndex++] = value.near; + array[startingIndex++] = value.far; + array[startingIndex++] = value.xOffset; + array[startingIndex] = value.yOffset; + + return array; + }; + + PerspectiveFrustum.unpack = function(array, startingIndex, result) { + //>>includeStart('debug', pragmas.debug); + Check.defined('array', array); + //>>includeEnd('debug'); + + startingIndex = defaultValue(startingIndex, 0); + + if (!defined(result)) { + result = new PerspectiveFrustum(); + } + + result.fov = array[startingIndex++]; + result.aspectRatio = array[startingIndex++]; + result.near = array[startingIndex++]; + result.far = array[startingIndex++]; + result.xOffset = array[startingIndex++]; + result.yOffset = array[startingIndex]; + + return result; + }; + function update(frustum) { //>>includeStart('debug', pragmas.debug); if (!defined(frustum.fov) || !defined(frustum.aspectRatio) || !defined(frustum.near) || !defined(frustum.far)) { diff --git a/Source/Scene/DebugCameraPrimitive.js b/Source/Scene/DebugCameraPrimitive.js index 32a8b5681362..d0b402883dd7 100644 --- a/Source/Scene/DebugCameraPrimitive.js +++ b/Source/Scene/DebugCameraPrimitive.js @@ -191,7 +191,7 @@ define([ } } - var boundingSphere = new BoundingSphere.fromVertices(positions); + var boundingSphere = BoundingSphere.fromVertices(positions); var attributes = new GeometryAttributes(); attributes.position = new GeometryAttribute({ diff --git a/Source/Workers/createFrustumGeometry.js b/Source/Workers/createFrustumGeometry.js new file mode 100644 index 000000000000..3f1c141e6896 --- /dev/null +++ b/Source/Workers/createFrustumGeometry.js @@ -0,0 +1,17 @@ +define([ + '../Core/defined', + '../Core/FrustumGeometry' + ], function( + defined, + FrustumGeometry) { + 'use strict'; + + function createFrustumGeometry(frustumGeometry, offset) { + if (defined(offset)) { + frustumGeometry = FrustumGeometry.unpack(frustumGeometry, offset); + } + return FrustumGeometry.createGeometry(frustumGeometry); + } + + return createFrustumGeometry; +}); From 7a44bfbdb71a99903fa80f7533064f612e78c609 Mon Sep 17 00:00:00 2001 From: Heiko Thiel Date: Mon, 17 Jul 2017 23:21:53 +0200 Subject: [PATCH 084/132] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 1c038dc5ea5e..d856b94769e2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ Change Log * Added ability to show tile urls in the 3D Tiles Inspector. [#5592](https://github.com/AnalyticalGraphicsInc/cesium/pull/5592) * Added behavior to `Cesium3DTilesInspector` that selects the first tileset hovered over if no tilest is specified. [#5139](https://github.com/AnalyticalGraphicsInc/cesium/issues/5139) * Added ability to provide a `width` and `height` to `scene.pick`. [#5602](https://github.com/AnalyticalGraphicsInc/cesium/pull/5602) +* Added ability to set a style's `color`, `show`, or `pointSize` with a string or object literal. `show` may also take a boolean and `pointSize` may take a number. [#5412](https://github.com/AnalyticalGraphicsInc/cesium/pull/5412) * Fixed crash when using the `Cesium3DTilesInspectorViewModel` and removing a tileset [#5607](https://github.com/AnalyticalGraphicsInc/cesium/issues/5607) ### 1.35.2 - 2017-07-11 From 100ade667b0c1504a4e061d856ef7b0eb82d4cf6 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 17 Jul 2017 19:26:48 -0400 Subject: [PATCH 085/132] Add frustum outline geometry. --- Source/Core/FrustumOutlineGeometry.js | 332 ++++++++++++++++++ .../Workers/createFrustumOutlineGeometry.js | 17 + 2 files changed, 349 insertions(+) create mode 100644 Source/Core/FrustumOutlineGeometry.js create mode 100644 Source/Workers/createFrustumOutlineGeometry.js diff --git a/Source/Core/FrustumOutlineGeometry.js b/Source/Core/FrustumOutlineGeometry.js new file mode 100644 index 000000000000..b3e4ead0b803 --- /dev/null +++ b/Source/Core/FrustumOutlineGeometry.js @@ -0,0 +1,332 @@ +define([ + './BoundingSphere', + './Cartesian3', + './Cartesian4', + './Check', + './ComponentDatatype', + './defaultValue', + './defined', + './Geometry', + './GeometryAttribute', + './GeometryAttributes', + './Matrix3', + './Matrix4', + './OrthographicFrustum', + './PerspectiveFrustum', + './PrimitiveType', + './Quaternion' + ], function( + BoundingSphere, + Cartesian3, + Cartesian4, + Check, + ComponentDatatype, + defaultValue, + defined, + Geometry, + GeometryAttribute, + GeometryAttributes, + Matrix3, + Matrix4, + OrthographicFrustum, + PerspectiveFrustum, + PrimitiveType, + Quaternion) { + 'use strict'; + + var PERSPECTIVE = 0; + var ORTHOGRAPHIC = 1; + + /** + * A description of the outline of a frustum with the given position and orientation. + * + * @alias FrustumOutlineGeometry + * @constructor + * + * @param {Object} options Object with the following properties: + * @param {PerspectiveFrustum|OrthographicFrustum} options.frustum The frustum. + * @param {Cartesian3} options.position The position of the frustum. + * @param {Quaternion} options.orientation The orientation of the frustum. + */ + function FrustumOutlineGeometry(options) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object('options', options); + Check.typeOf.object('options.frustum', options.frustum); + Check.typeOf.object('options.position', options.position); + Check.typeOf.object('options.orientation', options.orientation); + //>>includeEnd('debug'); + + var frustum = options.frustum; + var orientation = options.orientation; + var position = options.position; + + var frustumType; + var frustumPackedLength; + if (frustum instanceof PerspectiveFrustum) { + frustumType = PERSPECTIVE; + frustumPackedLength = PerspectiveFrustum.packedLength; + } else if (frustum instanceof OrthographicFrustum) { + frustumType = ORTHOGRAPHIC; + frustumPackedLength = OrthographicFrustum.packedLength; + } + + this._frustumType = frustumType; + this._frustum = frustum.clone(); + this._position = Cartesian3.clone(position); + this._orientation = Quaternion.clone(orientation); + this._workerName = 'createFrustumOutlineGeometry'; + + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ + this.packedLength = 1 + frustumPackedLength + Cartesian3.packedLength + Quaternion.packedLength; + } + + /** + * Stores the provided instance into the provided array. + * + * @param {FrustumOutlineGeometry} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ + FrustumOutlineGeometry.pack = function(value, array, startingIndex) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object('value', value); + Check.defined('array', array); + //>>includeEnd('debug'); + + startingIndex = defaultValue(startingIndex, 0); + + var frustumType = value._frustumType; + var frustum = value._frustum; + + array[startingIndex++] = frustumType; + + if (frustumType === PERSPECTIVE) { + PerspectiveFrustum.pack(frustum, array, startingIndex); + startingIndex += PerspectiveFrustum.packedLength; + } else { + OrthographicFrustum.pack(frustum, array, startingIndex); + startingIndex += OrthographicFrustum.packedLength; + } + + Cartesian3.pack(value._position, array, startingIndex); + startingIndex += Cartesian3.packedLength; + Quaternion.pack(value._orientation, array, startingIndex); + + return array; + }; + + var scratchPackPerspective = new PerspectiveFrustum(); + var scratchPackOrthographic = new OrthographicFrustum(); + var scratchPackQuaternion = new Quaternion(); + var scratchPackPosition = new Cartesian3(); + + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {FrustumOutlineGeometry} [result] The object into which to store the result. + */ + FrustumOutlineGeometry.unpack = function(array, startingIndex, result) { + //>>includeStart('debug', pragmas.debug); + Check.defined('array', array); + //>>includeEnd('debug'); + + startingIndex = defaultValue(startingIndex, 0); + + var frustumType = array[startingIndex++]; + + var frustum; + if (frustumType === PERSPECTIVE) { + frustum = PerspectiveFrustum.unpack(array, startingIndex, scratchPackPerspective); + startingIndex += PerspectiveFrustum.packedLength; + } else { + frustum = OrthographicFrustum.unpack(array, startingIndex, scratchPackOrthographic); + startingIndex += OrthographicFrustum.packedLength; + } + + var position = Cartesian3.unpack(array, startingIndex, scratchPackPosition); + startingIndex += Cartesian3.packedLength; + var orientation = Quaternion.unpack(array, startingIndex, scratchPackQuaternion); + + if (!defined(result)) { + return new FrustumOutlineGeometry({ + frustum : frustum, + position : position, + orientation : orientation + }); + } + + var frustumResult = frustumType === result._frustumType ? result._frustum : undefined; + result._frustum = frustum.clone(frustumResult); + + result._frustumType = frustumType; + result._position = Cartesian3.clone(position, result._position); + result._orientation = Quaternion.clone(orientation, result._orientation); + + return result; + }; + + var scratchRotationMatrix = new Matrix3(); + var scratchViewMatrix = new Matrix4(); + var scratchInverseMatrix = new Matrix4(); + + var scratchXDirection = new Cartesian3(); + var scratchYDirection = new Cartesian3(); + var scratchZDirection = new Cartesian3(); + var scratchNegativeX = new Cartesian3(); + var scratchNegativeY = new Cartesian3(); + var scratchNegativeZ = new Cartesian3(); + + var frustumSplits = new Array(3); + + var frustumCornersNDC = new Array(4); + frustumCornersNDC[0] = new Cartesian4(-1.0, -1.0, 1.0, 1.0); + frustumCornersNDC[1] = new Cartesian4(1.0, -1.0, 1.0, 1.0); + frustumCornersNDC[2] = new Cartesian4(1.0, 1.0, 1.0, 1.0); + frustumCornersNDC[3] = new Cartesian4(-1.0, 1.0, 1.0, 1.0); + + var scratchFrustumCorners = new Array(4); + for (var i = 0; i < 4; ++i) { + scratchFrustumCorners[i] = new Cartesian4(); + } + + /** + * Computes the geometric representation of a frustum outline, including its vertices, indices, and a bounding sphere. + * + * @param {FrustumOutlineGeometry} frustumGeometry A description of the frustum. + * @returns {Geometry|undefined} The computed vertices and indices. + */ + FrustumOutlineGeometry.createGeometry = function(frustumGeometry) { + var frustumType = frustumGeometry._frustumType; + var frustum = frustumGeometry._frustum; + var position = frustumGeometry._position; + var orientation = frustumGeometry._orientation; + + var rotationMatrix = Matrix3.fromQuaternion(orientation, scratchRotationMatrix); + var x = Matrix3.getColumn(rotationMatrix, 0, scratchXDirection); + var y = Matrix3.getColumn(rotationMatrix, 1, scratchYDirection); + var z = Matrix3.getColumn(rotationMatrix, 2, scratchZDirection); + + Cartesian3.normalize(x, x); + Cartesian3.normalize(y, y); + Cartesian3.normalize(z, z); + + Cartesian3.negate(x, x); + + var view = Matrix4.computeView(position, z, y, x, scratchViewMatrix); + + var inverseView; + var inverseViewProjection; + if (frustumType === PERSPECTIVE) { + var projection = frustum.projectionMatrix; + var viewProjection = Matrix4.multiply(projection, view, scratchInverseMatrix); + inverseViewProjection = Matrix4.inverse(viewProjection, scratchInverseMatrix); + } else { + inverseView = Matrix4.inverseTransformation(view, scratchInverseMatrix); + } + + frustumSplits[0] = frustum.near; + frustumSplits[1] = frustum.far; + frustumSplits[2] = frustum.far + 1.0; + + var i; + var positions = new Float64Array(3 * 4 * 2); + + for (i = 0; i < 2; ++i) { + for (var j = 0; j < 4; ++j) { + var corner = Cartesian4.clone(frustumCornersNDC[j], scratchFrustumCorners[j]); + + if (!defined(inverseViewProjection)) { + if (defined(frustum._offCenterFrustum)) { + frustum = frustum._offCenterFrustum; + } + + var near = frustumSplits[i]; + var far = frustumSplits[i + 1]; + + corner.x = (corner.x * (frustum.right - frustum.left) + frustum.left + frustum.right) * 0.5; + corner.y = (corner.y * (frustum.top - frustum.bottom) + frustum.bottom + frustum.top) * 0.5; + corner.z = (corner.z * (near - far) - near - far) * 0.5; + corner.w = 1.0; + + Matrix4.multiplyByVector(inverseView, corner, corner); + } else { + corner = Matrix4.multiplyByVector(inverseViewProjection, corner, corner); + + // Reverse perspective divide + var w = 1.0 / corner.w; + Cartesian3.multiplyByScalar(corner, w, corner); + + Cartesian3.subtract(corner, position, corner); + Cartesian3.normalize(corner, corner); + + var fac = Cartesian3.dot(z, corner); + Cartesian3.multiplyByScalar(corner, frustumSplits[i] / fac, corner); + Cartesian3.add(corner, position, corner); + } + + positions[12 * i + j * 3] = corner.x; + positions[12 * i + j * 3 + 1] = corner.y; + positions[12 * i + j * 3 + 2] = corner.z; + } + } + + var attributes = new GeometryAttributes({ + position : new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : positions + }) + }); + + var offset; + var index; + + var indices = new Uint16Array(8 * (2 + 1)); + + // Build the near/far planes + for (i = 0; i < 2; ++i) { + offset = i * 8; + index = i * 4; + + indices[offset] = index; + indices[offset + 1] = index + 1; + indices[offset + 2] = index + 1; + indices[offset + 3] = index + 2; + indices[offset + 4] = index + 2; + indices[offset + 5] = index + 3; + indices[offset + 6] = index + 3; + indices[offset + 7] = index; + } + + // Build the sides of the frustums + for (i = 0; i < 2; ++i) { + offset = (2 + i) * 8; + index = i * 4; + + indices[offset] = index; + indices[offset + 1] = index + 4; + indices[offset + 2] = index + 1; + indices[offset + 3] = index + 5; + indices[offset + 4] = index + 2; + indices[offset + 5] = index + 6; + indices[offset + 6] = index + 3; + indices[offset + 7] = index + 7; + } + + return new Geometry({ + attributes : attributes, + indices : indices, + primitiveType : PrimitiveType.LINES, + boundingSphere : BoundingSphere.fromVertices(positions) + }); + }; + + return FrustumOutlineGeometry; +}); diff --git a/Source/Workers/createFrustumOutlineGeometry.js b/Source/Workers/createFrustumOutlineGeometry.js new file mode 100644 index 000000000000..59f604697e27 --- /dev/null +++ b/Source/Workers/createFrustumOutlineGeometry.js @@ -0,0 +1,17 @@ +define([ + '../Core/defined', + '../Core/FrustumOutlineGeometry' +], function( + defined, + FrustumOutlineGeometry) { + 'use strict'; + + function createFrustumOutlineGeometry(frustumGeometry, offset) { + if (defined(offset)) { + frustumGeometry = FrustumOutlineGeometry.unpack(frustumGeometry, offset); + } + return FrustumOutlineGeometry.createGeometry(frustumGeometry); + } + + return createFrustumOutlineGeometry; +}); From 987ab4eab32ed25b7cc45f5fe6f41a9c9b62576c Mon Sep 17 00:00:00 2001 From: Rachel Hwang Date: Tue, 18 Jul 2017 03:34:57 -0400 Subject: [PATCH 086/132] fix docs --- CHANGES.md | 3 +-- Source/DataSources/Entity.js | 8 ++++++-- Specs/DataSources/EntitySpec.js | 7 +++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 793ec858449e..d4aaa0edee67 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,10 +5,9 @@ Change Log * Fixed a bug where a Model's compressed textures were not being displayed. [#5596](https://github.com/AnalyticalGraphicsInc/cesium/pull/5596) * Fixed a bug where jsep was undefined when using webpack [#5593](https://github.com/AnalyticalGraphicsInc/cesium/issues/5593) -* Make Entity mode matrix public via computeModelMatrix(). [#5584](https://github.com/AnalyticalGraphicsInc/cesium/pull/5584) +* Added Entity.computeModelMatrix which returns the model matrix representing the entity's transformation. [#5584](https://github.com/AnalyticalGraphicsInc/cesium/pull/5584) ### 1.35 - 2017-07-05 - * Breaking changes * `JulianDate.fromIso8601` will default to midnight UTC if no time is provided to match the Javascript [`Date` specification](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date). You must specify a local time of midnight to achieve the old behavior. * Deprecated diff --git a/Source/DataSources/Entity.js b/Source/DataSources/Entity.js index d5fcae72d21d..42c634f3b1b5 100644 --- a/Source/DataSources/Entity.js +++ b/Source/DataSources/Entity.js @@ -1,5 +1,6 @@ define([ '../Core/Cartesian3', + '../Core/Check', '../Core/createGuid', '../Core/defaultValue', '../Core/defined', @@ -32,6 +33,7 @@ define([ './WallGraphics' ], function( Cartesian3, + Check, createGuid, defaultValue, defined, @@ -581,14 +583,16 @@ define([ var orientationScratch = new Quaternion(); /** - * Computes the model matrix for the entity's transform at specified time. + * Computes the model matrix for the entity's transform at specified time. Returns undefined if orientation or position + * are undefined. * * @param {JulianDate} time The time to retrieve model matrix for. * @param {Matrix4} [result] The object onto which to store the result. * - * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. + * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. Result is undefined if position or orientation are undefined. */ Entity.prototype.computeModelMatrix = function(time, result) { + Check.typeOf.object('time', time); var position = Property.getValueOrUndefined(this._position, time, positionScratch); if (!defined(position)) { return undefined; diff --git a/Specs/DataSources/EntitySpec.js b/Specs/DataSources/EntitySpec.js index 14a76ee790fb..5a4a4eb4738a 100644 --- a/Specs/DataSources/EntitySpec.js +++ b/Specs/DataSources/EntitySpec.js @@ -241,6 +241,13 @@ defineSuite([ }).toThrowDeveloperError(); }); + it('computeModelMatrix throws if no time specified.', function() { + var entity = new Entity(); + expect(function() { + entity.computeModelMatrix(); + }).toThrowDeveloperError(); + }); + it('computeModelMatrix returns undefined when position is undefined.', function() { var entity = new Entity(); entity.orientation = new ConstantProperty(Quaternion.IDENTITY); From 70dfbdb1467ecc6345dd3f1028b4799bf744446b Mon Sep 17 00:00:00 2001 From: hpinkos Date: Tue, 18 Jul 2017 10:15:03 -0400 Subject: [PATCH 087/132] Fix typo on polygon demo --- Apps/Sandcastle/gallery/Polygon.html | 2 +- CHANGES.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Apps/Sandcastle/gallery/Polygon.html b/Apps/Sandcastle/gallery/Polygon.html index f1c86edafe76..56e7e95d5c3f 100644 --- a/Apps/Sandcastle/gallery/Polygon.html +++ b/Apps/Sandcastle/gallery/Polygon.html @@ -103,7 +103,7 @@ }] }, material : Cesium.Color.BLUE.withAlpha(0.5), - heigth : 0, + height : 0, outline : true // height is required for outline to display } }); diff --git a/CHANGES.md b/CHANGES.md index 78c2296e6f11..12032288b1ae 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -18,6 +18,7 @@ Change Log * Added ability to provide a `width` and `height` to `scene.pick`. [#5602](https://github.com/AnalyticalGraphicsInc/cesium/pull/5602) * Fixed issue where scene would blink when labels were added. [#5537](https://github.com/AnalyticalGraphicsInc/cesium/issues/5537) * Fixed crash when using the `Cesium3DTilesInspectorViewModel` and removing a tileset [#5607](https://github.com/AnalyticalGraphicsInc/cesium/issues/5607) +* Fixed polygon outline in Polygon Sandcastle demo [#5642](https://github.com/AnalyticalGraphicsInc/cesium/issues/5642) ### 1.35.2 - 2017-07-11 From e35d6ca8f5a1d956c13761d7ae792262656b9946 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Tue, 18 Jul 2017 10:19:14 -0400 Subject: [PATCH 088/132] CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 78c2296e6f11..fd95268a3a6e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,7 @@ Change Log * Added behavior to `Cesium3DTilesInspector` that selects the first tileset hovered over if no tilest is specified. [#5139](https://github.com/AnalyticalGraphicsInc/cesium/issues/5139) * Added ability to provide a `width` and `height` to `scene.pick`. [#5602](https://github.com/AnalyticalGraphicsInc/cesium/pull/5602) * Fixed issue where scene would blink when labels were added. [#5537](https://github.com/AnalyticalGraphicsInc/cesium/issues/5537) +* Fixed label positioning when height reference changes [#5609](https://github.com/AnalyticalGraphicsInc/cesium/issues/5609) * Fixed crash when using the `Cesium3DTilesInspectorViewModel` and removing a tileset [#5607](https://github.com/AnalyticalGraphicsInc/cesium/issues/5607) ### 1.35.2 - 2017-07-11 From 00d8eaba1d7eb7825de335f9aa6678ff1a1d60d1 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Tue, 18 Jul 2017 10:29:50 -0400 Subject: [PATCH 089/132] Renames variable "number" and also saves splitSource.length --- Source/Renderer/modernizeShader.js | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/Source/Renderer/modernizeShader.js b/Source/Renderer/modernizeShader.js index ba649428cb95..8e2a67623c95 100644 --- a/Source/Renderer/modernizeShader.js +++ b/Source/Renderer/modernizeShader.js @@ -12,24 +12,28 @@ define([ var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; var regex = new RegExp(regexStr, 'g'); - for (var number = 0; number < splitSource.length; ++number) { - var line = splitSource[number]; - splitSource[number] = line.replace(regex, '$1' + replacement + '$3'); + var splitSourceLength = splitSource.length; + for (var i = 0; i < splitSourceLength; ++i) { + var line = splitSource[i]; + splitSource[i] = line.replace(regex, '$1' + replacement + '$3'); } } function replaceInSourceRegex(regex, replacement, splitSource) { - for (var number = 0; number < splitSource.length; ++number) { - var line = splitSource[number]; - splitSource[number] = line.replace(regex, replacement); + var splitSourceLength = splitSource.length; + for (var i = 0; i < splitSourceLength; ++i) { + var line = splitSource[i]; + splitSource[i] = line.replace(regex, replacement); } } function findInSource(str, splitSource) { var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; var regex = new RegExp(regexStr, 'g'); - for (var number = 0; number < splitSource.length; ++number) { - var line = splitSource[number]; + + var splitSourceLength = splitSource.length; + for (var i = 0; i < splitSourceLength; ++i) { + var line = splitSource[i]; if (regex.test(line)) { return true; } @@ -39,8 +43,10 @@ define([ function compileSource(splitSource) { var wholeSource = ''; - for (var number = 0; number < splitSource.length; ++number) { - wholeSource += splitSource[number] + '\n'; + + var splitSourceLength = splitSource.length; + for (var i = 0; i < splitSourceLength; ++i) { + wholeSource += splitSource[i] + '\n'; } return wholeSource; } From c0957a97e1850b9b9cf2d31424c91602ebd9c1a3 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Tue, 18 Jul 2017 10:48:49 -0400 Subject: [PATCH 090/132] Renames set1 to set --- Source/Renderer/modernizeShader.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Renderer/modernizeShader.js b/Source/Renderer/modernizeShader.js index 8e2a67623c95..764f2fcd876d 100644 --- a/Source/Renderer/modernizeShader.js +++ b/Source/Renderer/modernizeShader.js @@ -51,9 +51,9 @@ define([ return wholeSource; } - function setAdd(variable, set1) { - if (set1.indexOf(variable) === -1) { - set1.push(variable); + function setAdd(variable, set) { + if (set.indexOf(variable) === -1) { + set.push(variable); } } From 6b34b077b6ff3e1b1cf5a55a44a98b855f73e94c Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Tue, 18 Jul 2017 10:50:06 -0400 Subject: [PATCH 091/132] Moves modernizeShader to the top of the file --- Source/Renderer/modernizeShader.js | 222 ++++++++++++++--------------- 1 file changed, 111 insertions(+), 111 deletions(-) diff --git a/Source/Renderer/modernizeShader.js b/Source/Renderer/modernizeShader.js index 764f2fcd876d..4a5dd91fec22 100644 --- a/Source/Renderer/modernizeShader.js +++ b/Source/Renderer/modernizeShader.js @@ -6,117 +6,6 @@ define([ DeveloperError) { 'use strict'; - // Note that this fails if your string looks like - // searchString[singleCharacter]searchString - function replaceInSourceString(str, replacement, splitSource) { - var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; - var regex = new RegExp(regexStr, 'g'); - - var splitSourceLength = splitSource.length; - for (var i = 0; i < splitSourceLength; ++i) { - var line = splitSource[i]; - splitSource[i] = line.replace(regex, '$1' + replacement + '$3'); - } - } - - function replaceInSourceRegex(regex, replacement, splitSource) { - var splitSourceLength = splitSource.length; - for (var i = 0; i < splitSourceLength; ++i) { - var line = splitSource[i]; - splitSource[i] = line.replace(regex, replacement); - } - } - - function findInSource(str, splitSource) { - var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; - var regex = new RegExp(regexStr, 'g'); - - var splitSourceLength = splitSource.length; - for (var i = 0; i < splitSourceLength; ++i) { - var line = splitSource[i]; - if (regex.test(line)) { - return true; - } - } - return false; - } - - function compileSource(splitSource) { - var wholeSource = ''; - - var splitSourceLength = splitSource.length; - for (var i = 0; i < splitSourceLength; ++i) { - wholeSource += splitSource[i] + '\n'; - } - return wholeSource; - } - - function setAdd(variable, set) { - if (set.indexOf(variable) === -1) { - set.push(variable); - } - } - - function getVariablePreprocessorBranch(layoutVariables, splitSource) { - var variableMap = {}; - - var numLayoutVariables = layoutVariables.length; - for (var a = 0; a < numLayoutVariables; ++a) { - var variableThatWeCareAbout = layoutVariables[a]; - variableMap[variableThatWeCareAbout] = [null]; - } - - var stack = []; - for (var i = 0; i < splitSource.length; ++i) { - var line = splitSource[i]; - var hasIF = /(#ifdef|#if)/g.test(line); - var hasELSE = /#else/g.test(line); - var hasENDIF = /#endif/g.test(line); - - if (hasIF) { - stack.push(line); - } else if (hasELSE) { - var top = stack[stack.length - 1]; - var op = top.replace('ifdef', 'ifndef'); - if (/if/g.test(op)) { - op = op.replace(/(#if\s+)(\S*)([^]*)/, '$1!($2)$3'); - } - stack.pop(); - stack.push(op); - } else if (hasENDIF) { - stack.pop(); - } else if (!/layout/g.test(line)) { - for (var varIndex = 0; varIndex < numLayoutVariables; ++varIndex) { - var varName = layoutVariables[varIndex]; - if (line.indexOf(varName) !== -1) { - if (variableMap[varName].length === 1 && variableMap[varName][0] === null) { - variableMap[varName] = stack.slice(); - } else { - variableMap[varName] = variableMap[varName].filter(function(x) { - return stack.indexOf(x) >= 0; - }); - } - } - } - } - } - - for (var care in variableMap) { - if (variableMap.hasOwnProperty(care)) { - if (variableMap.length === 1 && variableMap[0] === null) { - variableMap.splice(0, 1); - } - } - } - - return variableMap; - } - - function removeExtension(name, splitSource) { - var regex = '#extension\\s+GL_' + name + '\\s+:\\s+[a-zA-Z0-9]+\\s*$'; - replaceInSourceRegex(new RegExp(regex, 'g'), '', splitSource); - } - /** * A function to port GLSL shaders from GLSL ES 1.00 to GLSL ES 3.00 * @@ -235,5 +124,116 @@ define([ return compileSource(splitSource); } + // Note that this fails if your string looks like + // searchString[singleCharacter]searchString + function replaceInSourceString(str, replacement, splitSource) { + var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; + var regex = new RegExp(regexStr, 'g'); + + var splitSourceLength = splitSource.length; + for (var i = 0; i < splitSourceLength; ++i) { + var line = splitSource[i]; + splitSource[i] = line.replace(regex, '$1' + replacement + '$3'); + } + } + + function replaceInSourceRegex(regex, replacement, splitSource) { + var splitSourceLength = splitSource.length; + for (var i = 0; i < splitSourceLength; ++i) { + var line = splitSource[i]; + splitSource[i] = line.replace(regex, replacement); + } + } + + function findInSource(str, splitSource) { + var regexStr = '(^|[^\\w])(' + str + ')($|[^\\w])'; + var regex = new RegExp(regexStr, 'g'); + + var splitSourceLength = splitSource.length; + for (var i = 0; i < splitSourceLength; ++i) { + var line = splitSource[i]; + if (regex.test(line)) { + return true; + } + } + return false; + } + + function compileSource(splitSource) { + var wholeSource = ''; + + var splitSourceLength = splitSource.length; + for (var i = 0; i < splitSourceLength; ++i) { + wholeSource += splitSource[i] + '\n'; + } + return wholeSource; + } + + function setAdd(variable, set) { + if (set.indexOf(variable) === -1) { + set.push(variable); + } + } + + function getVariablePreprocessorBranch(layoutVariables, splitSource) { + var variableMap = {}; + + var numLayoutVariables = layoutVariables.length; + for (var a = 0; a < numLayoutVariables; ++a) { + var variableThatWeCareAbout = layoutVariables[a]; + variableMap[variableThatWeCareAbout] = [null]; + } + + var stack = []; + for (var i = 0; i < splitSource.length; ++i) { + var line = splitSource[i]; + var hasIF = /(#ifdef|#if)/g.test(line); + var hasELSE = /#else/g.test(line); + var hasENDIF = /#endif/g.test(line); + + if (hasIF) { + stack.push(line); + } else if (hasELSE) { + var top = stack[stack.length - 1]; + var op = top.replace('ifdef', 'ifndef'); + if (/if/g.test(op)) { + op = op.replace(/(#if\s+)(\S*)([^]*)/, '$1!($2)$3'); + } + stack.pop(); + stack.push(op); + } else if (hasENDIF) { + stack.pop(); + } else if (!/layout/g.test(line)) { + for (var varIndex = 0; varIndex < numLayoutVariables; ++varIndex) { + var varName = layoutVariables[varIndex]; + if (line.indexOf(varName) !== -1) { + if (variableMap[varName].length === 1 && variableMap[varName][0] === null) { + variableMap[varName] = stack.slice(); + } else { + variableMap[varName] = variableMap[varName].filter(function(x) { + return stack.indexOf(x) >= 0; + }); + } + } + } + } + } + + for (var care in variableMap) { + if (variableMap.hasOwnProperty(care)) { + if (variableMap.length === 1 && variableMap[0] === null) { + variableMap.splice(0, 1); + } + } + } + + return variableMap; + } + + function removeExtension(name, splitSource) { + var regex = '#extension\\s+GL_' + name + '\\s+:\\s+[a-zA-Z0-9]+\\s*$'; + replaceInSourceRegex(new RegExp(regex, 'g'), '', splitSource); + } + return modernizeShader; }); From 7251f2ae94e96b502ab75c77740997b7b7bf8090 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Tue, 18 Jul 2017 10:59:20 -0400 Subject: [PATCH 092/132] All the counters in modernizeShader now use "i" --- Source/Renderer/modernizeShader.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Source/Renderer/modernizeShader.js b/Source/Renderer/modernizeShader.js index 4a5dd91fec22..f7ed7034b2ad 100644 --- a/Source/Renderer/modernizeShader.js +++ b/Source/Renderer/modernizeShader.js @@ -27,11 +27,11 @@ define([ } var outputDeclarationLine = -1; - var number; - for (number = 0; number < splitSource.length; ++number) { - var line = splitSource[number]; - if (outputDeclarationRegex.exec(line)) { - outputDeclarationLine = number; + var i; + for (i = 0; i < splitSource.length; ++i) { + var line = splitSource[i]; + if (outputDeclarationRegex.test(line)) { + outputDeclarationLine = i; break; } } @@ -42,7 +42,7 @@ define([ var outputVariables = []; - for (var i = 0; i < 10; i++) { + for (i = 0; i < 10; i++) { var fragDataString = 'gl_FragData\\[' + i + '\\]'; var newOutput = 'czm_out' + i; var regex = new RegExp(fragDataString, 'g'); @@ -64,8 +64,8 @@ define([ var variableMap = getVariablePreprocessorBranch(outputVariables, splitSource); var lineAdds = {}; - for (var c = 0; c < splitSource.length; c++) { - var l = splitSource[c]; + for (i = 0; i < splitSource.length; i++) { + var l = splitSource[i]; for (var care in variableMap) { if (variableMap.hasOwnProperty(care)) { var matchVar = new RegExp('(layout)[^]+(out)[^]+(' + care + ')[^]+', 'g'); @@ -95,9 +95,9 @@ define([ var versionThree = '#version 300 es'; var foundVersion = false; - for (number = 0; number < splitSource.length; number++) { - if (/#version/.test(splitSource[number])) { - splitSource[number] = versionThree; + for (i = 0; i < splitSource.length; i++) { + if (/#version/.test(splitSource[i])) { + splitSource[i] = versionThree; foundVersion = true; } } From 968a28d41e810c51103b2e011d05ae255f4a71eb Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Tue, 18 Jul 2017 11:02:40 -0400 Subject: [PATCH 093/132] Renames "l" to "line" --- Source/Renderer/modernizeShader.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Renderer/modernizeShader.js b/Source/Renderer/modernizeShader.js index f7ed7034b2ad..8aa7a1bab97f 100644 --- a/Source/Renderer/modernizeShader.js +++ b/Source/Renderer/modernizeShader.js @@ -27,9 +27,9 @@ define([ } var outputDeclarationLine = -1; - var i; + var i, line; for (i = 0; i < splitSource.length; ++i) { - var line = splitSource[i]; + line = splitSource[i]; if (outputDeclarationRegex.test(line)) { outputDeclarationLine = i; break; @@ -65,12 +65,12 @@ define([ var variableMap = getVariablePreprocessorBranch(outputVariables, splitSource); var lineAdds = {}; for (i = 0; i < splitSource.length; i++) { - var l = splitSource[i]; + line = splitSource[i]; for (var care in variableMap) { if (variableMap.hasOwnProperty(care)) { var matchVar = new RegExp('(layout)[^]+(out)[^]+(' + care + ')[^]+', 'g'); - if (matchVar.test(l)) { - lineAdds[l] = care; + if (matchVar.test(line)) { + lineAdds[line] = care; } } } From ff24d72b19c2f0300a702ba4e8306afd202340ec Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Tue, 18 Jul 2017 11:06:29 -0400 Subject: [PATCH 094/132] Renames "care" --- Source/Renderer/modernizeShader.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/Renderer/modernizeShader.js b/Source/Renderer/modernizeShader.js index 8aa7a1bab97f..b07d3b06a3e1 100644 --- a/Source/Renderer/modernizeShader.js +++ b/Source/Renderer/modernizeShader.js @@ -66,11 +66,11 @@ define([ var lineAdds = {}; for (i = 0; i < splitSource.length; i++) { line = splitSource[i]; - for (var care in variableMap) { - if (variableMap.hasOwnProperty(care)) { - var matchVar = new RegExp('(layout)[^]+(out)[^]+(' + care + ')[^]+', 'g'); + for (var variable in variableMap) { + if (variableMap.hasOwnProperty(variable)) { + var matchVar = new RegExp('(layout)[^]+(out)[^]+(' + variable + ')[^]+', 'g'); if (matchVar.test(line)) { - lineAdds[line] = care; + lineAdds[line] = variable; } } } @@ -219,8 +219,8 @@ define([ } } - for (var care in variableMap) { - if (variableMap.hasOwnProperty(care)) { + for (var variable in variableMap) { + if (variableMap.hasOwnProperty(variable)) { if (variableMap.length === 1 && variableMap[0] === null) { variableMap.splice(0, 1); } From 7a7da05e185d5391bc67b58b48de35b565d59944 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Tue, 18 Jul 2017 11:21:32 -0400 Subject: [PATCH 095/132] Cleanup of unused variables --- Source/Renderer/modernizeShader.js | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/Source/Renderer/modernizeShader.js b/Source/Renderer/modernizeShader.js index b07d3b06a3e1..b2accdf7e62a 100644 --- a/Source/Renderer/modernizeShader.js +++ b/Source/Renderer/modernizeShader.js @@ -179,10 +179,6 @@ define([ var variableMap = {}; var numLayoutVariables = layoutVariables.length; - for (var a = 0; a < numLayoutVariables; ++a) { - var variableThatWeCareAbout = layoutVariables[a]; - variableMap[variableThatWeCareAbout] = [null]; - } var stack = []; for (var i = 0; i < splitSource.length; ++i) { @@ -207,7 +203,7 @@ define([ for (var varIndex = 0; varIndex < numLayoutVariables; ++varIndex) { var varName = layoutVariables[varIndex]; if (line.indexOf(varName) !== -1) { - if (variableMap[varName].length === 1 && variableMap[varName][0] === null) { + if (!defined(variableMap[varName])) { variableMap[varName] = stack.slice(); } else { variableMap[varName] = variableMap[varName].filter(function(x) { @@ -219,14 +215,6 @@ define([ } } - for (var variable in variableMap) { - if (variableMap.hasOwnProperty(variable)) { - if (variableMap.length === 1 && variableMap[0] === null) { - variableMap.splice(0, 1); - } - } - } - return variableMap; } From a05a976d1482121eefc2cc5722fb9aac097aa203 Mon Sep 17 00:00:00 2001 From: Srinivas Kaza Date: Tue, 18 Jul 2017 14:29:07 -0400 Subject: [PATCH 096/132] Adds support for the EXT_blend_minmax extension --- Source/Renderer/Context.js | 15 +++++++++++++++ Source/Renderer/RenderState.js | 4 +++- Source/Scene/BlendEquation.js | 22 ++++++++++++++++++++-- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/Source/Renderer/Context.js b/Source/Renderer/Context.js index b92bfa2e916c..5ab984919331 100644 --- a/Source/Renderer/Context.js +++ b/Source/Renderer/Context.js @@ -269,6 +269,7 @@ define([ // Query and initialize extensions this._standardDerivatives = !!getExtension(gl, ['OES_standard_derivatives']); + this._blendMinmax = !!getExtension(gl, ['EXT_blend_minmax']); this._elementIndexUint = !!getExtension(gl, ['OES_element_index_uint']); this._depthTexture = !!getExtension(gl, ['WEBGL_depth_texture', 'WEBKIT_WEBGL_depth_texture']); this._textureFloat = !!getExtension(gl, ['OES_texture_float']); @@ -489,6 +490,20 @@ define([ } }, + /** + * true if the EXT_blend_minmax extension is supported. This + * extension extends blending capabilities by adding two new blend equations: + * the minimum or maximum color components of the source and destination colors. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link https://www.khronos.org/registry/webgl/extensions/EXT_blend_minmax/} + */ + blendMinmax : { + get : function() { + return this._blendMinmax || this._webgl2; + } + }, + /** * true if the OES_element_index_uint extension is supported. This * extension allows the use of unsigned int indices, which can improve performance by diff --git a/Source/Renderer/RenderState.js b/Source/Renderer/RenderState.js index 3b30bebbd290..07ab7633fe12 100644 --- a/Source/Renderer/RenderState.js +++ b/Source/Renderer/RenderState.js @@ -21,7 +21,9 @@ define([ function validateBlendEquation(blendEquation) { return ((blendEquation === WebGLConstants.FUNC_ADD) || (blendEquation === WebGLConstants.FUNC_SUBTRACT) || - (blendEquation === WebGLConstants.FUNC_REVERSE_SUBTRACT)); + (blendEquation === WebGLConstants.FUNC_REVERSE_SUBTRACT) || + (blendEquation === WebGLConstants.MIN) || + (blendEquation === WebGLConstants.MAX)); } function validateBlendFunction(blendFunction) { diff --git a/Source/Scene/BlendEquation.js b/Source/Scene/BlendEquation.js index 27bf019d21eb..e589beeae418 100644 --- a/Source/Scene/BlendEquation.js +++ b/Source/Scene/BlendEquation.js @@ -34,9 +34,27 @@ define([ * @type {Number} * @constant */ - REVERSE_SUBTRACT : WebGLConstants.FUNC_REVERSE_SUBTRACT + REVERSE_SUBTRACT : WebGLConstants.FUNC_REVERSE_SUBTRACT, - // No min and max like in ColladaFX GLES2 profile + /** + * Pixel values are given to the minimum function (min(source, destination)). + * + * This equation operates on each pixel color component. + * + * @type {Number} + * @constant + */ + MIN : WebGLConstants.MIN, + + /** + * Pixel values are given to the maximum function (max(source, destination)). + * + * This equation operates on each pixel color component. + * + * @type {Number} + * @constant + */ + MAX : WebGLConstants.MAX }; return freezeObject(BlendEquation); From 72da8cae81509123b10a4c80c3f387503d55cd62 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Tue, 18 Jul 2017 15:31:01 -0400 Subject: [PATCH 097/132] clear clamp to ground callback --- Source/Scene/LabelCollection.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/Scene/LabelCollection.js b/Source/Scene/LabelCollection.js index c93803a6c255..efb9f4fd11b0 100644 --- a/Source/Scene/LabelCollection.js +++ b/Source/Scene/LabelCollection.js @@ -106,6 +106,10 @@ define([ if (defined(billboard)) { billboard.show = false; billboard.image = undefined; + if (defined(billboard._removeCallbackFunc)) { + billboard._removeCallbackFunc(); + billboard._removeCallbackFunc = undefined; + } labelCollection._spareBillboards.push(billboard); glyph.billboard = undefined; } From 8fb7df9859b287c5bd927ea229652c114b8f9687 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Tue, 18 Jul 2017 15:42:47 -0400 Subject: [PATCH 098/132] specs, CHANGES.md --- CHANGES.md | 1 + Specs/Scene/LabelCollectionSpec.js | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index e06889b90fa6..547dfc0ca0b5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -20,6 +20,7 @@ Change Log * Fixed label positioning when height reference changes [#5609](https://github.com/AnalyticalGraphicsInc/cesium/issues/5609) * Fixed crash when using the `Cesium3DTilesInspectorViewModel` and removing a tileset [#5607](https://github.com/AnalyticalGraphicsInc/cesium/issues/5607) * Fixed polygon outline in Polygon Sandcastle demo [#5642](https://github.com/AnalyticalGraphicsInc/cesium/issues/5642) +* Fixed label positioning when using `HeightReference.CLAMP_TO_GROUND` and no position [#5648](https://github.com/AnalyticalGraphicsInc/cesium/pull/5648) ### 1.35.2 - 2017-07-11 diff --git a/Specs/Scene/LabelCollectionSpec.js b/Specs/Scene/LabelCollectionSpec.js index 01d0a0e9f67e..2f999ca1ea9d 100644 --- a/Specs/Scene/LabelCollectionSpec.js +++ b/Specs/Scene/LabelCollectionSpec.js @@ -2227,6 +2227,23 @@ defineSuite([ expect(l._clampedPosition).toBeUndefined(); expect(l._glyphs[0].billboard._clampedPosition).toBeUndefined(); }); + + it('clears the billboard height reference callback when the label is removed', function() { + scene.globe = createGlobe(); + spyOn(scene.camera, 'update'); + var l = labelsWithHeight.add({ + heightReference : HeightReference.CLAMP_TO_GROUND, + text: 't', + position : Cartesian3.fromDegrees(-72.0, 40.0) + }); + scene.renderForSpecs(); + var billboard = l._glyphs[0].billboard; + expect(billboard._removeCallbackFunc).toBeDefined(); + var spy = spyOn(billboard, '_removeCallbackFunc'); + labelsWithHeight.remove(l); + expect(spy).toHaveBeenCalled(); + expect(labelsWithHeight._spareBillboards[0]._removeCallbackFunc).not.toBeDefined(); + }); }); }, 'WebGL'); From 16979216e4c4c1f62fd994731c4bab2e8234d4ea Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 18 Jul 2017 16:58:56 -0400 Subject: [PATCH 099/132] Update DebugCameraPrimitive, add Sandcastle example, fix broken tests. --- .../gallery/development/Frustum.html | 101 ++++++ Source/Core/FrustumGeometry.js | 61 +++- Source/Core/FrustumOutlineGeometry.js | 37 +- Source/Scene/DebugCameraPrimitive.js | 331 +++++++----------- Specs/Scene/DebugCameraPrimitiveSpec.js | 18 +- 5 files changed, 301 insertions(+), 247 deletions(-) create mode 100644 Apps/Sandcastle/gallery/development/Frustum.html diff --git a/Apps/Sandcastle/gallery/development/Frustum.html b/Apps/Sandcastle/gallery/development/Frustum.html new file mode 100644 index 000000000000..96d99ffe1b42 --- /dev/null +++ b/Apps/Sandcastle/gallery/development/Frustum.html @@ -0,0 +1,101 @@ + + + + + + + + + Cesium Demo + + + + + + +

+

Loading...

+
+ + + diff --git a/Source/Core/FrustumGeometry.js b/Source/Core/FrustumGeometry.js index f876e7c0d1ac..8727261165af 100644 --- a/Source/Core/FrustumGeometry.js +++ b/Source/Core/FrustumGeometry.js @@ -63,6 +63,7 @@ define([ var orientation = options.orientation; var position = options.position; var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); + var drawNearPlane = defaultValue(options._drawNearPlane, true); var frustumType; var frustumPackedLength; @@ -78,6 +79,7 @@ define([ this._frustum = frustum.clone(); this._position = Cartesian3.clone(position); this._orientation = Quaternion.clone(orientation); + this._drawNearPlane = drawNearPlane; this._vertexFormat = vertexFormat; this._workerName = 'createFrustumGeometry'; @@ -85,7 +87,7 @@ define([ * The number of elements used to pack the object into an array. * @type {Number} */ - this.packedLength = 1 + frustumPackedLength + Cartesian3.packedLength + Quaternion.packedLength + VertexFormat.packedLength; + this.packedLength = 2 + frustumPackedLength + Cartesian3.packedLength + Quaternion.packedLength + VertexFormat.packedLength; } /** @@ -123,6 +125,8 @@ define([ Quaternion.pack(value._orientation, array, startingIndex); startingIndex += Quaternion.packedLength; VertexFormat.pack(value._vertexFormat, array, startingIndex); + startingIndex += VertexFormat.packedLength; + array[startingIndex] = value._drawNearPlane ? 1.0 : 0.0; return array; }; @@ -163,13 +167,16 @@ define([ var orientation = Quaternion.unpack(array, startingIndex, scratchPackQuaternion); startingIndex += Quaternion.packedLength; var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat); + startingIndex += VertexFormat.packedLength; + var drawNearPlane = array[startingIndex] === 1.0; if (!defined(result)) { return new FrustumGeometry({ frustum : frustum, position : position, orientation : orientation, - vertexFormat : vertexFormat + vertexFormat : vertexFormat, + _drawNearPlane : drawNearPlane }); } @@ -180,6 +187,7 @@ define([ result._position = Cartesian3.clone(position, result._position); result._orientation = Quaternion.clone(orientation, result._orientation); result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); + result._drawNearPlane = drawNearPlane; return result; }; @@ -251,6 +259,7 @@ define([ var frustum = frustumGeometry._frustum; var position = frustumGeometry._position; var orientation = frustumGeometry._orientation; + var drawNearPlane = frustumGeometry._drawNearPlane; var vertexFormat = frustumGeometry._vertexFormat; var rotationMatrix = Matrix3.fromQuaternion(orientation, scratchRotationMatrix); @@ -276,11 +285,17 @@ define([ inverseView = Matrix4.inverseTransformation(view, scratchInverseMatrix); } - frustumSplits[0] = frustum.near; - frustumSplits[1] = frustum.far; - frustumSplits[2] = frustum.far + 1.0; + if (defined(inverseViewProjection)) { + frustumSplits[0] = frustum.near; + frustumSplits[1] = frustum.far; + } else { + frustumSplits[0] = 0.0; + frustumSplits[1] = frustum.near; + frustumSplits[2] = frustum.far; + } var i; + var numberOfPlanes = drawNearPlane ? 6 : 5; var positions = new Float64Array(3 * 4 * 6); for (i = 0; i < 2; ++i) { @@ -382,6 +397,10 @@ define([ positions[offset + 10] = positions[3 * 3 + 1]; positions[offset + 11] = positions[3 * 3 + 2]; + if (!drawNearPlane) { + positions = positions.subarray(3 * 4); + } + var attributes = new GeometryAttributes({ position : new GeometryAttribute({ componentDatatype : ComponentDatatype.DOUBLE, @@ -391,21 +410,29 @@ define([ }); if (defined(vertexFormat.normal) || defined(vertexFormat.tangent) || defined(vertexFormat.bitangent) || defined(vertexFormat.st)) { - var normals = defined(vertexFormat.normal) ? new Float32Array(3 * 4 * 6) : undefined; - var tangents = defined(vertexFormat.tangent) ? new Float32Array(3 * 4 * 6) : undefined; - var bitangents = defined(vertexFormat.bitangent) ? new Float32Array(3 * 4 * 6) : undefined; - var st = defined(vertexFormat.st) ? new Float32Array(2 * 4 * 6) : undefined; + var normals = defined(vertexFormat.normal) ? new Float32Array(3 * 4 * numberOfPlanes) : undefined; + var tangents = defined(vertexFormat.tangent) ? new Float32Array(3 * 4 * numberOfPlanes) : undefined; + var bitangents = defined(vertexFormat.bitangent) ? new Float32Array(3 * 4 * numberOfPlanes) : undefined; + var st = defined(vertexFormat.st) ? new Float32Array(2 * 4 * numberOfPlanes) : undefined; var negativeX = Cartesian3.negate(x, scratchNegativeX); var negativeY = Cartesian3.negate(y, scratchNegativeY); var negativeZ = Cartesian3.negate(z, scratchNegativeZ); - getAttributes(0, normals, tangents, bitangents, st, negativeZ, x, y); // near - getAttributes(3 * 4, normals, tangents, bitangents, st, z, negativeX, y); // far - getAttributes(3 * 4 * 2, normals, tangents, bitangents, st, negativeX, negativeZ, y); // -x - getAttributes(3 * 4 * 3, normals, tangents, bitangents, st, negativeY, negativeZ, negativeX); // -y - getAttributes(3 * 4 * 4, normals, tangents, bitangents, st, x, z, y); // +x - getAttributes(3 * 4 * 5, normals, tangents, bitangents, st, y, z, negativeX); // +y + offset = 0; + if (drawNearPlane) { + getAttributes(offset, normals, tangents, bitangents, st, negativeZ, x, y); // near + offset += 3 * 4; + } + getAttributes(offset, normals, tangents, bitangents, st, z, negativeX, y); // far + offset += 3 * 4; + getAttributes(offset, normals, tangents, bitangents, st, negativeX, negativeZ, y); // -x + offset += 3 * 4; + getAttributes(offset, normals, tangents, bitangents, st, negativeY, negativeZ, negativeX); // -y + offset += 3 * 4; + getAttributes(offset, normals, tangents, bitangents, st, x, z, y); // +x + offset += 3 * 4; + getAttributes(offset, normals, tangents, bitangents, st, y, z, negativeX); // +y if (defined(normals)) { attributes.normal = new GeometryAttribute({ @@ -437,8 +464,8 @@ define([ } } - var indices = new Uint16Array(6 * 6); - for (i = 0; i < 6; ++i) { + var indices = new Uint16Array(6 * numberOfPlanes); + for (i = 0; i < numberOfPlanes; ++i) { var indexOffset = i * 6; var index = i * 4; diff --git a/Source/Core/FrustumOutlineGeometry.js b/Source/Core/FrustumOutlineGeometry.js index b3e4ead0b803..d803081036de 100644 --- a/Source/Core/FrustumOutlineGeometry.js +++ b/Source/Core/FrustumOutlineGeometry.js @@ -59,6 +59,7 @@ define([ var frustum = options.frustum; var orientation = options.orientation; var position = options.position; + var drawNearPlane = defaultValue(options._drawNearPlane, true); var frustumType; var frustumPackedLength; @@ -74,13 +75,14 @@ define([ this._frustum = frustum.clone(); this._position = Cartesian3.clone(position); this._orientation = Quaternion.clone(orientation); + this._drawNearPlane = drawNearPlane; this._workerName = 'createFrustumOutlineGeometry'; /** * The number of elements used to pack the object into an array. * @type {Number} */ - this.packedLength = 1 + frustumPackedLength + Cartesian3.packedLength + Quaternion.packedLength; + this.packedLength = 2 + frustumPackedLength + Cartesian3.packedLength + Quaternion.packedLength; } /** @@ -116,6 +118,8 @@ define([ Cartesian3.pack(value._position, array, startingIndex); startingIndex += Cartesian3.packedLength; Quaternion.pack(value._orientation, array, startingIndex); + startingIndex += Quaternion.packedLength; + array[startingIndex] = value._drawNearPlane ? 1.0 : 0.0; return array; }; @@ -153,12 +157,15 @@ define([ var position = Cartesian3.unpack(array, startingIndex, scratchPackPosition); startingIndex += Cartesian3.packedLength; var orientation = Quaternion.unpack(array, startingIndex, scratchPackQuaternion); + startingIndex += Quaternion.packedLength; + var drawNearPlane = array[startingIndex] === 1.0; if (!defined(result)) { return new FrustumOutlineGeometry({ frustum : frustum, position : position, - orientation : orientation + orientation : orientation, + _drawNearPlane : drawNearPlane }); } @@ -168,6 +175,7 @@ define([ result._frustumType = frustumType; result._position = Cartesian3.clone(position, result._position); result._orientation = Quaternion.clone(orientation, result._orientation); + result._drawNearPlane = drawNearPlane; return result; }; @@ -179,9 +187,6 @@ define([ var scratchXDirection = new Cartesian3(); var scratchYDirection = new Cartesian3(); var scratchZDirection = new Cartesian3(); - var scratchNegativeX = new Cartesian3(); - var scratchNegativeY = new Cartesian3(); - var scratchNegativeZ = new Cartesian3(); var frustumSplits = new Array(3); @@ -207,6 +212,7 @@ define([ var frustum = frustumGeometry._frustum; var position = frustumGeometry._position; var orientation = frustumGeometry._orientation; + var drawNearPlane = frustumGeometry._drawNearPlane; var rotationMatrix = Matrix3.fromQuaternion(orientation, scratchRotationMatrix); var x = Matrix3.getColumn(rotationMatrix, 0, scratchXDirection); @@ -231,9 +237,14 @@ define([ inverseView = Matrix4.inverseTransformation(view, scratchInverseMatrix); } - frustumSplits[0] = frustum.near; - frustumSplits[1] = frustum.far; - frustumSplits[2] = frustum.far + 1.0; + if (defined(inverseViewProjection)) { + frustumSplits[0] = frustum.near; + frustumSplits[1] = frustum.far; + } else { + frustumSplits[0] = 0.0; + frustumSplits[1] = frustum.near; + frustumSplits[2] = frustum.far; + } var i; var positions = new Float64Array(3 * 4 * 2); @@ -288,11 +299,13 @@ define([ var offset; var index; - var indices = new Uint16Array(8 * (2 + 1)); + var numberOfPlanes = drawNearPlane ? 2 : 1; + var indices = new Uint16Array(8 * (numberOfPlanes + 1)); // Build the near/far planes - for (i = 0; i < 2; ++i) { - offset = i * 8; + i = drawNearPlane ? 0 : 1; + for (; i < 2; ++i) { + offset = drawNearPlane ? i * 8 : 0; index = i * 4; indices[offset] = index; @@ -307,7 +320,7 @@ define([ // Build the sides of the frustums for (i = 0; i < 2; ++i) { - offset = (2 + i) * 8; + offset = (numberOfPlanes + i) * 8; index = i * 4; indices[offset] = index; diff --git a/Source/Scene/DebugCameraPrimitive.js b/Source/Scene/DebugCameraPrimitive.js index d0b402883dd7..5bcd23fe61ea 100644 --- a/Source/Scene/DebugCameraPrimitive.js +++ b/Source/Scene/DebugCameraPrimitive.js @@ -9,11 +9,19 @@ define([ '../Core/defined', '../Core/destroyObject', '../Core/DeveloperError', + '../Core/FrustumGeometry', + '../Core/FrustumOutlineGeometry', '../Core/GeometryAttribute', '../Core/GeometryAttributes', '../Core/GeometryInstance', + '../Core/Matrix3', '../Core/Matrix4', + '../Core/OrthographicFrustum', + '../Core/OrthographicOffCenterFrustum', + '../Core/PerspectiveFrustum', + '../Core/PerspectiveOffCenterFrustum', '../Core/PrimitiveType', + '../Core/Quaternion', './PerInstanceColorAppearance', './Primitive' ], function( @@ -27,11 +35,19 @@ define([ defined, destroyObject, DeveloperError, + FrustumGeometry, + FrustumOutlineGeometry, GeometryAttribute, GeometryAttributes, GeometryInstance, + Matrix3, Matrix4, + OrthographicFrustum, + OrthographicOffCenterFrustum, + PerspectiveFrustum, + PerspectiveOffCenterFrustum, PrimitiveType, + Quaternion, PerInstanceColorAppearance, Primitive) { 'use strict'; @@ -87,24 +103,21 @@ define([ this.id = options.id; this._id = undefined; - this._outlinePrimitive = undefined; - this._planesPrimitive = undefined; + this._outlinePrimitives = []; + this._planesPrimitives = []; } - var frustumCornersNDC = new Array(4); - frustumCornersNDC[0] = new Cartesian4(-1.0, -1.0, 1.0, 1.0); - frustumCornersNDC[1] = new Cartesian4(1.0, -1.0, 1.0, 1.0); - frustumCornersNDC[2] = new Cartesian4(1.0, 1.0, 1.0, 1.0); - frustumCornersNDC[3] = new Cartesian4(-1.0, 1.0, 1.0, 1.0); - - var scratchMatrix = new Matrix4(); - var scratchFrustumCorners = new Array(4); - for (var i = 0; i < 4; ++i) { - scratchFrustumCorners[i] = new Cartesian4(); - } + var scratchRight = new Cartesian3(); + var scratchRotation = new Matrix3(); + var scratchOrientation = new Quaternion(); + var scratchPerspective = new PerspectiveFrustum(); + var scratchPerspectiveOffCenter = new PerspectiveOffCenterFrustum(); + var scratchOrthographic = new OrthographicFrustum(); + var scratchOrthographicOffCenter = new OrthographicOffCenterFrustum(); var scratchColor = new Color(); var scratchSplits = [1.0, 100000.0]; + /** * @private */ @@ -113,15 +126,36 @@ define([ return; } + var planesPrimitives = this._planesPrimitives; + var outlinePrimitives = this._outlinePrimitives; + var i; + var length; + if (this._updateOnChange) { // Recreate the primitive every frame - this._outlinePrimitive = this._outlinePrimitive && this._outlinePrimitive.destroy(); - this._planesPrimitive = this._planesPrimitive && this._planesPrimitive.destroy(); + length = planesPrimitives.length; + for (i = 0; i < length; ++i) { + outlinePrimitives[i] = outlinePrimitives[i] && outlinePrimitives[i].destroy(); + planesPrimitives[i] = planesPrimitives[i] && planesPrimitives[i].destroy(); + } + planesPrimitives.length = 0; + outlinePrimitives.length = 0; } - if (!defined(this._outlinePrimitive)) { + if (planesPrimitives.length === 0) { var camera = this._camera; - var frustum = camera.frustum; + var cameraFrustum = camera.frustum; + var frustum; + if (cameraFrustum instanceof PerspectiveFrustum) { + frustum = scratchPerspective; + } else if (cameraFrustum instanceof PerspectiveOffCenterFrustum) { + frustum = scratchPerspectiveOffCenter; + } else if (cameraFrustum instanceof OrthographicFrustum) { + frustum = scratchOrthographic; + } else { + frustum = scratchOrthographicOffCenter; + } + frustum = cameraFrustum.clone(frustum); var frustumSplits = frameState.frustumSplits; var numFrustums = frustumSplits.length - 1; @@ -132,200 +166,74 @@ define([ numFrustums = 1; } - var view = this._camera.viewMatrix; - var inverseView; - var inverseViewProjection; - if (defined(camera.frustum.fovy)) { - var projection = this._camera.frustum.projectionMatrix; - var viewProjection = Matrix4.multiply(projection, view, scratchMatrix); - inverseViewProjection = Matrix4.inverse(viewProjection, scratchMatrix); - } else { - inverseView = Matrix4.inverseTransformation(view, scratchMatrix); - } - - - var positions = new Float64Array(3 * 4 * (numFrustums + 1)); - var f; - for (f = 0; f < numFrustums + 1; ++f) { - for (var i = 0; i < 4; ++i) { - var corner = Cartesian4.clone(frustumCornersNDC[i], scratchFrustumCorners[i]); - - if (!defined(inverseViewProjection)) { - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; - } - - var near; - var far; - if (f === numFrustums) { - near = frustumSplits[f - 1]; - far = frustumSplits[f]; - } else { - near = frustumSplits[f]; - far = frustumSplits[f + 1]; - } - corner.x = (corner.x * (frustum.right - frustum.left) + frustum.left + frustum.right) * 0.5; - corner.y = (corner.y * (frustum.top - frustum.bottom) + frustum.bottom + frustum.top) * 0.5; - corner.z = (corner.z * (near - far) - near - far) * 0.5; - corner.w = 1.0; - - Matrix4.multiplyByVector(inverseView, corner, corner); - } else { - corner = Matrix4.multiplyByVector(inverseViewProjection, corner, corner); - - // Reverse perspective divide - var w = 1.0 / corner.w; - Cartesian3.multiplyByScalar(corner, w, corner); - - Cartesian3.subtract(corner, this._camera.positionWC, corner); - Cartesian3.normalize(corner, corner); - - var fac = Cartesian3.dot(this._camera.directionWC, corner); - Cartesian3.multiplyByScalar(corner, frustumSplits[f] / fac, corner); - Cartesian3.add(corner, this._camera.positionWC, corner); - } - - positions[12 * f + i * 3] = corner.x; - positions[12 * f + i * 3 + 1] = corner.y; - positions[12 * f + i * 3 + 2] = corner.z; - } - } - - var boundingSphere = BoundingSphere.fromVertices(positions); - - var attributes = new GeometryAttributes(); - attributes.position = new GeometryAttribute({ - componentDatatype : ComponentDatatype.DOUBLE, - componentsPerAttribute : 3, - values : positions - }); - - var offset, index; - - // Create the outline primitive - var outlineIndices = new Uint16Array(8 * (2 * numFrustums + 1)); - // Build the far planes - for (f = 0; f < numFrustums + 1; ++f) { - offset = f * 8; - index = f * 4; - - outlineIndices[offset] = index; - outlineIndices[offset + 1] = index + 1; - outlineIndices[offset + 2] = index + 1; - outlineIndices[offset + 3] = index + 2; - outlineIndices[offset + 4] = index + 2; - outlineIndices[offset + 5] = index + 3; - outlineIndices[offset + 6] = index + 3; - outlineIndices[offset + 7] = index; - } - // Build the sides of the frustums - for (f = 0; f < numFrustums; ++f) { - offset = (numFrustums + 1 + f) * 8; - index = f * 4; - - outlineIndices[offset] = index; - outlineIndices[offset + 1] = index + 4; - outlineIndices[offset + 2] = index + 1; - outlineIndices[offset + 3] = index + 5; - outlineIndices[offset + 4] = index + 2; - outlineIndices[offset + 5] = index + 6; - outlineIndices[offset + 6] = index + 3; - outlineIndices[offset + 7] = index + 7; + var position = camera.positionWC; + var direction = camera.directionWC; + var up = camera.upWC; + var right = camera.rightWC; + right = Cartesian3.negate(right, scratchRight); + + var rotation = scratchRotation; + Matrix3.setColumn(rotation, 0, right, rotation); + Matrix3.setColumn(rotation, 1, up, rotation); + Matrix3.setColumn(rotation, 2, direction, rotation); + + var orientation = Quaternion.fromRotationMatrix(rotation, scratchOrientation); + + planesPrimitives.length = outlinePrimitives.length = numFrustums; + + for (i = 0; i < numFrustums; ++i) { + frustum.near = frustumSplits[i]; + frustum.far = frustumSplits[i + 1]; + + planesPrimitives[i] = new Primitive({ + geometryInstances : new GeometryInstance({ + geometry : new FrustumGeometry({ + position : position, + orientation : orientation, + frustum : frustum, + _drawNearPlane : i === 0 + }), + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(Color.fromAlpha(this._color, 0.1, scratchColor)) + }, + id : this.id, + pickPrimitive : this + }), + appearance : new PerInstanceColorAppearance({ + translucent : true, + flat : true + }), + asynchronous : false + }); + + outlinePrimitives[i] = new Primitive({ + geometryInstances : new GeometryInstance({ + geometry : new FrustumOutlineGeometry({ + position : position, + orientation : orientation, + frustum : frustum, + _drawNearPlane : i === 0 + }), + attributes : { + color : ColorGeometryInstanceAttribute.fromColor(this._color) + }, + id : this.id, + pickPrimitive : this + }), + appearance : new PerInstanceColorAppearance({ + translucent : false, + flat : true + }), + asynchronous : false + }); } - - this._outlinePrimitive = new Primitive({ - geometryInstances : new GeometryInstance({ - geometry : { - attributes : attributes, - indices : outlineIndices, - primitiveType : PrimitiveType.LINES, - boundingSphere : boundingSphere - }, - attributes : { - color : ColorGeometryInstanceAttribute.fromColor(this._color) - }, - id : this.id, - pickPrimitive : this - }), - appearance : new PerInstanceColorAppearance({ - translucent : false, - flat : true - }), - asynchronous : false - }); - - // Create the planes primitive - var planesIndices = new Uint16Array(6 * (5 * numFrustums + 1)); - // Build the far planes - for (f = 0; f < numFrustums + 1; ++f) { - offset = f * 6; - index = f * 4; - - planesIndices[offset] = index; - planesIndices[offset + 1] = index + 1; - planesIndices[offset + 2] = index + 2; - planesIndices[offset + 3] = index; - planesIndices[offset + 4] = index + 2; - planesIndices[offset + 5] = index + 3; - } - // Build the sides of the frustums - for (f = 0; f < numFrustums; ++f) { - offset = (numFrustums + 1 + 4 * f) * 6; - index = f * 4; - - planesIndices[offset] = index + 4; - planesIndices[offset + 1] = index; - planesIndices[offset + 2] = index + 3; - planesIndices[offset + 3] = index + 4; - planesIndices[offset + 4] = index + 3; - planesIndices[offset + 5] = index + 7; - - planesIndices[offset + 6] = index + 4; - planesIndices[offset + 7] = index; - planesIndices[offset + 8] = index + 1; - planesIndices[offset + 9] = index + 4; - planesIndices[offset + 10] = index + 1; - planesIndices[offset + 11] = index + 5; - - planesIndices[offset + 12] = index + 7; - planesIndices[offset + 13] = index + 3; - planesIndices[offset + 14] = index + 2; - planesIndices[offset + 15] = index + 7; - planesIndices[offset + 16] = index + 2; - planesIndices[offset + 17] = index + 6; - - planesIndices[offset + 18] = index + 6; - planesIndices[offset + 19] = index + 2; - planesIndices[offset + 20] = index + 1; - planesIndices[offset + 21] = index + 6; - planesIndices[offset + 22] = index + 1; - planesIndices[offset + 23] = index + 5; - } - - this._planesPrimitive = new Primitive({ - geometryInstances : new GeometryInstance({ - geometry : { - attributes : attributes, - indices : planesIndices, - primitiveType : PrimitiveType.TRIANGLES, - boundingSphere : boundingSphere - }, - attributes : { - color : ColorGeometryInstanceAttribute.fromColor(Color.fromAlpha(this._color, 0.1, scratchColor)) - }, - id : this.id, - pickPrimitive : this - }), - appearance : new PerInstanceColorAppearance({ - translucent : true, - flat : true - }), - asynchronous : false - }); } - this._outlinePrimitive.update(frameState); - this._planesPrimitive.update(frameState); + length = planesPrimitives.length; + for (i = 0; i < length; ++i) { + outlinePrimitives[i].update(frameState); + planesPrimitives[i].update(frameState); + } }; /** @@ -362,8 +270,11 @@ define([ * @see DebugCameraPrimitive#isDestroyed */ DebugCameraPrimitive.prototype.destroy = function() { - this._outlinePrimitive = this._outlinePrimitive && this._outlinePrimitive.destroy(); - this._planesPrimitive = this._planesPrimitive && this._planesPrimitive.destroy(); + var length = this._planesPrimitives.length; + for (var i = 0; i < length; ++i) { + this._outlinePrimitives[i] = this._outlinePrimitives[i] && this._outlinePrimitives[i].destroy(); + this._planesPrimitives[i] = this._planesPrimitives[i] && this._planesPrimitives[i].destroy(); + } return destroyObject(this); }; diff --git a/Specs/Scene/DebugCameraPrimitiveSpec.js b/Specs/Scene/DebugCameraPrimitiveSpec.js index 9634f622b567..90fe211053bb 100644 --- a/Specs/Scene/DebugCameraPrimitiveSpec.js +++ b/Specs/Scene/DebugCameraPrimitiveSpec.js @@ -16,16 +16,18 @@ defineSuite([ var camera; beforeAll(function() { - scene = createScene(); - - camera = new Camera(scene); - camera.position = new Cartesian3(0.0, 0.0, 0.0); - camera.direction = Cartesian3.negate(Cartesian3.UNIT_X, new Cartesian3()); - camera.up = Cartesian3.clone(Cartesian3.UNIT_Z); + scene = createScene({ + scene3DOnly : true + }); scene.camera.position = new Cartesian3(0.0, 0.0, 0.0); scene.camera.direction = Cartesian3.negate(Cartesian3.UNIT_X, new Cartesian3()); scene.camera.up = Cartesian3.clone(Cartesian3.UNIT_Z); + scene.camera.frustum.near = 1.0; + scene.camera.frustum.far = 500.0; + + camera = Camera.clone(scene.camera); + scene.camera.zoomOut(1.0); }); @@ -85,9 +87,9 @@ defineSuite([ camera : camera })); scene.renderForSpecs(); - var primitive = p._outlinePrimitive; + var primitive = p._outlinePrimitives[0]; scene.renderForSpecs(); - expect(p._outlinePrimitive).not.toBe(primitive); + expect(p._outlinePrimitives[0]).not.toBe(primitive); }); it('does not update when updateOnChange is false', function() { From 226d4e2eae8fb7e12ba6507a532144cce9630a28 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 18 Jul 2017 19:17:57 -0400 Subject: [PATCH 100/132] Update doc and add tests. --- Source/Core/OrthographicFrustum.js | 21 +++++ Source/Core/PerspectiveFrustum.js | 21 +++++ Source/Core/VertexFormat.js | 4 +- Source/Scene/DebugCameraPrimitive.js | 14 --- .../Workers/createFrustumOutlineGeometry.js | 10 +- Specs/Core/FrustumGeometrySpec.js | 93 +++++++++++++++++++ Specs/Core/FrustumOutlineGeometrySpec.js | 87 +++++++++++++++++ Specs/Core/OrthographicFrustumSpec.js | 35 ++++--- Specs/Core/PerspectiveFrustumSpec.js | 15 ++- 9 files changed, 264 insertions(+), 36 deletions(-) create mode 100644 Specs/Core/FrustumGeometrySpec.js create mode 100644 Specs/Core/FrustumOutlineGeometrySpec.js diff --git a/Source/Core/OrthographicFrustum.js b/Source/Core/OrthographicFrustum.js index c4739c4b71ca..c308f3117180 100644 --- a/Source/Core/OrthographicFrustum.js +++ b/Source/Core/OrthographicFrustum.js @@ -66,8 +66,21 @@ define([ this._far = this.far; } + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ OrthographicFrustum.packedLength = 4; + /** + * Stores the provided instance into the provided array. + * + * @param {OrthographicFrustum} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ OrthographicFrustum.pack = function(value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); Check.typeOf.object('value', value); @@ -84,6 +97,14 @@ define([ return array; }; + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {OrthographicFrustum} [result] The object into which to store the result. + * @returns {OrthographicFrustum} The modified result parameter or a new OrthographicFrustum instance if one was not provided. + */ OrthographicFrustum.unpack = function(array, startingIndex, result) { //>>includeStart('debug', pragmas.debug); Check.defined('array', array); diff --git a/Source/Core/PerspectiveFrustum.js b/Source/Core/PerspectiveFrustum.js index 0701f82cec67..d0d40c84e5ec 100644 --- a/Source/Core/PerspectiveFrustum.js +++ b/Source/Core/PerspectiveFrustum.js @@ -90,8 +90,21 @@ define([ this._yOffset = this.yOffset; } + /** + * The number of elements used to pack the object into an array. + * @type {Number} + */ PerspectiveFrustum.packedLength = 6; + /** + * Stores the provided instance into the provided array. + * + * @param {PerspectiveFrustum} value The value to pack. + * @param {Number[]} array The array to pack into. + * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. + * + * @returns {Number[]} The array that was packed into + */ PerspectiveFrustum.pack = function(value, array, startingIndex) { //>>includeStart('debug', pragmas.debug); Check.typeOf.object('value', value); @@ -110,6 +123,14 @@ define([ return array; }; + /** + * Retrieves an instance from a packed array. + * + * @param {Number[]} array The packed array. + * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. + * @param {PerspectiveFrustum} [result] The object into which to store the result. + * @returns {PerspectiveFrustum} The modified result parameter or a new PerspectiveFrustum instance if one was not provided. + */ PerspectiveFrustum.unpack = function(array, startingIndex, result) { //>>includeStart('debug', pragmas.debug); Check.defined('array', array); diff --git a/Source/Core/VertexFormat.js b/Source/Core/VertexFormat.js index 64b93c9dced7..55627ea7364e 100644 --- a/Source/Core/VertexFormat.js +++ b/Source/Core/VertexFormat.js @@ -246,7 +246,7 @@ define([ array[startingIndex++] = value.st ? 1.0 : 0.0; array[startingIndex++] = value.tangent ? 1.0 : 0.0; array[startingIndex++] = value.bitangent ? 1.0 : 0.0; - array[startingIndex++] = value.color ? 1.0 : 0.0; + array[startingIndex] = value.color ? 1.0 : 0.0; return array; }; @@ -277,7 +277,7 @@ define([ result.st = array[startingIndex++] === 1.0; result.tangent = array[startingIndex++] === 1.0; result.bitangent = array[startingIndex++] === 1.0; - result.color = array[startingIndex++] === 1.0; + result.color = array[startingIndex] === 1.0; return result; }; diff --git a/Source/Scene/DebugCameraPrimitive.js b/Source/Scene/DebugCameraPrimitive.js index 5bcd23fe61ea..5b59f46d201b 100644 --- a/Source/Scene/DebugCameraPrimitive.js +++ b/Source/Scene/DebugCameraPrimitive.js @@ -1,52 +1,38 @@ define([ - '../Core/BoundingSphere', '../Core/Cartesian3', - '../Core/Cartesian4', '../Core/Color', '../Core/ColorGeometryInstanceAttribute', - '../Core/ComponentDatatype', '../Core/defaultValue', '../Core/defined', '../Core/destroyObject', '../Core/DeveloperError', '../Core/FrustumGeometry', '../Core/FrustumOutlineGeometry', - '../Core/GeometryAttribute', - '../Core/GeometryAttributes', '../Core/GeometryInstance', '../Core/Matrix3', - '../Core/Matrix4', '../Core/OrthographicFrustum', '../Core/OrthographicOffCenterFrustum', '../Core/PerspectiveFrustum', '../Core/PerspectiveOffCenterFrustum', - '../Core/PrimitiveType', '../Core/Quaternion', './PerInstanceColorAppearance', './Primitive' ], function( - BoundingSphere, Cartesian3, - Cartesian4, Color, ColorGeometryInstanceAttribute, - ComponentDatatype, defaultValue, defined, destroyObject, DeveloperError, FrustumGeometry, FrustumOutlineGeometry, - GeometryAttribute, - GeometryAttributes, GeometryInstance, Matrix3, - Matrix4, OrthographicFrustum, OrthographicOffCenterFrustum, PerspectiveFrustum, PerspectiveOffCenterFrustum, - PrimitiveType, Quaternion, PerInstanceColorAppearance, Primitive) { diff --git a/Source/Workers/createFrustumOutlineGeometry.js b/Source/Workers/createFrustumOutlineGeometry.js index 59f604697e27..4e6a84370bcf 100644 --- a/Source/Workers/createFrustumOutlineGeometry.js +++ b/Source/Workers/createFrustumOutlineGeometry.js @@ -1,9 +1,9 @@ define([ - '../Core/defined', - '../Core/FrustumOutlineGeometry' -], function( - defined, - FrustumOutlineGeometry) { + '../Core/defined', + '../Core/FrustumOutlineGeometry' + ], function( + defined, + FrustumOutlineGeometry) { 'use strict'; function createFrustumOutlineGeometry(frustumGeometry, offset) { diff --git a/Specs/Core/FrustumGeometrySpec.js b/Specs/Core/FrustumGeometrySpec.js new file mode 100644 index 000000000000..6202904bac5b --- /dev/null +++ b/Specs/Core/FrustumGeometrySpec.js @@ -0,0 +1,93 @@ +defineSuite([ + 'Core/FrustumGeometry', + 'Core/Cartesian3', + 'Core/Math', + 'Core/PerspectiveFrustum', + 'Core/Quaternion', + 'Core/VertexFormat', + 'Specs/createPackableSpecs' + ], function( + FrustumGeometry, + Cartesian3, + CesiumMath, + PerspectiveFrustum, + Quaternion, + VertexFormat, + createPackableSpecs) { + 'use strict'; + + it('constructor throws without options', function() { + expect(function() { + return new FrustumGeometry(); + }).toThrowDeveloperError(); + }); + + it('constructor throws without frustum', function() { + expect(function() { + return new FrustumGeometry({ + position : Cartesian3.ZERO, + orientation : Quaternion.IDENTITY + }); + }).toThrowDeveloperError(); + }); + + it('constructor throws without position', function() { + expect(function() { + return new FrustumGeometry({ + frustum : new PerspectiveFrustum(), + orientation : Quaternion.IDENTITY + }); + }).toThrowDeveloperError(); + }); + + it('constructor throws without orientation', function() { + expect(function() { + return new FrustumGeometry({ + frustum : new PerspectiveFrustum(), + position : Cartesian3.ZERO + }); + }).toThrowDeveloperError(); + }); + + it('constructor computes all vertex attributes', function() { + var frustum = new PerspectiveFrustum(); + frustum.fov = CesiumMath.toRadians(30.0); + frustum.aspectRatio = 1920.0 / 1080.0; + frustum.near = 1.0; + frustum.far = 3.0; + + var m = FrustumGeometry.createGeometry(new FrustumGeometry({ + frustum : frustum, + position : Cartesian3.ZERO, + orientation : Quaternion.IDENTITY, + vertexFormat : VertexFormat.ALL + })); + + var numVertices = 24; //3 components x 8 corners + var numTriangles = 12; //6 sides x 2 triangles per side + expect(m.attributes.position.values.length).toEqual(numVertices * 3); + expect(m.attributes.normal.values.length).toEqual(numVertices * 3); + expect(m.attributes.tangent.values.length).toEqual(numVertices * 3); + expect(m.attributes.bitangent.values.length).toEqual(numVertices * 3); + expect(m.attributes.st.values.length).toEqual(numVertices * 2); + + expect(m.indices.length).toEqual(numTriangles * 3); + + expect(m.boundingSphere.center).toEqual(new Cartesian3(0.0, 0.0, 2.0)); + expect(m.boundingSphere.radius).toBeGreaterThan(1.0); + expect(m.boundingSphere.radius).toBeLessThan(2.0); + }); + + var packableFrustum = new PerspectiveFrustum(); + packableFrustum.fov = 1.0; + packableFrustum.aspectRatio = 2.0; + packableFrustum.near = 3.0; + packableFrustum.far = 4.0; + + createPackableSpecs(FrustumGeometry, new FrustumGeometry({ + frustum : packableFrustum, + position : Cartesian3.ZERO, + orientation : Quaternion.IDENTITY, + vertexFormat : VertexFormat.POSITION_ONLY + }), [0.0, 1.0, 2.0, 3.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]); +}); diff --git a/Specs/Core/FrustumOutlineGeometrySpec.js b/Specs/Core/FrustumOutlineGeometrySpec.js new file mode 100644 index 000000000000..8fabd5ed5ec6 --- /dev/null +++ b/Specs/Core/FrustumOutlineGeometrySpec.js @@ -0,0 +1,87 @@ +defineSuite([ + 'Core/FrustumOutlineGeometry', + 'Core/Cartesian3', + 'Core/Math', + 'Core/PerspectiveFrustum', + 'Core/Quaternion', + 'Core/VertexFormat', + 'Specs/createPackableSpecs' + ], function( + FrustumOutlineGeometry, + Cartesian3, + CesiumMath, + PerspectiveFrustum, + Quaternion, + VertexFormat, + createPackableSpecs) { + 'use strict'; + + it('constructor throws without options', function() { + expect(function() { + return new FrustumOutlineGeometry(); + }).toThrowDeveloperError(); + }); + + it('constructor throws without frustum', function() { + expect(function() { + return new FrustumOutlineGeometry({ + position : Cartesian3.ZERO, + orientation : Quaternion.IDENTITY + }); + }).toThrowDeveloperError(); + }); + + it('constructor throws without position', function() { + expect(function() { + return new FrustumOutlineGeometry({ + frustum : new PerspectiveFrustum(), + orientation : Quaternion.IDENTITY + }); + }).toThrowDeveloperError(); + }); + + it('constructor throws without orientation', function() { + expect(function() { + return new FrustumOutlineGeometry({ + frustum : new PerspectiveFrustum(), + position : Cartesian3.ZERO + }); + }).toThrowDeveloperError(); + }); + + it('constructor computes all vertex attributes', function() { + var frustum = new PerspectiveFrustum(); + frustum.fov = CesiumMath.toRadians(30.0); + frustum.aspectRatio = 1920.0 / 1080.0; + frustum.near = 1.0; + frustum.far = 3.0; + + var m = FrustumOutlineGeometry.createGeometry(new FrustumOutlineGeometry({ + frustum : frustum, + position : Cartesian3.ZERO, + orientation : Quaternion.IDENTITY + })); + + var numVertices = 8; + var numLines = 12; + expect(m.attributes.position.values.length).toEqual(numVertices * 3); + expect(m.indices.length).toEqual(numLines * 2); + + expect(m.boundingSphere.center).toEqual(new Cartesian3(0.0, 0.0, 2.0)); + expect(m.boundingSphere.radius).toBeGreaterThan(1.0); + expect(m.boundingSphere.radius).toBeLessThan(2.0); + }); + + var packableFrustum = new PerspectiveFrustum(); + packableFrustum.fov = 1.0; + packableFrustum.aspectRatio = 2.0; + packableFrustum.near = 3.0; + packableFrustum.far = 4.0; + + createPackableSpecs(FrustumOutlineGeometry, new FrustumOutlineGeometry({ + frustum : packableFrustum, + position : Cartesian3.ZERO, + orientation : Quaternion.IDENTITY, + vertexFormat : VertexFormat.POSITION_ONLY + }), [0.0, 1.0, 2.0, 3.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0]); +}); diff --git a/Specs/Core/OrthographicFrustumSpec.js b/Specs/Core/OrthographicFrustumSpec.js index f40c2ca60fe0..8d52ef011d58 100644 --- a/Specs/Core/OrthographicFrustumSpec.js +++ b/Specs/Core/OrthographicFrustumSpec.js @@ -1,17 +1,19 @@ defineSuite([ - 'Core/OrthographicFrustum', - 'Core/Cartesian2', - 'Core/Cartesian3', - 'Core/Cartesian4', - 'Core/Math', - 'Core/Matrix4' -], function( - OrthographicFrustum, - Cartesian2, - Cartesian3, - Cartesian4, - CesiumMath, - Matrix4) { + 'Core/OrthographicFrustum', + 'Core/Cartesian2', + 'Core/Cartesian3', + 'Core/Cartesian4', + 'Core/Math', + 'Core/Matrix4', + 'Specs/createPackableSpecs' + ], function( + OrthographicFrustum, + Cartesian2, + Cartesian3, + Cartesian4, + CesiumMath, + Matrix4, + createPackableSpecs) { 'use strict'; var frustum, planes; @@ -167,4 +169,11 @@ defineSuite([ expect(frustum2).toBe(result); expect(frustum).toEqual(frustum2); }); + + var packableFrustum = new OrthographicFrustum(); + packableFrustum.width = 1.0; + packableFrustum.aspectRatio = 2.0; + packableFrustum.near = 3.0; + packableFrustum.far = 4.0; + createPackableSpecs(OrthographicFrustum, packableFrustum, [1.0, 2.0, 3.0, 4.0]); }); diff --git a/Specs/Core/PerspectiveFrustumSpec.js b/Specs/Core/PerspectiveFrustumSpec.js index 4a3f37c80085..703d63304c0f 100644 --- a/Specs/Core/PerspectiveFrustumSpec.js +++ b/Specs/Core/PerspectiveFrustumSpec.js @@ -4,14 +4,16 @@ defineSuite([ 'Core/Cartesian3', 'Core/Cartesian4', 'Core/Math', - 'Core/Matrix4' + 'Core/Matrix4', + 'Specs/createPackableSpecs' ], function( PerspectiveFrustum, Cartesian2, Cartesian3, Cartesian4, CesiumMath, - Matrix4) { + Matrix4, + createPackableSpecs) { 'use strict'; var frustum, planes; @@ -172,4 +174,13 @@ defineSuite([ expect(frustum2).toBe(result); expect(frustum).toEqual(frustum2); }); + + var packableFrustum = new PerspectiveFrustum(); + packableFrustum.fov = 1.0; + packableFrustum.aspectRatio = 2.0; + packableFrustum.near = 3.0; + packableFrustum.far = 4.0; + packableFrustum.xOffset = 5.0; + packableFrustum.yOffset = 6.0; + createPackableSpecs(PerspectiveFrustum, packableFrustum, [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]); }); From cf0423a46735fea00ed90600c30f76d1ff7af482 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Wed, 19 Jul 2017 13:18:45 -0400 Subject: [PATCH 101/132] Clone values in constructors --- Source/Scene/Billboard.js | 55 ++++++++++++++++++++++++---------- Source/Scene/Label.js | 55 ++++++++++++++++++++++++---------- Source/Scene/PointPrimitive.js | 43 ++++++++++++++++++-------- 3 files changed, 111 insertions(+), 42 deletions(-) diff --git a/Source/Scene/Billboard.js b/Source/Scene/Billboard.js index 88e8d1870597..56d0fef92103 100644 --- a/Source/Scene/Billboard.js +++ b/Source/Scene/Billboard.js @@ -76,22 +76,47 @@ define([ options = defaultValue(options, defaultValue.EMPTY_OBJECT); //>>includeStart('debug', pragmas.debug); - if (defined(options.scaleByDistance) && options.scaleByDistance.far <= options.scaleByDistance.near) { - throw new DeveloperError('scaleByDistance.far must be greater than scaleByDistance.near.'); + if (defined(options.disableDepthTestDistance) && options.disableDepthTestDistance < 0.0) { + throw new DeveloperError('disableDepthTestDistance must be greater than or equal to 0.0.'); } - if (defined(options.translucencyByDistance) && options.translucencyByDistance.far <= options.translucencyByDistance.near) { - throw new DeveloperError('translucencyByDistance.far must be greater than translucencyByDistance.near.'); + //>>includeEnd('debug'); + + var translucencyByDistance = options.translucencyByDistance; + var pixelOffsetScaleByDistance = options.pixelOffsetScaleByDistance; + var scaleByDistance = options.scaleByDistance; + var distanceDisplayCondition = options.distanceDisplayCondition; + if (defined(translucencyByDistance)) { + //>>includeStart('debug', pragmas.debug); + if (translucencyByDistance.far <= translucencyByDistance.near) { + throw new DeveloperError('translucencyByDistance.far must be greater than translucencyByDistance.near.'); + } + //>>includeEnd('debug'); + translucencyByDistance = NearFarScalar.clone(translucencyByDistance); } - if (defined(options.pixelOffsetScaleByDistance) && options.pixelOffsetScaleByDistance.far <= options.pixelOffsetScaleByDistance.near) { - throw new DeveloperError('pixelOffsetScaleByDistance.far must be greater than pixelOffsetScaleByDistance.near.'); + if (defined(pixelOffsetScaleByDistance)) { + //>>includeStart('debug', pragmas.debug); + if (pixelOffsetScaleByDistance.far <= pixelOffsetScaleByDistance.near) { + throw new DeveloperError('pixelOffsetScaleByDistance.far must be greater than pixelOffsetScaleByDistance.near.'); + } + //>>includeEnd('debug'); + pixelOffsetScaleByDistance = NearFarScalar.clone(pixelOffsetScaleByDistance); } - if (defined(options.distanceDisplayCondition) && options.distanceDisplayCondition.far <= options.distanceDisplayCondition.near) { - throw new DeveloperError('distanceDisplayCondition.far must be greater than distanceDisplayCondition.near'); + if (defined(scaleByDistance)) { + //>>includeStart('debug', pragmas.debug); + if (scaleByDistance.far <= scaleByDistance.near) { + throw new DeveloperError('scaleByDistance.far must be greater than scaleByDistance.near.'); + } + //>>includeEnd('debug'); + scaleByDistance = NearFarScalar.clone(scaleByDistance); } - if (defined(options.disableDepthTestDistance) && options.disableDepthTestDistance < 0.0) { - throw new DeveloperError('disableDepthTestDistance must be greater than or equal to 0.0.'); + if (defined(distanceDisplayCondition)) { + //>>includeStart('debug', pragmas.debug); + if (distanceDisplayCondition.far <= distanceDisplayCondition.near) { + throw new DeveloperError('distanceDisplayCondition.far must be greater than distanceDisplayCondition.near.'); + } + //>>includeEnd('debug'); + distanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition); } - //>>includeEnd('debug'); this._show = defaultValue(options.show, true); this._position = Cartesian3.clone(defaultValue(options.position, Cartesian3.ZERO)); @@ -108,11 +133,11 @@ define([ this._alignedAxis = Cartesian3.clone(defaultValue(options.alignedAxis, Cartesian3.ZERO)); this._width = options.width; this._height = options.height; - this._scaleByDistance = options.scaleByDistance; - this._translucencyByDistance = options.translucencyByDistance; - this._pixelOffsetScaleByDistance = options.pixelOffsetScaleByDistance; + this._scaleByDistance = scaleByDistance; + this._translucencyByDistance = translucencyByDistance; + this._pixelOffsetScaleByDistance = pixelOffsetScaleByDistance; this._sizeInMeters = defaultValue(options.sizeInMeters, false); - this._distanceDisplayCondition = options.distanceDisplayCondition; + this._distanceDisplayCondition = distanceDisplayCondition; this._disableDepthTestDistance = defaultValue(options.disableDepthTestDistance, 0.0); this._id = options.id; this._collection = defaultValue(options.collection, billboardCollection); diff --git a/Source/Scene/Label.js b/Source/Scene/Label.js index b48b4be9a051..813522182a0e 100644 --- a/Source/Scene/Label.js +++ b/Source/Scene/Label.js @@ -68,22 +68,47 @@ define([ options = defaultValue(options, defaultValue.EMPTY_OBJECT); //>>includeStart('debug', pragmas.debug); - if (defined(options.translucencyByDistance) && options.translucencyByDistance.far <= options.translucencyByDistance.near) { - throw new DeveloperError('translucencyByDistance.far must be greater than translucencyByDistance.near.'); + if (defined(options.disableDepthTestDistance) && options.disableDepthTestDistance < 0.0) { + throw new DeveloperError('disableDepthTestDistance must be greater than 0.0.'); } - if (defined(options.pixelOffsetScaleByDistance) && options.pixelOffsetScaleByDistance.far <= options.pixelOffsetScaleByDistance.near) { - throw new DeveloperError('pixelOffsetScaleByDistance.far must be greater than pixelOffsetScaleByDistance.near.'); + //>>includeEnd('debug'); + + var translucencyByDistance = options.translucencyByDistance; + var pixelOffsetScaleByDistance = options.pixelOffsetScaleByDistance; + var scaleByDistance = options.scaleByDistance; + var distanceDisplayCondition = options.distanceDisplayCondition; + if (defined(translucencyByDistance)) { + //>>includeStart('debug', pragmas.debug); + if (translucencyByDistance.far <= translucencyByDistance.near) { + throw new DeveloperError('translucencyByDistance.far must be greater than translucencyByDistance.near.'); + } + //>>includeEnd('debug'); + translucencyByDistance = NearFarScalar.clone(translucencyByDistance); } - if (defined(options.scaleByDistance) && options.scaleByDistance.far <= options.scaleByDistance.near) { - throw new DeveloperError('scaleByDistance.far must be greater than scaleByDistance.near.'); + if (defined(pixelOffsetScaleByDistance)) { + //>>includeStart('debug', pragmas.debug); + if (pixelOffsetScaleByDistance.far <= pixelOffsetScaleByDistance.near) { + throw new DeveloperError('pixelOffsetScaleByDistance.far must be greater than pixelOffsetScaleByDistance.near.'); + } + //>>includeEnd('debug'); + pixelOffsetScaleByDistance = NearFarScalar.clone(pixelOffsetScaleByDistance); } - if (defined(options.distanceDisplayCondition) && options.distanceDisplayCondition.far <= options.distanceDisplayCondition.near) { - throw new DeveloperError('distanceDisplayCondition.far must be greater than distanceDisplayCondition.near'); + if (defined(scaleByDistance)) { + //>>includeStart('debug', pragmas.debug); + if (scaleByDistance.far <= scaleByDistance.near) { + throw new DeveloperError('scaleByDistance.far must be greater than scaleByDistance.near.'); + } + //>>includeEnd('debug'); + scaleByDistance = NearFarScalar.clone(scaleByDistance); } - if (defined(options.disableDepthTestDistance) && options.disableDepthTestDistance < 0.0) { - throw new DeveloperError('disableDepthTestDistance must be greater than 0.0.'); + if (defined(distanceDisplayCondition)) { + //>>includeStart('debug', pragmas.debug); + if (distanceDisplayCondition.far <= distanceDisplayCondition.near) { + throw new DeveloperError('distanceDisplayCondition.far must be greater than distanceDisplayCondition.near.'); + } + //>>includeEnd('debug'); + distanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition); } - //>>includeEnd('debug'); this._text = defaultValue(options.text, ''); this._show = defaultValue(options.show, true); @@ -102,11 +127,11 @@ define([ this._position = Cartesian3.clone(defaultValue(options.position, Cartesian3.ZERO)); this._scale = defaultValue(options.scale, 1.0); this._id = options.id; - this._translucencyByDistance = options.translucencyByDistance; - this._pixelOffsetScaleByDistance = options.pixelOffsetScaleByDistance; - this._scaleByDistance = options.scaleByDistance; + this._translucencyByDistance = translucencyByDistance; + this._pixelOffsetScaleByDistance = pixelOffsetScaleByDistance; + this._scaleByDistance = scaleByDistance; this._heightReference = defaultValue(options.heightReference, HeightReference.NONE); - this._distanceDisplayCondition = options.distanceDisplayCondition; + this._distanceDisplayCondition = distanceDisplayCondition; this._disableDepthTestDistance = defaultValue(options.disableDepthTestDistance, 0.0); this._labelCollection = labelCollection; diff --git a/Source/Scene/PointPrimitive.js b/Source/Scene/PointPrimitive.js index 088f03b61dfa..b4e18e8eed9a 100644 --- a/Source/Scene/PointPrimitive.js +++ b/Source/Scene/PointPrimitive.js @@ -59,20 +59,39 @@ define([ options = defaultValue(options, defaultValue.EMPTY_OBJECT); //>>includeStart('debug', pragmas.debug); - if (defined(options.scaleByDistance) && options.scaleByDistance.far <= options.scaleByDistance.near) { - throw new DeveloperError('scaleByDistance.far must be greater than scaleByDistance.near.'); - } - if (defined(options.translucencyByDistance) && options.translucencyByDistance.far <= options.translucencyByDistance.near) { - throw new DeveloperError('translucencyByDistance.far must be greater than translucencyByDistance.near.'); - } - if (defined(options.distanceDisplayCondition) && options.distanceDisplayCondition.far <= options.distanceDisplayCondition.near) { - throw new DeveloperError('distanceDisplayCondition.far must be greater than distanceDisplayCondition.near'); - } if (defined(options.disableDepthTestDistance) && options.disableDepthTestDistance < 0.0) { throw new DeveloperError('disableDepthTestDistance must be greater than or equal to 0.0.'); } //>>includeEnd('debug'); + var translucencyByDistance = options.translucencyByDistance; + var scaleByDistance = options.scaleByDistance; + var distanceDisplayCondition = options.distanceDisplayCondition; + if (defined(translucencyByDistance)) { + //>>includeStart('debug', pragmas.debug); + if (translucencyByDistance.far <= translucencyByDistance.near) { + throw new DeveloperError('translucencyByDistance.far must be greater than translucencyByDistance.near.'); + } + //>>includeEnd('debug'); + translucencyByDistance = NearFarScalar.clone(translucencyByDistance); + } + if (defined(scaleByDistance)) { + //>>includeStart('debug', pragmas.debug); + if (scaleByDistance.far <= scaleByDistance.near) { + throw new DeveloperError('scaleByDistance.far must be greater than scaleByDistance.near.'); + } + //>>includeEnd('debug'); + scaleByDistance = NearFarScalar.clone(scaleByDistance); + } + if (defined(distanceDisplayCondition)) { + //>>includeStart('debug', pragmas.debug); + if (distanceDisplayCondition.far <= distanceDisplayCondition.near) { + throw new DeveloperError('distanceDisplayCondition.far must be greater than distanceDisplayCondition.near.'); + } + //>>includeEnd('debug'); + distanceDisplayCondition = DistanceDisplayCondition.clone(distanceDisplayCondition); + } + this._show = defaultValue(options.show, true); this._position = Cartesian3.clone(defaultValue(options.position, Cartesian3.ZERO)); this._actualPosition = Cartesian3.clone(this._position); // For columbus view and 2D @@ -80,9 +99,9 @@ define([ this._outlineColor = Color.clone(defaultValue(options.outlineColor, Color.TRANSPARENT)); this._outlineWidth = defaultValue(options.outlineWidth, 0.0); this._pixelSize = defaultValue(options.pixelSize, 10.0); - this._scaleByDistance = options.scaleByDistance; - this._translucencyByDistance = options.translucencyByDistance; - this._distanceDisplayCondition = options.distanceDisplayCondition; + this._scaleByDistance = scaleByDistance; + this._translucencyByDistance = translucencyByDistance; + this._distanceDisplayCondition = distanceDisplayCondition; this._disableDepthTestDistance = defaultValue(options.disableDepthTestDistance, 0.0); this._id = options.id; this._collection = defaultValue(options.collection, pointPrimitiveCollection); From b9d7b45b580e01850bcdcdf444c30e065e6e947d Mon Sep 17 00:00:00 2001 From: hpinkos Date: Wed, 19 Jul 2017 13:44:16 -0400 Subject: [PATCH 102/132] Add setter for GeoJsonDataSource.name --- CHANGES.md | 1 + Source/DataSources/GeoJsonDataSource.js | 6 ++++++ Specs/DataSources/GeoJsonDataSourceSpec.js | 13 +++++++++++++ 3 files changed, 20 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index e06889b90fa6..826f7eee1471 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ Change Log * Added ability to show tile urls in the 3D Tiles Inspector. [#5592](https://github.com/AnalyticalGraphicsInc/cesium/pull/5592) * Added behavior to `Cesium3DTilesInspector` that selects the first tileset hovered over if no tilest is specified. [#5139](https://github.com/AnalyticalGraphicsInc/cesium/issues/5139) * Added ability to provide a `width` and `height` to `scene.pick`. [#5602](https://github.com/AnalyticalGraphicsInc/cesium/pull/5602) +* Added setter for `GeoJsonDataSource.name` to specify a name for the datasource [#5653](https://github.com/AnalyticalGraphicsInc/cesium/issues/5653) * Fixed issue where scene would blink when labels were added. [#5537](https://github.com/AnalyticalGraphicsInc/cesium/issues/5537) * Fixed label positioning when height reference changes [#5609](https://github.com/AnalyticalGraphicsInc/cesium/issues/5609) * Fixed crash when using the `Cesium3DTilesInspectorViewModel` and removing a tileset [#5607](https://github.com/AnalyticalGraphicsInc/cesium/issues/5607) diff --git a/Source/DataSources/GeoJsonDataSource.js b/Source/DataSources/GeoJsonDataSource.js index 2123486fcb1c..4fe2a5eec8fc 100644 --- a/Source/DataSources/GeoJsonDataSource.js +++ b/Source/DataSources/GeoJsonDataSource.js @@ -690,6 +690,12 @@ define([ name : { get : function() { return this._name; + }, + set : function(value) { + if (this._name !== value) { + this._name = value; + this._changed.raiseEvent(this); + } } }, /** diff --git a/Specs/DataSources/GeoJsonDataSourceSpec.js b/Specs/DataSources/GeoJsonDataSourceSpec.js index a19097e85205..18fd511998bd 100644 --- a/Specs/DataSources/GeoJsonDataSourceSpec.js +++ b/Specs/DataSources/GeoJsonDataSourceSpec.js @@ -279,6 +279,19 @@ defineSuite([ expect(dataSource.show).toBe(true); }); + it('setting name raises changed event', function() { + var dataSource = new GeoJsonDataSource(); + + var spy = jasmine.createSpy('changedEvent'); + dataSource.changedEvent.addEventListener(spy); + + var newName = 'chester'; + dataSource.name = newName; + expect(dataSource.name).toEqual(newName); + expect(spy.calls.count()).toEqual(1); + expect(spy).toHaveBeenCalledWith(dataSource); + }); + it('show sets underlying entity collection show.', function() { var dataSource = new GeoJsonDataSource(); From b146e77c303b5113e019c040595f9a34838c6c00 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Wed, 19 Jul 2017 13:59:44 -0400 Subject: [PATCH 103/132] doc --- Source/DataSources/GeoJsonDataSource.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/DataSources/GeoJsonDataSource.js b/Source/DataSources/GeoJsonDataSource.js index 4fe2a5eec8fc..854760323b76 100644 --- a/Source/DataSources/GeoJsonDataSource.js +++ b/Source/DataSources/GeoJsonDataSource.js @@ -683,7 +683,7 @@ define([ defineProperties(GeoJsonDataSource.prototype, { /** - * Gets a human-readable name for this instance. + * Gets or sets a human-readable name for this instance. * @memberof GeoJsonDataSource.prototype * @type {String} */ From 3cbf6c11f414f54f989687bc94253952946d4cf6 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Wed, 19 Jul 2017 14:17:24 -0400 Subject: [PATCH 104/132] Remove model height callback on destroy --- Source/Scene/Model.js | 5 +++++ Specs/Scene/ModelSpec.js | 18 +++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 06425037b1f8..2ff7c56c6fa2 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -4764,6 +4764,11 @@ define([ destroy(this._rendererResources.vertexArrays); } + if (defined(this._removeUpdateHeightCallback)) { + this._removeUpdateHeightCallback(); + this._removeUpdateHeightCallback = undefined; + } + this._rendererResources = undefined; this._cachedRendererResources = this._cachedRendererResources && this._cachedRendererResources.release(); diff --git a/Specs/Scene/ModelSpec.js b/Specs/Scene/ModelSpec.js index 87f7a76c5346..c7dd2dfec270 100644 --- a/Specs/Scene/ModelSpec.js +++ b/Specs/Scene/ModelSpec.js @@ -2521,6 +2521,23 @@ defineSuite([ }); }); + it('removes the callback on destroy', function() { + scene.globe = createMockGlobe(); + return loadModelJson(texturedBoxModel.gltf, { + heightReference : HeightReference.CLAMP_TO_GROUND, + position : Cartesian3.fromDegrees(-72.0, 40.0), + scene : scene, + show : true + }).then(function(model) { + expect(scene.globe.callback).toBeDefined(); + scene.renderForSpecs(); + + primitives.remove(model); + scene.renderForSpecs(); + expect(scene.globe.callback).toBeUndefined(); + }); + }); + it('changing the terrain provider', function() { scene.globe = createMockGlobe(); return loadModelJson(texturedBoxModel.gltf, { @@ -2566,5 +2583,4 @@ defineSuite([ }); }); }); - }, 'WebGL'); From d6d08496c148ebc2fd9031be983a22d240558cc7 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 19 Jul 2017 15:49:04 -0400 Subject: [PATCH 105/132] Add options parameter to constructors for *Frustum classes. --- .../gallery/development/Frustum.html | 11 ++--- Source/Core/OrthographicFrustum.js | 18 +++++--- Source/Core/OrthographicOffCenterFrustum.js | 26 ++++++++--- Source/Core/PerspectiveFrustum.js | 34 +++++++++----- Source/Core/PerspectiveOffCenterFrustum.js | 40 +++++++++++------ Source/Scene/OrthographicFrustum.js | 4 +- Source/Scene/OrthographicOffCenterFrustum.js | 4 +- Source/Scene/PerspectiveFrustum.js | 4 +- Source/Scene/PerspectiveOffCenterFrustum.js | 4 +- Specs/Core/OrthographicFrustumSpec.js | 36 ++++++++++++--- .../Core/OrthographicOffCenterFrustumSpec.js | 26 +++++++++++ Specs/Core/PerspectiveFrustumSpec.js | 44 +++++++++++++++---- Specs/Core/PerspectiveOffCenterFrustumSpec.js | 26 +++++++++++ 13 files changed, 212 insertions(+), 65 deletions(-) diff --git a/Apps/Sandcastle/gallery/development/Frustum.html b/Apps/Sandcastle/gallery/development/Frustum.html index 96d99ffe1b42..0e6e1bf979a9 100644 --- a/Apps/Sandcastle/gallery/development/Frustum.html +++ b/Apps/Sandcastle/gallery/development/Frustum.html @@ -39,11 +39,12 @@ Cesium.Matrix3.multiply(rotation, Cesium.Matrix3.fromRotationX(-Cesium.Math.PI_OVER_TWO), rotation); var orientation = Cesium.Quaternion.fromRotationMatrix(rotation); -var frustum = new Cesium.PerspectiveFrustum(); -frustum.fov = Cesium.Math.toRadians(60.0); -frustum.aspectRatio = scene.canvas.clientWidth / scene.canvas.clientHeight; -frustum.near = 10.0; -frustum.far = 50.0; +var frustum = new Cesium.PerspectiveFrustum({ + fov : Cesium.Math.toRadians(60.0), + aspectRatio : scene.canvas.clientWidth / scene.canvas.clientHeight, + near : 10.0, + far : 50.0 +}); var frustumGeometry = new Cesium.FrustumGeometry({ frustum : frustum, diff --git a/Source/Core/OrthographicFrustum.js b/Source/Core/OrthographicFrustum.js index c308f3117180..b3377b99fde1 100644 --- a/Source/Core/OrthographicFrustum.js +++ b/Source/Core/OrthographicFrustum.js @@ -23,6 +23,12 @@ define([ * @alias OrthographicFrustum * @constructor * + * @param {Object} [options] An object with the following properties: + * @param {Number} [options.width] The width of the frustum in meters. + * @param {Number} [options.aspectRatio] The aspect ratio of the frustum's width to it's height. + * @param {Number} [options.near=1.0] The distance of the near plane. + * @param {Number} [options.far=500000000.0] The distance of the far plane. + * * @example * var maxRadii = ellipsoid.maximumRadius; * @@ -30,7 +36,9 @@ define([ * frustum.near = 0.01 * maxRadii; * frustum.far = 50.0 * maxRadii; */ - function OrthographicFrustum() { + function OrthographicFrustum(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + this._offCenterFrustum = new OrthographicOffCenterFrustum(); /** @@ -38,7 +46,7 @@ define([ * @type {Number} * @default undefined */ - this.width = undefined; + this.width = options.width; this._width = undefined; /** @@ -46,7 +54,7 @@ define([ * @type {Number} * @default undefined */ - this.aspectRatio = undefined; + this.aspectRatio = options.aspectRatio; this._aspectRatio = undefined; /** @@ -54,7 +62,7 @@ define([ * @type {Number} * @default 1.0 */ - this.near = 1.0; + this.near = defaultValue(options.near, 1.0); this._near = this.near; /** @@ -62,7 +70,7 @@ define([ * @type {Number} * @default 500000000.0; */ - this.far = 500000000.0; + this.far = defaultValue(options.far, 500000000.0); this._far = this.far; } diff --git a/Source/Core/OrthographicOffCenterFrustum.js b/Source/Core/OrthographicOffCenterFrustum.js index dff8404b5a3d..63dd0c40dfbf 100644 --- a/Source/Core/OrthographicOffCenterFrustum.js +++ b/Source/Core/OrthographicOffCenterFrustum.js @@ -2,6 +2,7 @@ define([ './Cartesian3', './Cartesian4', './CullingVolume', + './defaultValue', './defined', './defineProperties', './DeveloperError', @@ -10,6 +11,7 @@ define([ Cartesian3, Cartesian4, CullingVolume, + defaultValue, defined, defineProperties, DeveloperError, @@ -25,6 +27,14 @@ define([ * @alias OrthographicOffCenterFrustum * @constructor * + * @param {Object} [options] An object with the following properties: + * @param {Number} [options.left] The left clipping plane distance. + * @param {Number} [options.right] The right clipping plane distance. + * @param {Number} [options.top] The top clipping plane distance. + * @param {Number} [options.bottom] The bottom clipping plane distance. + * @param {Number} [options.near=1.0] The near clipping plane distance. + * @param {Number} [options.far=500000000.0] The far clipping plane distance. + * * @example * var maxRadii = ellipsoid.maximumRadius; * @@ -36,13 +46,15 @@ define([ * frustum.near = 0.01 * maxRadii; * frustum.far = 50.0 * maxRadii; */ - function OrthographicOffCenterFrustum() { + function OrthographicOffCenterFrustum(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + /** * The left clipping plane. * @type {Number} * @default undefined */ - this.left = undefined; + this.left = options.left; this._left = undefined; /** @@ -50,7 +62,7 @@ define([ * @type {Number} * @default undefined */ - this.right = undefined; + this.right = options.right; this._right = undefined; /** @@ -58,7 +70,7 @@ define([ * @type {Number} * @default undefined */ - this.top = undefined; + this.top = options.top; this._top = undefined; /** @@ -66,7 +78,7 @@ define([ * @type {Number} * @default undefined */ - this.bottom = undefined; + this.bottom = options.bottom; this._bottom = undefined; /** @@ -74,7 +86,7 @@ define([ * @type {Number} * @default 1.0 */ - this.near = 1.0; + this.near = defaultValue(options.near, 1.0); this._near = this.near; /** @@ -82,7 +94,7 @@ define([ * @type {Number} * @default 500000000.0; */ - this.far = 500000000.0; + this.far = defaultValue(options.far, 500000000.0); this._far = this.far; this._cullingVolume = new CullingVolume(); diff --git a/Source/Core/PerspectiveFrustum.js b/Source/Core/PerspectiveFrustum.js index d0d40c84e5ec..5926554f69dc 100644 --- a/Source/Core/PerspectiveFrustum.js +++ b/Source/Core/PerspectiveFrustum.js @@ -23,17 +23,27 @@ define([ * @alias PerspectiveFrustum * @constructor * + * @param {Object} [options] An object with the following properties: + * @param {Number} [options.fov] The angle of the field of view (FOV), in radians. + * @param {Number} [options.aspectRatio] The aspect ratio of the frustum's width to it's height. + * @param {Number} [options.near=1.0] The distance of the near plane. + * @param {Number} [options.far=500000000.0] The distance of the far plane. + * @param {Number} [options.xOffset=0.0] The offset in the x direction. + * @param {Number} [options.yOffset=0.0] The offset in the y direction. * * @example - * var frustum = new Cesium.PerspectiveFrustum(); - * frustum.aspectRatio = canvas.clientWidth / canvas.clientHeight; - * frustum.fov = Cesium.Math.PI_OVER_THREE; - * frustum.near = 1.0; - * frustum.far = 2.0; + * var frustum = new Cesium.PerspectiveFrustum({ + * fov : Cesium.Math.PI_OVER_THREE, + * aspectRatio : canvas.clientWidth / canvas.clientHeight + * near : 1.0, + * far : 1000.0 + * }); * * @see PerspectiveOffCenterFrustum */ - function PerspectiveFrustum() { + function PerspectiveFrustum(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + this._offCenterFrustum = new PerspectiveOffCenterFrustum(); /** @@ -43,7 +53,7 @@ define([ * @type {Number} * @default undefined */ - this.fov = undefined; + this.fov = options.fov; this._fov = undefined; this._fovy = undefined; @@ -54,7 +64,7 @@ define([ * @type {Number} * @default undefined */ - this.aspectRatio = undefined; + this.aspectRatio = options.aspectRatio; this._aspectRatio = undefined; /** @@ -62,7 +72,7 @@ define([ * @type {Number} * @default 1.0 */ - this.near = 1.0; + this.near = defaultValue(options.near, 1.0); this._near = this.near; /** @@ -70,7 +80,7 @@ define([ * @type {Number} * @default 500000000.0 */ - this.far = 500000000.0; + this.far = defaultValue(options.far, 500000000.0); this._far = this.far; /** @@ -78,7 +88,7 @@ define([ * @type {Number} * @default 0.0 */ - this.xOffset = 0.0; + this.xOffset = defaultValue(options.xOffset, 0.0); this._xOffset = this.xOffset; /** @@ -86,7 +96,7 @@ define([ * @type {Number} * @default 0.0 */ - this.yOffset = 0.0; + this.yOffset = defaultValue(options.yOffset, 0.0); this._yOffset = this.yOffset; } diff --git a/Source/Core/PerspectiveOffCenterFrustum.js b/Source/Core/PerspectiveOffCenterFrustum.js index 6792faa4e98f..7b031d85e77c 100644 --- a/Source/Core/PerspectiveOffCenterFrustum.js +++ b/Source/Core/PerspectiveOffCenterFrustum.js @@ -2,6 +2,7 @@ define([ './Cartesian3', './Cartesian4', './CullingVolume', + './defaultValue', './defined', './defineProperties', './DeveloperError', @@ -10,6 +11,7 @@ define([ Cartesian3, Cartesian4, CullingVolume, + defaultValue, defined, defineProperties, DeveloperError, @@ -25,25 +27,35 @@ define([ * @alias PerspectiveOffCenterFrustum * @constructor * + * @param {Object} [options] An object with the following properties: + * @param {Number} [options.left] The left clipping plane distance. + * @param {Number} [options.right] The right clipping plane distance. + * @param {Number} [options.top] The top clipping plane distance. + * @param {Number} [options.bottom] The bottom clipping plane distance. + * @param {Number} [options.near=1.0] The near clipping plane distance. + * @param {Number} [options.far=500000000.0] The far clipping plane distance. * * @example - * var frustum = new Cesium.PerspectiveOffCenterFrustum(); - * frustum.right = 1.0; - * frustum.left = -1.0; - * frustum.top = 1.0; - * frustum.bottom = -1.0; - * frustum.near = 1.0; - * frustum.far = 2.0; + * var frustum = new Cesium.PerspectiveOffCenterFrustum({ + * left : -1.0, + * right : 1.0, + * top : 1.0, + * bottom : -1.0, + * near : 1.0, + * far : 100.0 + * }); * * @see PerspectiveFrustum */ - function PerspectiveOffCenterFrustum() { + function PerspectiveOffCenterFrustum(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + /** * Defines the left clipping plane. * @type {Number} * @default undefined */ - this.left = undefined; + this.left = options.left; this._left = undefined; /** @@ -51,7 +63,7 @@ define([ * @type {Number} * @default undefined */ - this.right = undefined; + this.right = options.right; this._right = undefined; /** @@ -59,7 +71,7 @@ define([ * @type {Number} * @default undefined */ - this.top = undefined; + this.top = options.top; this._top = undefined; /** @@ -67,7 +79,7 @@ define([ * @type {Number} * @default undefined */ - this.bottom = undefined; + this.bottom = options.bottom; this._bottom = undefined; /** @@ -75,7 +87,7 @@ define([ * @type {Number} * @default 1.0 */ - this.near = 1.0; + this.near = defaultValue(options.near, 1.0); this._near = this.near; /** @@ -83,7 +95,7 @@ define([ * @type {Number} * @default 500000000.0 */ - this.far = 500000000.0; + this.far = defaultValue(options.far, 500000000.0); this._far = this.far; this._cullingVolume = new CullingVolume(); diff --git a/Source/Scene/OrthographicFrustum.js b/Source/Scene/OrthographicFrustum.js index 057b9d80fa11..bbb36ec006ac 100644 --- a/Source/Scene/OrthographicFrustum.js +++ b/Source/Scene/OrthographicFrustum.js @@ -6,9 +6,9 @@ define([ OrthographicFrustum) { 'use strict'; - function DeprecatedOrthographicFrustum() { + function DeprecatedOrthographicFrustum(options) { deprecationWarning('OrthographicFrustum', 'Scene/OrthographicFrustum is deprecated. It has moved to Core/OrthographicFrustum in 1.36. Scene/OrthographicFrustum will be removed in 1.38.'); - return new OrthographicFrustum(); + return new OrthographicFrustum(options); } return DeprecatedOrthographicFrustum; diff --git a/Source/Scene/OrthographicOffCenterFrustum.js b/Source/Scene/OrthographicOffCenterFrustum.js index 93a9f14edf45..54d53cf14321 100644 --- a/Source/Scene/OrthographicOffCenterFrustum.js +++ b/Source/Scene/OrthographicOffCenterFrustum.js @@ -6,9 +6,9 @@ define([ OrthographicOffCenterFrustum) { 'use strict'; - function DeprecatedOrthographicOffCenterFrustum() { + function DeprecatedOrthographicOffCenterFrustum(options) { deprecationWarning('OrthographicOffCenterFrustum', 'Scene/OrthographicOffCenterFrustum is deprecated. It has moved to Core/OrthographicOffCenterFrustum in 1.36. Scene/OrthographicOffCenterFrustum will be removed in 1.38.'); - return new OrthographicOffCenterFrustum(); + return new OrthographicOffCenterFrustum(options); } return DeprecatedOrthographicOffCenterFrustum; diff --git a/Source/Scene/PerspectiveFrustum.js b/Source/Scene/PerspectiveFrustum.js index c2ae3b511fa5..5030940f5c5c 100644 --- a/Source/Scene/PerspectiveFrustum.js +++ b/Source/Scene/PerspectiveFrustum.js @@ -6,9 +6,9 @@ define([ PerspectiveFrustum) { 'use strict'; - function DeprecatedPerspectiveFrustum() { + function DeprecatedPerspectiveFrustum(options) { deprecationWarning('PerspectiveFrustum', 'Scene/PerspectiveFrustum is deprecated. It has moved to Core/PerspectiveFrustum in 1.36. Scene/PerspectiveFrustum will be removed in 1.38.'); - return new PerspectiveFrustum(); + return new PerspectiveFrustum(options); } return DeprecatedPerspectiveFrustum; diff --git a/Source/Scene/PerspectiveOffCenterFrustum.js b/Source/Scene/PerspectiveOffCenterFrustum.js index 4953638ef85d..e8496b4ef925 100644 --- a/Source/Scene/PerspectiveOffCenterFrustum.js +++ b/Source/Scene/PerspectiveOffCenterFrustum.js @@ -6,9 +6,9 @@ define([ PerspectiveOffCenterFrustum) { 'use strict'; - function DeprecatedPerspectiveOffCenterFrustum() { + function DeprecatedPerspectiveOffCenterFrustum(options) { deprecationWarning('PerspectiveOffCenterFrustum', 'Scene/PerspectiveOffCenterFrustum is deprecated. It has moved to Core/PerspectiveOffCenterFrustum in 1.36. Scene/PerspectiveOffCenterFrustum will be removed in 1.38.'); - return new PerspectiveOffCenterFrustum(); + return new PerspectiveOffCenterFrustum(options); } return DeprecatedPerspectiveOffCenterFrustum; diff --git a/Specs/Core/OrthographicFrustumSpec.js b/Specs/Core/OrthographicFrustumSpec.js index 8d52ef011d58..4ac99bd4e0ec 100644 --- a/Specs/Core/OrthographicFrustumSpec.js +++ b/Specs/Core/OrthographicFrustumSpec.js @@ -27,6 +27,30 @@ defineSuite([ planes = frustum.computeCullingVolume(new Cartesian3(), Cartesian3.negate(Cartesian3.UNIT_Z, new Cartesian3()), Cartesian3.UNIT_Y).planes; }); + it('constructs', function() { + var options = { + width : 1.0, + aspectRatio : 2.0, + near : 3.0, + far : 4.0, + xOffset : 5.0, + yOffset : 6.0 + }; + var f = new OrthographicFrustum(options); + expect(f.width).toEqual(options.width); + expect(f.aspectRatio).toEqual(options.aspectRatio); + expect(f.near).toEqual(options.near); + expect(f.far).toEqual(options.far); + }); + + it('default constructs', function() { + var f = new OrthographicFrustum(); + expect(f.width).toBeUndefined(); + expect(f.aspectRatio).toBeUndefined(); + expect(f.near).toEqual(1.0); + expect(f.far).toEqual(500000000.0); + }); + it('undefined width causes an exception', function() { frustum.width = undefined; expect(function() { @@ -170,10 +194,10 @@ defineSuite([ expect(frustum).toEqual(frustum2); }); - var packableFrustum = new OrthographicFrustum(); - packableFrustum.width = 1.0; - packableFrustum.aspectRatio = 2.0; - packableFrustum.near = 3.0; - packableFrustum.far = 4.0; - createPackableSpecs(OrthographicFrustum, packableFrustum, [1.0, 2.0, 3.0, 4.0]); + createPackableSpecs(OrthographicFrustum, new OrthographicFrustum({ + width : 1.0, + aspectRatio : 2.0, + near : 3.0, + far : 4.0 + }), [1.0, 2.0, 3.0, 4.0]); }); diff --git a/Specs/Core/OrthographicOffCenterFrustumSpec.js b/Specs/Core/OrthographicOffCenterFrustumSpec.js index 176024388cba..a81c88f087dc 100644 --- a/Specs/Core/OrthographicOffCenterFrustumSpec.js +++ b/Specs/Core/OrthographicOffCenterFrustumSpec.js @@ -27,6 +27,32 @@ defineSuite([ planes = frustum.computeCullingVolume(new Cartesian3(), Cartesian3.negate(Cartesian3.UNIT_Z, new Cartesian3()), Cartesian3.UNIT_Y).planes; }); + it('constructs', function() { + var options = { + left : -1.0, + right : 2.0, + top : 5.0, + bottom : -1.0, + near : 3.0, + far : 4.0 + }; + var f = new OrthographicOffCenterFrustum(options); + expect(f.width).toEqual(options.width); + expect(f.aspectRatio).toEqual(options.aspectRatio); + expect(f.near).toEqual(options.near); + expect(f.far).toEqual(options.far); + }); + + it('default constructs', function() { + var f = new OrthographicOffCenterFrustum(); + expect(f.left).toBeUndefined(); + expect(f.right).toBeUndefined(); + expect(f.top).toBeUndefined(); + expect(f.bottom).toBeUndefined(); + expect(f.near).toEqual(1.0); + expect(f.far).toEqual(500000000.0); + }); + it('left greater than right causes an exception', function() { frustum.left = frustum.right + 1.0; expect(function() { diff --git a/Specs/Core/PerspectiveFrustumSpec.js b/Specs/Core/PerspectiveFrustumSpec.js index 703d63304c0f..7682b09d6ffc 100644 --- a/Specs/Core/PerspectiveFrustumSpec.js +++ b/Specs/Core/PerspectiveFrustumSpec.js @@ -27,6 +27,34 @@ defineSuite([ planes = frustum.computeCullingVolume(new Cartesian3(), Cartesian3.negate(Cartesian3.UNIT_Z, new Cartesian3()), Cartesian3.UNIT_Y).planes; }); + it('constructs', function() { + var options = { + fov : 1.0, + aspectRatio : 2.0, + near : 3.0, + far : 4.0, + xOffset : 5.0, + yOffset : 6.0 + }; + var f = new PerspectiveFrustum(options); + expect(f.fov).toEqual(options.fov); + expect(f.aspectRatio).toEqual(options.aspectRatio); + expect(f.near).toEqual(options.near); + expect(f.far).toEqual(options.far); + expect(f.xOffset).toEqual(options.xOffset); + expect(f.yOffset).toEqual(options.yOffset); + }); + + it('default constructs', function() { + var f = new PerspectiveFrustum(); + expect(f.fov).toBeUndefined(); + expect(f.aspectRatio).toBeUndefined(); + expect(f.near).toEqual(1.0); + expect(f.far).toEqual(500000000.0); + expect(f.xOffset).toEqual(0.0); + expect(f.yOffset).toEqual(0.0); + }); + it('out of range fov causes an exception', function() { frustum.fov = -1.0; expect(function() { @@ -175,12 +203,12 @@ defineSuite([ expect(frustum).toEqual(frustum2); }); - var packableFrustum = new PerspectiveFrustum(); - packableFrustum.fov = 1.0; - packableFrustum.aspectRatio = 2.0; - packableFrustum.near = 3.0; - packableFrustum.far = 4.0; - packableFrustum.xOffset = 5.0; - packableFrustum.yOffset = 6.0; - createPackableSpecs(PerspectiveFrustum, packableFrustum, [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]); + createPackableSpecs(PerspectiveFrustum, new PerspectiveFrustum({ + fov : 1.0, + aspectRatio : 2.0, + near : 3.0, + far : 4.0, + xOffset : 5.0, + yOffset : 6.0 + }), [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]); }); diff --git a/Specs/Core/PerspectiveOffCenterFrustumSpec.js b/Specs/Core/PerspectiveOffCenterFrustumSpec.js index 01df32c6eec0..937f0d2a499f 100644 --- a/Specs/Core/PerspectiveOffCenterFrustumSpec.js +++ b/Specs/Core/PerspectiveOffCenterFrustumSpec.js @@ -27,6 +27,32 @@ defineSuite([ planes = frustum.computeCullingVolume(new Cartesian3(), Cartesian3.negate(Cartesian3.UNIT_Z, new Cartesian3()), Cartesian3.UNIT_Y).planes; }); + it('constructs', function() { + var options = { + left : -1.0, + right : 2.0, + top : 5.0, + bottom : -1.0, + near : 3.0, + far : 4.0 + }; + var f = new PerspectiveOffCenterFrustum(options); + expect(f.width).toEqual(options.width); + expect(f.aspectRatio).toEqual(options.aspectRatio); + expect(f.near).toEqual(options.near); + expect(f.far).toEqual(options.far); + }); + + it('default constructs', function() { + var f = new PerspectiveOffCenterFrustum(); + expect(f.left).toBeUndefined(); + expect(f.right).toBeUndefined(); + expect(f.top).toBeUndefined(); + expect(f.bottom).toBeUndefined(); + expect(f.near).toEqual(1.0); + expect(f.far).toEqual(500000000.0); + }); + it('out of range near plane throws an exception', function() { frustum.near = -1.0; expect(function() { From fbb2efe4d6ee4bdbca2950930ce9ec85bd73ad24 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 19 Jul 2017 15:56:59 -0400 Subject: [PATCH 106/132] Rename frustum position to orientation. --- .../gallery/development/Frustum.html | 4 +-- Source/Core/FrustumGeometry.js | 32 +++++++++++-------- Source/Core/FrustumOutlineGeometry.js | 32 +++++++++++-------- 3 files changed, 38 insertions(+), 30 deletions(-) diff --git a/Apps/Sandcastle/gallery/development/Frustum.html b/Apps/Sandcastle/gallery/development/Frustum.html index 0e6e1bf979a9..7f688433d8f6 100644 --- a/Apps/Sandcastle/gallery/development/Frustum.html +++ b/Apps/Sandcastle/gallery/development/Frustum.html @@ -48,7 +48,7 @@ var frustumGeometry = new Cesium.FrustumGeometry({ frustum : frustum, - position : positionOnEllipsoid, + origin : positionOnEllipsoid, orientation : orientation, vertexFormat : Cesium.VertexFormat.POSITION_ONLY }); @@ -72,7 +72,7 @@ geometryInstances : new Cesium.GeometryInstance({ geometry : new Cesium.FrustumOutlineGeometry({ frustum : frustum, - position : positionOnEllipsoid, + origin : positionOnEllipsoid, orientation : orientation }), attributes : { diff --git a/Source/Core/FrustumGeometry.js b/Source/Core/FrustumGeometry.js index 8727261165af..3cb07f26fedc 100644 --- a/Source/Core/FrustumGeometry.js +++ b/Source/Core/FrustumGeometry.js @@ -40,14 +40,14 @@ define([ var ORTHOGRAPHIC = 1; /** - * Describes a frustum at the given position and orientation. + * Describes a frustum at the given the origin and orientation. * * @alias FrustumGeometry * @constructor * * @param {Object} options Object with the following properties: * @param {PerspectiveFrustum|OrthographicFrustum} options.frustum The frustum. - * @param {Cartesian3} options.position The position of the frustum. + * @param {Cartesian3} options.origin The origin of the frustum. * @param {Quaternion} options.orientation The orientation of the frustum. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. */ @@ -55,14 +55,18 @@ define([ //>>includeStart('debug', pragmas.debug); Check.typeOf.object('options', options); Check.typeOf.object('options.frustum', options.frustum); - Check.typeOf.object('options.position', options.position); + Check.typeOf.object('options.origin', options.origin); Check.typeOf.object('options.orientation', options.orientation); //>>includeEnd('debug'); var frustum = options.frustum; var orientation = options.orientation; - var position = options.position; + var origin = options.origin; var vertexFormat = defaultValue(options.vertexFormat, VertexFormat.DEFAULT); + + // This is private because it is used by DebugCameraPrimitive to draw a multi-frustum by + // creating multiple FrustumGeometrys. This way the near plane of one frustum doesn't overlap + // the far plane of another. var drawNearPlane = defaultValue(options._drawNearPlane, true); var frustumType; @@ -77,7 +81,7 @@ define([ this._frustumType = frustumType; this._frustum = frustum.clone(); - this._position = Cartesian3.clone(position); + this._origin = Cartesian3.clone(origin); this._orientation = Quaternion.clone(orientation); this._drawNearPlane = drawNearPlane; this._vertexFormat = vertexFormat; @@ -120,7 +124,7 @@ define([ startingIndex += OrthographicFrustum.packedLength; } - Cartesian3.pack(value._position, array, startingIndex); + Cartesian3.pack(value._origin, array, startingIndex); startingIndex += Cartesian3.packedLength; Quaternion.pack(value._orientation, array, startingIndex); startingIndex += Quaternion.packedLength; @@ -134,7 +138,7 @@ define([ var scratchPackPerspective = new PerspectiveFrustum(); var scratchPackOrthographic = new OrthographicFrustum(); var scratchPackQuaternion = new Quaternion(); - var scratchPackPosition = new Cartesian3(); + var scratchPackorigin = new Cartesian3(); var scratchVertexFormat = new VertexFormat(); /** @@ -162,7 +166,7 @@ define([ startingIndex += OrthographicFrustum.packedLength; } - var position = Cartesian3.unpack(array, startingIndex, scratchPackPosition); + var origin = Cartesian3.unpack(array, startingIndex, scratchPackorigin); startingIndex += Cartesian3.packedLength; var orientation = Quaternion.unpack(array, startingIndex, scratchPackQuaternion); startingIndex += Quaternion.packedLength; @@ -173,7 +177,7 @@ define([ if (!defined(result)) { return new FrustumGeometry({ frustum : frustum, - position : position, + origin : origin, orientation : orientation, vertexFormat : vertexFormat, _drawNearPlane : drawNearPlane @@ -184,7 +188,7 @@ define([ result._frustum = frustum.clone(frustumResult); result._frustumType = frustumType; - result._position = Cartesian3.clone(position, result._position); + result._origin = Cartesian3.clone(origin, result._origin); result._orientation = Quaternion.clone(orientation, result._orientation); result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat); result._drawNearPlane = drawNearPlane; @@ -257,7 +261,7 @@ define([ FrustumGeometry.createGeometry = function(frustumGeometry) { var frustumType = frustumGeometry._frustumType; var frustum = frustumGeometry._frustum; - var position = frustumGeometry._position; + var origin = frustumGeometry._origin; var orientation = frustumGeometry._orientation; var drawNearPlane = frustumGeometry._drawNearPlane; var vertexFormat = frustumGeometry._vertexFormat; @@ -273,7 +277,7 @@ define([ Cartesian3.negate(x, x); - var view = Matrix4.computeView(position, z, y, x, scratchViewMatrix); + var view = Matrix4.computeView(origin, z, y, x, scratchViewMatrix); var inverseView; var inverseViewProjection; @@ -323,12 +327,12 @@ define([ var w = 1.0 / corner.w; Cartesian3.multiplyByScalar(corner, w, corner); - Cartesian3.subtract(corner, position, corner); + Cartesian3.subtract(corner, origin, corner); Cartesian3.normalize(corner, corner); var fac = Cartesian3.dot(z, corner); Cartesian3.multiplyByScalar(corner, frustumSplits[i] / fac, corner); - Cartesian3.add(corner, position, corner); + Cartesian3.add(corner, origin, corner); } positions[12 * i + j * 3] = corner.x; diff --git a/Source/Core/FrustumOutlineGeometry.js b/Source/Core/FrustumOutlineGeometry.js index d803081036de..8c4e0aeab1a3 100644 --- a/Source/Core/FrustumOutlineGeometry.js +++ b/Source/Core/FrustumOutlineGeometry.js @@ -38,27 +38,31 @@ define([ var ORTHOGRAPHIC = 1; /** - * A description of the outline of a frustum with the given position and orientation. + * A description of the outline of a frustum with the given the origin and orientation. * * @alias FrustumOutlineGeometry * @constructor * * @param {Object} options Object with the following properties: * @param {PerspectiveFrustum|OrthographicFrustum} options.frustum The frustum. - * @param {Cartesian3} options.position The position of the frustum. + * @param {Cartesian3} options.origin The origin of the frustum. * @param {Quaternion} options.orientation The orientation of the frustum. */ function FrustumOutlineGeometry(options) { //>>includeStart('debug', pragmas.debug); Check.typeOf.object('options', options); Check.typeOf.object('options.frustum', options.frustum); - Check.typeOf.object('options.position', options.position); + Check.typeOf.object('options.origin', options.origin); Check.typeOf.object('options.orientation', options.orientation); //>>includeEnd('debug'); var frustum = options.frustum; var orientation = options.orientation; - var position = options.position; + var origin = options.origin; + + // This is private because it is used by DebugCameraPrimitive to draw a multi-frustum by + // creating multiple FrustumOutlineGeometrys. This way the near plane of one frustum doesn't overlap + // the far plane of another. var drawNearPlane = defaultValue(options._drawNearPlane, true); var frustumType; @@ -73,7 +77,7 @@ define([ this._frustumType = frustumType; this._frustum = frustum.clone(); - this._position = Cartesian3.clone(position); + this._origin = Cartesian3.clone(origin); this._orientation = Quaternion.clone(orientation); this._drawNearPlane = drawNearPlane; this._workerName = 'createFrustumOutlineGeometry'; @@ -115,7 +119,7 @@ define([ startingIndex += OrthographicFrustum.packedLength; } - Cartesian3.pack(value._position, array, startingIndex); + Cartesian3.pack(value._origin, array, startingIndex); startingIndex += Cartesian3.packedLength; Quaternion.pack(value._orientation, array, startingIndex); startingIndex += Quaternion.packedLength; @@ -127,7 +131,7 @@ define([ var scratchPackPerspective = new PerspectiveFrustum(); var scratchPackOrthographic = new OrthographicFrustum(); var scratchPackQuaternion = new Quaternion(); - var scratchPackPosition = new Cartesian3(); + var scratchPackorigin = new Cartesian3(); /** * Retrieves an instance from a packed array. @@ -154,7 +158,7 @@ define([ startingIndex += OrthographicFrustum.packedLength; } - var position = Cartesian3.unpack(array, startingIndex, scratchPackPosition); + var origin = Cartesian3.unpack(array, startingIndex, scratchPackorigin); startingIndex += Cartesian3.packedLength; var orientation = Quaternion.unpack(array, startingIndex, scratchPackQuaternion); startingIndex += Quaternion.packedLength; @@ -163,7 +167,7 @@ define([ if (!defined(result)) { return new FrustumOutlineGeometry({ frustum : frustum, - position : position, + origin : origin, orientation : orientation, _drawNearPlane : drawNearPlane }); @@ -173,7 +177,7 @@ define([ result._frustum = frustum.clone(frustumResult); result._frustumType = frustumType; - result._position = Cartesian3.clone(position, result._position); + result._origin = Cartesian3.clone(origin, result._origin); result._orientation = Quaternion.clone(orientation, result._orientation); result._drawNearPlane = drawNearPlane; @@ -210,7 +214,7 @@ define([ FrustumOutlineGeometry.createGeometry = function(frustumGeometry) { var frustumType = frustumGeometry._frustumType; var frustum = frustumGeometry._frustum; - var position = frustumGeometry._position; + var origin = frustumGeometry._origin; var orientation = frustumGeometry._orientation; var drawNearPlane = frustumGeometry._drawNearPlane; @@ -225,7 +229,7 @@ define([ Cartesian3.negate(x, x); - var view = Matrix4.computeView(position, z, y, x, scratchViewMatrix); + var view = Matrix4.computeView(origin, z, y, x, scratchViewMatrix); var inverseView; var inverseViewProjection; @@ -274,12 +278,12 @@ define([ var w = 1.0 / corner.w; Cartesian3.multiplyByScalar(corner, w, corner); - Cartesian3.subtract(corner, position, corner); + Cartesian3.subtract(corner, origin, corner); Cartesian3.normalize(corner, corner); var fac = Cartesian3.dot(z, corner); Cartesian3.multiplyByScalar(corner, frustumSplits[i] / fac, corner); - Cartesian3.add(corner, position, corner); + Cartesian3.add(corner, origin, corner); } positions[12 * i + j * 3] = corner.x; From b82dd808ac323ff45c6aa6bb5c25ec217c63bc47 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 19 Jul 2017 16:13:21 -0400 Subject: [PATCH 107/132] Refactor duplicate code. --- Source/Core/FrustumGeometry.js | 56 ++++++++------- Source/Core/FrustumOutlineGeometry.js | 98 ++------------------------- 2 files changed, 37 insertions(+), 117 deletions(-) diff --git a/Source/Core/FrustumGeometry.js b/Source/Core/FrustumGeometry.js index 3cb07f26fedc..22713aa81e6b 100644 --- a/Source/Core/FrustumGeometry.js +++ b/Source/Core/FrustumGeometry.js @@ -252,24 +252,15 @@ define([ scratchFrustumCorners[i] = new Cartesian4(); } - /** - * Computes the geometric representation of a frustum, including its vertices, indices, and a bounding sphere. - * - * @param {FrustumGeometry} frustumGeometry A description of the frustum. - * @returns {Geometry|undefined} The computed vertices and indices. - */ - FrustumGeometry.createGeometry = function(frustumGeometry) { - var frustumType = frustumGeometry._frustumType; - var frustum = frustumGeometry._frustum; - var origin = frustumGeometry._origin; - var orientation = frustumGeometry._orientation; - var drawNearPlane = frustumGeometry._drawNearPlane; - var vertexFormat = frustumGeometry._vertexFormat; - + FrustumGeometry._computeNearFarPlanes = function(origin, orientation, frustumType, frustum, positions, xDirection, yDirection, zDirection) { var rotationMatrix = Matrix3.fromQuaternion(orientation, scratchRotationMatrix); - var x = Matrix3.getColumn(rotationMatrix, 0, scratchXDirection); - var y = Matrix3.getColumn(rotationMatrix, 1, scratchYDirection); - var z = Matrix3.getColumn(rotationMatrix, 2, scratchZDirection); + var x = defaultValue(xDirection, scratchXDirection); + var y = defaultValue(yDirection, scratchYDirection); + var z = defaultValue(zDirection, scratchZDirection); + + x = Matrix3.getColumn(rotationMatrix, 0, x); + y = Matrix3.getColumn(rotationMatrix, 1, y); + z = Matrix3.getColumn(rotationMatrix, 2, z); Cartesian3.normalize(x, x); Cartesian3.normalize(y, y); @@ -298,11 +289,7 @@ define([ frustumSplits[2] = frustum.far; } - var i; - var numberOfPlanes = drawNearPlane ? 6 : 5; - var positions = new Float64Array(3 * 4 * 6); - - for (i = 0; i < 2; ++i) { + for (var i = 0; i < 2; ++i) { for (var j = 0; j < 4; ++j) { var corner = Cartesian4.clone(frustumCornersNDC[j], scratchFrustumCorners[j]); @@ -340,6 +327,25 @@ define([ positions[12 * i + j * 3 + 2] = corner.z; } } + }; + + /** + * Computes the geometric representation of a frustum, including its vertices, indices, and a bounding sphere. + * + * @param {FrustumGeometry} frustumGeometry A description of the frustum. + * @returns {Geometry|undefined} The computed vertices and indices. + */ + FrustumGeometry.createGeometry = function(frustumGeometry) { + var frustumType = frustumGeometry._frustumType; + var frustum = frustumGeometry._frustum; + var origin = frustumGeometry._origin; + var orientation = frustumGeometry._orientation; + var drawNearPlane = frustumGeometry._drawNearPlane; + var vertexFormat = frustumGeometry._vertexFormat; + + var numberOfPlanes = drawNearPlane ? 6 : 5; + var positions = new Float64Array(3 * 4 * 6); + FrustumGeometry._computeNearFarPlanes(origin, orientation, frustumType, frustum, positions); // -x plane var offset = 3 * 4 * 2; @@ -419,6 +425,10 @@ define([ var bitangents = defined(vertexFormat.bitangent) ? new Float32Array(3 * 4 * numberOfPlanes) : undefined; var st = defined(vertexFormat.st) ? new Float32Array(2 * 4 * numberOfPlanes) : undefined; + var x = scratchXDirection; + var y = scratchYDirection; + var z = scratchZDirection; + var negativeX = Cartesian3.negate(x, scratchNegativeX); var negativeY = Cartesian3.negate(y, scratchNegativeY); var negativeZ = Cartesian3.negate(z, scratchNegativeZ); @@ -469,7 +479,7 @@ define([ } var indices = new Uint16Array(6 * numberOfPlanes); - for (i = 0; i < numberOfPlanes; ++i) { + for (var i = 0; i < numberOfPlanes; ++i) { var indexOffset = i * 6; var index = i * 4; diff --git a/Source/Core/FrustumOutlineGeometry.js b/Source/Core/FrustumOutlineGeometry.js index 8c4e0aeab1a3..2740e2f98547 100644 --- a/Source/Core/FrustumOutlineGeometry.js +++ b/Source/Core/FrustumOutlineGeometry.js @@ -6,6 +6,7 @@ define([ './ComponentDatatype', './defaultValue', './defined', + './FrustumGeometry', './Geometry', './GeometryAttribute', './GeometryAttributes', @@ -23,6 +24,7 @@ define([ ComponentDatatype, defaultValue, defined, + FrustumGeometry, Geometry, GeometryAttribute, GeometryAttributes, @@ -184,27 +186,6 @@ define([ return result; }; - var scratchRotationMatrix = new Matrix3(); - var scratchViewMatrix = new Matrix4(); - var scratchInverseMatrix = new Matrix4(); - - var scratchXDirection = new Cartesian3(); - var scratchYDirection = new Cartesian3(); - var scratchZDirection = new Cartesian3(); - - var frustumSplits = new Array(3); - - var frustumCornersNDC = new Array(4); - frustumCornersNDC[0] = new Cartesian4(-1.0, -1.0, 1.0, 1.0); - frustumCornersNDC[1] = new Cartesian4(1.0, -1.0, 1.0, 1.0); - frustumCornersNDC[2] = new Cartesian4(1.0, 1.0, 1.0, 1.0); - frustumCornersNDC[3] = new Cartesian4(-1.0, 1.0, 1.0, 1.0); - - var scratchFrustumCorners = new Array(4); - for (var i = 0; i < 4; ++i) { - scratchFrustumCorners[i] = new Cartesian4(); - } - /** * Computes the geometric representation of a frustum outline, including its vertices, indices, and a bounding sphere. * @@ -218,79 +199,8 @@ define([ var orientation = frustumGeometry._orientation; var drawNearPlane = frustumGeometry._drawNearPlane; - var rotationMatrix = Matrix3.fromQuaternion(orientation, scratchRotationMatrix); - var x = Matrix3.getColumn(rotationMatrix, 0, scratchXDirection); - var y = Matrix3.getColumn(rotationMatrix, 1, scratchYDirection); - var z = Matrix3.getColumn(rotationMatrix, 2, scratchZDirection); - - Cartesian3.normalize(x, x); - Cartesian3.normalize(y, y); - Cartesian3.normalize(z, z); - - Cartesian3.negate(x, x); - - var view = Matrix4.computeView(origin, z, y, x, scratchViewMatrix); - - var inverseView; - var inverseViewProjection; - if (frustumType === PERSPECTIVE) { - var projection = frustum.projectionMatrix; - var viewProjection = Matrix4.multiply(projection, view, scratchInverseMatrix); - inverseViewProjection = Matrix4.inverse(viewProjection, scratchInverseMatrix); - } else { - inverseView = Matrix4.inverseTransformation(view, scratchInverseMatrix); - } - - if (defined(inverseViewProjection)) { - frustumSplits[0] = frustum.near; - frustumSplits[1] = frustum.far; - } else { - frustumSplits[0] = 0.0; - frustumSplits[1] = frustum.near; - frustumSplits[2] = frustum.far; - } - - var i; var positions = new Float64Array(3 * 4 * 2); - - for (i = 0; i < 2; ++i) { - for (var j = 0; j < 4; ++j) { - var corner = Cartesian4.clone(frustumCornersNDC[j], scratchFrustumCorners[j]); - - if (!defined(inverseViewProjection)) { - if (defined(frustum._offCenterFrustum)) { - frustum = frustum._offCenterFrustum; - } - - var near = frustumSplits[i]; - var far = frustumSplits[i + 1]; - - corner.x = (corner.x * (frustum.right - frustum.left) + frustum.left + frustum.right) * 0.5; - corner.y = (corner.y * (frustum.top - frustum.bottom) + frustum.bottom + frustum.top) * 0.5; - corner.z = (corner.z * (near - far) - near - far) * 0.5; - corner.w = 1.0; - - Matrix4.multiplyByVector(inverseView, corner, corner); - } else { - corner = Matrix4.multiplyByVector(inverseViewProjection, corner, corner); - - // Reverse perspective divide - var w = 1.0 / corner.w; - Cartesian3.multiplyByScalar(corner, w, corner); - - Cartesian3.subtract(corner, origin, corner); - Cartesian3.normalize(corner, corner); - - var fac = Cartesian3.dot(z, corner); - Cartesian3.multiplyByScalar(corner, frustumSplits[i] / fac, corner); - Cartesian3.add(corner, origin, corner); - } - - positions[12 * i + j * 3] = corner.x; - positions[12 * i + j * 3 + 1] = corner.y; - positions[12 * i + j * 3 + 2] = corner.z; - } - } + FrustumGeometry._computeNearFarPlanes(origin, orientation, frustumType, frustum, positions); var attributes = new GeometryAttributes({ position : new GeometryAttribute({ @@ -307,7 +217,7 @@ define([ var indices = new Uint16Array(8 * (numberOfPlanes + 1)); // Build the near/far planes - i = drawNearPlane ? 0 : 1; + var i = drawNearPlane ? 0 : 1; for (; i < 2; ++i) { offset = drawNearPlane ? i * 8 : 0; index = i * 4; From 3d1d03014e23404f044c0b755647bf321d622f26 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 19 Jul 2017 16:29:57 -0400 Subject: [PATCH 108/132] Update tests after rename. --- Source/Scene/DebugCameraPrimitive.js | 4 ++-- Specs/Core/FrustumGeometrySpec.js | 8 ++++---- Specs/Core/FrustumOutlineGeometrySpec.js | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Source/Scene/DebugCameraPrimitive.js b/Source/Scene/DebugCameraPrimitive.js index 5b59f46d201b..02f990da1353 100644 --- a/Source/Scene/DebugCameraPrimitive.js +++ b/Source/Scene/DebugCameraPrimitive.js @@ -174,7 +174,7 @@ define([ planesPrimitives[i] = new Primitive({ geometryInstances : new GeometryInstance({ geometry : new FrustumGeometry({ - position : position, + origin : position, orientation : orientation, frustum : frustum, _drawNearPlane : i === 0 @@ -195,7 +195,7 @@ define([ outlinePrimitives[i] = new Primitive({ geometryInstances : new GeometryInstance({ geometry : new FrustumOutlineGeometry({ - position : position, + origin : position, orientation : orientation, frustum : frustum, _drawNearPlane : i === 0 diff --git a/Specs/Core/FrustumGeometrySpec.js b/Specs/Core/FrustumGeometrySpec.js index 6202904bac5b..0b9f5669fc6d 100644 --- a/Specs/Core/FrustumGeometrySpec.js +++ b/Specs/Core/FrustumGeometrySpec.js @@ -25,7 +25,7 @@ defineSuite([ it('constructor throws without frustum', function() { expect(function() { return new FrustumGeometry({ - position : Cartesian3.ZERO, + origin : Cartesian3.ZERO, orientation : Quaternion.IDENTITY }); }).toThrowDeveloperError(); @@ -44,7 +44,7 @@ defineSuite([ expect(function() { return new FrustumGeometry({ frustum : new PerspectiveFrustum(), - position : Cartesian3.ZERO + origin : Cartesian3.ZERO }); }).toThrowDeveloperError(); }); @@ -58,7 +58,7 @@ defineSuite([ var m = FrustumGeometry.createGeometry(new FrustumGeometry({ frustum : frustum, - position : Cartesian3.ZERO, + origin : Cartesian3.ZERO, orientation : Quaternion.IDENTITY, vertexFormat : VertexFormat.ALL })); @@ -86,7 +86,7 @@ defineSuite([ createPackableSpecs(FrustumGeometry, new FrustumGeometry({ frustum : packableFrustum, - position : Cartesian3.ZERO, + origin : Cartesian3.ZERO, orientation : Quaternion.IDENTITY, vertexFormat : VertexFormat.POSITION_ONLY }), [0.0, 1.0, 2.0, 3.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]); diff --git a/Specs/Core/FrustumOutlineGeometrySpec.js b/Specs/Core/FrustumOutlineGeometrySpec.js index 8fabd5ed5ec6..71a46b75da84 100644 --- a/Specs/Core/FrustumOutlineGeometrySpec.js +++ b/Specs/Core/FrustumOutlineGeometrySpec.js @@ -25,7 +25,7 @@ defineSuite([ it('constructor throws without frustum', function() { expect(function() { return new FrustumOutlineGeometry({ - position : Cartesian3.ZERO, + origin : Cartesian3.ZERO, orientation : Quaternion.IDENTITY }); }).toThrowDeveloperError(); @@ -44,7 +44,7 @@ defineSuite([ expect(function() { return new FrustumOutlineGeometry({ frustum : new PerspectiveFrustum(), - position : Cartesian3.ZERO + origin : Cartesian3.ZERO }); }).toThrowDeveloperError(); }); @@ -58,7 +58,7 @@ defineSuite([ var m = FrustumOutlineGeometry.createGeometry(new FrustumOutlineGeometry({ frustum : frustum, - position : Cartesian3.ZERO, + origin : Cartesian3.ZERO, orientation : Quaternion.IDENTITY })); @@ -80,7 +80,7 @@ defineSuite([ createPackableSpecs(FrustumOutlineGeometry, new FrustumOutlineGeometry({ frustum : packableFrustum, - position : Cartesian3.ZERO, + origin : Cartesian3.ZERO, orientation : Quaternion.IDENTITY, vertexFormat : VertexFormat.POSITION_ONLY }), [0.0, 1.0, 2.0, 3.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0]); From 855681a811e4bceb96c011404263f17256a87c3c Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 19 Jul 2017 16:33:39 -0400 Subject: [PATCH 109/132] Update CHANGES.md. --- CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 547dfc0ca0b5..1fa858a010a8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,8 @@ Change Log * Fixed crash when using the `Cesium3DTilesInspectorViewModel` and removing a tileset [#5607](https://github.com/AnalyticalGraphicsInc/cesium/issues/5607) * Fixed polygon outline in Polygon Sandcastle demo [#5642](https://github.com/AnalyticalGraphicsInc/cesium/issues/5642) * Fixed label positioning when using `HeightReference.CLAMP_TO_GROUND` and no position [#5648](https://github.com/AnalyticalGraphicsInc/cesium/pull/5648) +* Added `FrustumGeometry` and `FrustumOutlineGeometry`. [#5649](https://github.com/AnalyticalGraphicsInc/cesium/pull/5649) +* Added an `options` parameter to the constructors of `PerspectiveFrustum`, `PerspectiveOffCenterFrustum`, `OrthographicFrustum`, and `OrthographicOffCenterFrustum` to set properties. [#5649](https://github.com/AnalyticalGraphicsInc/cesium/pull/5649) ### 1.35.2 - 2017-07-11 From eebf7e51d54f398c1de8c4170d8f0e03170de7a9 Mon Sep 17 00:00:00 2001 From: Tom Fili Date: Wed, 19 Jul 2017 16:50:31 -0400 Subject: [PATCH 110/132] Fixed tests to use samples-generator. --- .../compositeOfInstanced.cmpt | Bin 0 -> 11760 bytes .../CompositeOfInstanced/tileset.json | 29 ++++++++++++++++++ .../MultipleInstancedTilesets/1/0/0.i3dm | Bin 151 -> 0 bytes .../MultipleInstancedTilesets/2/2/2.i3dm | Bin 174 -> 0 bytes .../MultipleInstancedTilesets/2/2/3.i3dm | Bin 175 -> 0 bytes .../MultipleInstancedTilesets/2/3/3.i3dm | Bin 173 -> 0 bytes .../MultipleInstancedTilesets/box1.glb | Bin 1981 -> 0 bytes .../MultipleInstancedTilesets/box2.glb | Bin 2003 -> 0 bytes .../MultipleInstancedTilesets/tileset.json | Bin 481 -> 0 bytes Specs/Scene/Composite3DTileContentSpec.js | 26 ++-------------- 10 files changed, 31 insertions(+), 24 deletions(-) create mode 100644 Specs/Data/Cesium3DTiles/Composite/CompositeOfInstanced/compositeOfInstanced.cmpt create mode 100644 Specs/Data/Cesium3DTiles/Composite/CompositeOfInstanced/tileset.json delete mode 100644 Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/1/0/0.i3dm delete mode 100644 Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/2/2/2.i3dm delete mode 100644 Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/2/2/3.i3dm delete mode 100644 Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/2/3/3.i3dm delete mode 100644 Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/box1.glb delete mode 100644 Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/box2.glb delete mode 100644 Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/tileset.json diff --git a/Specs/Data/Cesium3DTiles/Composite/CompositeOfInstanced/compositeOfInstanced.cmpt b/Specs/Data/Cesium3DTiles/Composite/CompositeOfInstanced/compositeOfInstanced.cmpt new file mode 100644 index 0000000000000000000000000000000000000000..d2149ce185edf70f11373d391792c5fbc2365611 GIT binary patch literal 11760 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 F007w3L>&MC diff --git a/Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/2/2/2.i3dm b/Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/2/2/2.i3dm deleted file mode 100644 index 3dd31dc796ba283f98ea2d41c751b7b14739288a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174 zcmV;f08#%RiwFP!000003d=N3$z^07WvHVR;2-Q6;_2_FWL2${R9TYhpO#jfTB2lSP^+Wl>KGgn@8=&B;t?Mjpk!52 zRGO-z6zuHi&E)x}w%3d6y0v4ql1FN0dInHYw4tG%xk)Tk cp`M;T5GCbT80n?wBrz}m0EdR~(ZB!z03UEt*#H0l diff --git a/Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/2/2/3.i3dm b/Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/2/2/3.i3dm deleted file mode 100644 index bf77cccec5d649015a368e97ba41a30e05394bdf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175 zcmV;g08sxQiwFP!000003d=N3$z^07WvHVR;2-Q6;_2_FWL2${R9TYhpO#jfTB2lSP^+Wl>KGgn@8=&B;t?Mjpk!52 zRGO-z6zuHiP7WvHVR;2-Q6;_2_FWL2${R9TYhpO#jfTB2lSP^+Wl>KGgn@8=&B;t?Mjpk!52 zRGO-z6zuHijR bP)|=Eh?4Rv4E54;k{B2Of)Ou6zyJUMGw4nd diff --git a/Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/box1.glb b/Specs/Data/Cesium3DTiles/Composite/MultipleInstancedTilesets/box1.glb deleted file mode 100644 index d43defba2fb5ff1ce2284967dd091501b84992a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1981 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 X#2F> Date: Wed, 19 Jul 2017 17:01:22 -0400 Subject: [PATCH 111/132] Fix sporadic build/test failures. The default load timeout for AMD modules is 7 seconds, when running the tests so many modules get loaded at once that it can time out. This fixes the karma configuration under Node so that timeout is indefinite. Because we've also seen sporadic build failures, I also added the timeout option to `requirejs.optimize` as well, I'm not sure if this has any effect, but if we stop seeing sporadic requirejs.optimize failures, we'll know it did. --- Specs/karma.conf.js | 3 +++ gulpfile.js | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/Specs/karma.conf.js b/Specs/karma.conf.js index 374f114dded8..a697e0767b27 100644 --- a/Specs/karma.conf.js +++ b/Specs/karma.conf.js @@ -6,6 +6,9 @@ module.exports = function(config) { // base path that will be used to resolve all patterns (eg. files, exclude) basePath : '..', + // Disable module load timeout + waitSeconds : 0, + // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter frameworks : ['jasmine', 'requirejs', 'detectBrowsers'], diff --git a/gulpfile.js b/gulpfile.js index eb0a95c34a6a..b46c2eb1999c 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -123,6 +123,10 @@ gulp.task('clean', function(done) { gulp.task('requirejs', function(done) { var config = JSON.parse(new Buffer(process.argv[3].substring(2), 'base64').toString('utf8')); + + // Disable module load timeout + config.waitSeconds = 0; + requirejs.optimize(config, function() { done(); }, done); From ef09e3e0c58c7e6c000a9ebeb09c693c785f13e7 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 19 Jul 2017 17:08:27 -0400 Subject: [PATCH 112/132] Minor updates and file moves. --- ...sificationPrimitive.html => Classification.html} | 2 +- ...assificationPrimitive.jpg => Classification.jpg} | Bin Source/Scene/ClassificationPrimitive.js | 4 +++- Source/Scene/GroundPrimitive.js | 2 ++ Source/Scene/Primitive.js | 3 +++ 5 files changed, 9 insertions(+), 2 deletions(-) rename Apps/Sandcastle/gallery/{development/ClassificationPrimitive.html => Classification.html} (98%) rename Apps/Sandcastle/gallery/{development/ClassificationPrimitive.jpg => Classification.jpg} (100%) diff --git a/Apps/Sandcastle/gallery/development/ClassificationPrimitive.html b/Apps/Sandcastle/gallery/Classification.html similarity index 98% rename from Apps/Sandcastle/gallery/development/ClassificationPrimitive.html rename to Apps/Sandcastle/gallery/Classification.html index c74dd18f2905..ccfbf4192d41 100644 --- a/Apps/Sandcastle/gallery/development/ClassificationPrimitive.html +++ b/Apps/Sandcastle/gallery/Classification.html @@ -5,7 +5,7 @@ - + Cesium Demo diff --git a/Apps/Sandcastle/gallery/development/ClassificationPrimitive.jpg b/Apps/Sandcastle/gallery/Classification.jpg similarity index 100% rename from Apps/Sandcastle/gallery/development/ClassificationPrimitive.jpg rename to Apps/Sandcastle/gallery/Classification.jpg diff --git a/Source/Scene/ClassificationPrimitive.js b/Source/Scene/ClassificationPrimitive.js index 6ebdb850d0d5..86440fcecf86 100644 --- a/Source/Scene/ClassificationPrimitive.js +++ b/Source/Scene/ClassificationPrimitive.js @@ -77,7 +77,7 @@ define([ * @constructor * * @param {Object} [options] Object with the following properties: - * @param {Array|GeometryInstance} [options.geometryInstances] The geometry instances to render. + * @param {Array|GeometryInstance} [options.geometryInstances] The geometry instances to render. This can either be a single instance or an array of length one. * @param {Boolean} [options.show=true] Determines if this primitive will be shown. * @param {Boolean} [options.vertexCacheOptimize=false] When true, geometry vertices are optimized for the pre and post-vertex-shader caches. * @param {Boolean} [options.interleave=false] When true, geometry vertex attributes are interleaved, which can slightly improve rendering performance but increases load time. @@ -110,6 +110,7 @@ define([ * on the first attempt to render. *

* + * @readonly * @type {Array|GeometryInstance} * * @default undefined @@ -148,6 +149,7 @@ define([ this.debugShowShadowVolume = defaultValue(options.debugShowShadowVolume, false); this._debugShowShadowVolume = false; + // These are used by GroundPrimitive to augment the shader and uniform map. this._extruded = defaultValue(options._extruded, false); this._uniformMap = options._uniformMap; diff --git a/Source/Scene/GroundPrimitive.js b/Source/Scene/GroundPrimitive.js index e918e836d6ba..9a46f35d16c4 100644 --- a/Source/Scene/GroundPrimitive.js +++ b/Source/Scene/GroundPrimitive.js @@ -124,6 +124,7 @@ define([ * })); * * @see Primitive + * @see ClassificationPrimitive * @see GeometryInstance * @see Appearance */ @@ -143,6 +144,7 @@ define([ * on the first attempt to render. *

* + * @readonly * @type {Array|GeometryInstance} * * @default undefined diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 425bb9d19a89..0484e51bff28 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -189,6 +189,8 @@ define([ * * @see GeometryInstance * @see Appearance + * @see ClassificationPrimitive + * @see GroundPrimitive */ function Primitive(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -201,6 +203,7 @@ define([ * Changing this property after the primitive is rendered has no effect. *

* + * @readonly * @type GeometryInstance[]|GeometryInstance * * @default undefined From 74184d8436ac8e3e9faf2a25ad0f33be5e322815 Mon Sep 17 00:00:00 2001 From: Cody Date: Wed, 19 Jul 2017 22:37:11 -0400 Subject: [PATCH 113/132] Add ability to set name of KML data source --- Source/DataSources/KmlDataSource.js | 7 ++++++- Specs/DataSources/KmlDataSourceSpec.js | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Source/DataSources/KmlDataSource.js b/Source/DataSources/KmlDataSource.js index ded2f89e5fcc..96495fba8ef2 100644 --- a/Source/DataSources/KmlDataSource.js +++ b/Source/DataSources/KmlDataSource.js @@ -2344,7 +2344,7 @@ define([ defineProperties(KmlDataSource.prototype, { /** - * Gets a human-readable name for this instance. + * Gets or sets a human-readable name for this instance. * This will be automatically be set to the KML document name on load. * @memberof KmlDataSource.prototype * @type {String} @@ -2352,6 +2352,11 @@ define([ name : { get : function() { return this._name; + }, + set : function(value) { + if(this._name !== value) { + this._name = value; + } } }, /** diff --git a/Specs/DataSources/KmlDataSourceSpec.js b/Specs/DataSources/KmlDataSourceSpec.js index 17198cd83648..8c8eb7cdcb60 100644 --- a/Specs/DataSources/KmlDataSourceSpec.js +++ b/Specs/DataSources/KmlDataSourceSpec.js @@ -150,6 +150,20 @@ defineSuite([ expect(dataSource.show).toBe(true); }); + + it('setting name raises changed event', function() { + var dataSource = new KmlDataSource(); + + var spy = jasmine.createSpy('changedEvent'); + dataSource.changedEvent.addEventListener(spy); + + var newName = 'garfield'; + dataSource.name = newName; + expect(dataSource.name).toEqual(newName); + expect(spy.calls.count()).toEqual(1); + expect(spy).toHaveBeenCalledWith(dataSource); + }); + it('show sets underlying entity collection show.', function() { var dataSource = new KmlDataSource(options); From a97f4cd122657b61355ed7b0e7a4e46672c74111 Mon Sep 17 00:00:00 2001 From: Cody Date: Wed, 19 Jul 2017 22:45:44 -0400 Subject: [PATCH 114/132] Fix test errors; update CHANGES.md --- CHANGES.md | 1 + Source/DataSources/KmlDataSource.js | 1 + Specs/DataSources/KmlDataSourceSpec.js | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 1fa858a010a8..afa7ad60d932 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ Change Log * Added ability to show tile urls in the 3D Tiles Inspector. [#5592](https://github.com/AnalyticalGraphicsInc/cesium/pull/5592) * Added behavior to `Cesium3DTilesInspector` that selects the first tileset hovered over if no tilest is specified. [#5139](https://github.com/AnalyticalGraphicsInc/cesium/issues/5139) * Added ability to provide a `width` and `height` to `scene.pick`. [#5602](https://github.com/AnalyticalGraphicsInc/cesium/pull/5602) +* Added setter for `KkmlDataSource.name` to specify a name for the datasource. * Fixed issue where scene would blink when labels were added. [#5537](https://github.com/AnalyticalGraphicsInc/cesium/issues/5537) * Fixed label positioning when height reference changes [#5609](https://github.com/AnalyticalGraphicsInc/cesium/issues/5609) * Fixed crash when using the `Cesium3DTilesInspectorViewModel` and removing a tileset [#5607](https://github.com/AnalyticalGraphicsInc/cesium/issues/5607) diff --git a/Source/DataSources/KmlDataSource.js b/Source/DataSources/KmlDataSource.js index 96495fba8ef2..1ae152906b57 100644 --- a/Source/DataSources/KmlDataSource.js +++ b/Source/DataSources/KmlDataSource.js @@ -2356,6 +2356,7 @@ define([ set : function(value) { if(this._name !== value) { this._name = value; + this._changed.raiseEvent(this); } } }, diff --git a/Specs/DataSources/KmlDataSourceSpec.js b/Specs/DataSources/KmlDataSourceSpec.js index 8c8eb7cdcb60..e152eee4f79f 100644 --- a/Specs/DataSources/KmlDataSourceSpec.js +++ b/Specs/DataSources/KmlDataSourceSpec.js @@ -152,7 +152,7 @@ defineSuite([ it('setting name raises changed event', function() { - var dataSource = new KmlDataSource(); + var dataSource = new KmlDataSource(options); var spy = jasmine.createSpy('changedEvent'); dataSource.changedEvent.addEventListener(spy); From c14aea7a834cbcb90521c1014a4e59e1ddd7c778 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Wed, 19 Jul 2017 22:45:55 -0400 Subject: [PATCH 115/132] Fix travis builds The problem was that travis itself was killing our build process because we were trying to run 8 requirejs processes at once, leading us to run out of memory (only 3GB available on travis). This adds a command line to specify concurrency and updates travis to do at most 2 (one for each core). --- .travis.yml | 2 +- gulpfile.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 024b8097b877..42139a1752fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ script: - echo 'makeZipFile' && echo -en 'travis_fold:start:script.makeZipFile\\r' - npm run clean - - npm run makeZipFile + - npm run makeZipFile -- --concurrency 2 - npm pack - echo -en 'travis_fold:end:script.makeZipFile\\r' diff --git a/gulpfile.js b/gulpfile.js index b46c2eb1999c..6be3722bd14b 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -46,8 +46,10 @@ var noDevelopmentGallery = taskName === 'release' || taskName === 'makeZipFile'; var buildingRelease = noDevelopmentGallery; var minifyShaders = taskName === 'minify' || taskName === 'minifyRelease' || taskName === 'release' || taskName === 'makeZipFile' || taskName === 'buildApps'; -//travis reports 32 cores but only has 3GB of memory, which causes the VM to run out. Limit to 8 cores instead. -var concurrency = Math.min(os.cpus().length, 8); +var concurrency = yargs.argv.concurrency; +if (!concurrency) { + concurrency = os.cpus().length; +} //Since combine and minify run in parallel already, split concurrency in half when building both. //This can go away when gulp 4 comes out because it allows for synchronous tasks. From 8bc17605d4812dfb34fde782ad33e498f2ec3416 Mon Sep 17 00:00:00 2001 From: Hannah Date: Thu, 20 Jul 2017 09:25:20 -0400 Subject: [PATCH 116/132] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 1fa858a010a8..5579d8c74fb2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,7 @@ Change Log * Fixed crash when using the `Cesium3DTilesInspectorViewModel` and removing a tileset [#5607](https://github.com/AnalyticalGraphicsInc/cesium/issues/5607) * Fixed polygon outline in Polygon Sandcastle demo [#5642](https://github.com/AnalyticalGraphicsInc/cesium/issues/5642) * Fixed label positioning when using `HeightReference.CLAMP_TO_GROUND` and no position [#5648](https://github.com/AnalyticalGraphicsInc/cesium/pull/5648) +* Updated `Billboard`, `Label` and `PointPrimitive` constructors to clone NearFarScale parameters [#5654](https://github.com/AnalyticalGraphicsInc/cesium/pull/5654) * Added `FrustumGeometry` and `FrustumOutlineGeometry`. [#5649](https://github.com/AnalyticalGraphicsInc/cesium/pull/5649) * Added an `options` parameter to the constructors of `PerspectiveFrustum`, `PerspectiveOffCenterFrustum`, `OrthographicFrustum`, and `OrthographicOffCenterFrustum` to set properties. [#5649](https://github.com/AnalyticalGraphicsInc/cesium/pull/5649) From 2760875293d4f6319b4f72e2cda2c02488b1acda Mon Sep 17 00:00:00 2001 From: Hannah Date: Thu, 20 Jul 2017 09:25:45 -0400 Subject: [PATCH 117/132] Update CHANGES.md --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 5579d8c74fb2..4b4cab78edac 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,7 +21,7 @@ Change Log * Fixed crash when using the `Cesium3DTilesInspectorViewModel` and removing a tileset [#5607](https://github.com/AnalyticalGraphicsInc/cesium/issues/5607) * Fixed polygon outline in Polygon Sandcastle demo [#5642](https://github.com/AnalyticalGraphicsInc/cesium/issues/5642) * Fixed label positioning when using `HeightReference.CLAMP_TO_GROUND` and no position [#5648](https://github.com/AnalyticalGraphicsInc/cesium/pull/5648) -* Updated `Billboard`, `Label` and `PointPrimitive` constructors to clone NearFarScale parameters [#5654](https://github.com/AnalyticalGraphicsInc/cesium/pull/5654) +* Updated `Billboard`, `Label` and `PointPrimitive` constructors to clone `NearFarScale` parameters [#5654](https://github.com/AnalyticalGraphicsInc/cesium/pull/5654) * Added `FrustumGeometry` and `FrustumOutlineGeometry`. [#5649](https://github.com/AnalyticalGraphicsInc/cesium/pull/5649) * Added an `options` parameter to the constructors of `PerspectiveFrustum`, `PerspectiveOffCenterFrustum`, `OrthographicFrustum`, and `OrthographicOffCenterFrustum` to set properties. [#5649](https://github.com/AnalyticalGraphicsInc/cesium/pull/5649) From eb81163672b3f20b407afe698ea3c5219fa0895f Mon Sep 17 00:00:00 2001 From: Cody Guldner Date: Thu, 20 Jul 2017 09:58:01 -0400 Subject: [PATCH 118/132] Fix typos --- CHANGES.md | 2 +- Source/DataSources/KmlDataSource.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index afa7ad60d932..838884100a2f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,7 +16,7 @@ Change Log * Added ability to show tile urls in the 3D Tiles Inspector. [#5592](https://github.com/AnalyticalGraphicsInc/cesium/pull/5592) * Added behavior to `Cesium3DTilesInspector` that selects the first tileset hovered over if no tilest is specified. [#5139](https://github.com/AnalyticalGraphicsInc/cesium/issues/5139) * Added ability to provide a `width` and `height` to `scene.pick`. [#5602](https://github.com/AnalyticalGraphicsInc/cesium/pull/5602) -* Added setter for `KkmlDataSource.name` to specify a name for the datasource. +* Added setter for `KmlDataSource.name` to specify a name for the datasource [#5660](https://github.com/AnalyticalGraphicsInc/cesium/pull/5660). * Fixed issue where scene would blink when labels were added. [#5537](https://github.com/AnalyticalGraphicsInc/cesium/issues/5537) * Fixed label positioning when height reference changes [#5609](https://github.com/AnalyticalGraphicsInc/cesium/issues/5609) * Fixed crash when using the `Cesium3DTilesInspectorViewModel` and removing a tileset [#5607](https://github.com/AnalyticalGraphicsInc/cesium/issues/5607) diff --git a/Source/DataSources/KmlDataSource.js b/Source/DataSources/KmlDataSource.js index 1ae152906b57..c236e71955aa 100644 --- a/Source/DataSources/KmlDataSource.js +++ b/Source/DataSources/KmlDataSource.js @@ -2354,7 +2354,7 @@ define([ return this._name; }, set : function(value) { - if(this._name !== value) { + if (this._name !== value) { this._name = value; this._changed.raiseEvent(this); } From 9db61912e02c8cf703133b2d1ac3a04df5499a92 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Thu, 20 Jul 2017 11:03:17 -0400 Subject: [PATCH 119/132] Updated files --- .../Composite/CompositeOfInstanced/box.glb | Bin 0 -> 5360 bytes .../compositeOfInstanced.cmpt | Bin 11760 -> 1024 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Specs/Data/Cesium3DTiles/Composite/CompositeOfInstanced/box.glb diff --git a/Specs/Data/Cesium3DTiles/Composite/CompositeOfInstanced/box.glb b/Specs/Data/Cesium3DTiles/Composite/CompositeOfInstanced/box.glb new file mode 100644 index 0000000000000000000000000000000000000000..2bde3c4ee98e6dae935c4f9e5e2ee152fbfdc347 GIT binary patch literal 5360 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 Date: Thu, 20 Jul 2017 17:26:00 -0400 Subject: [PATCH 120/132] Update Sandcastle example. --- Apps/Sandcastle/gallery/Classification.html | 189 +++++++++++++++++--- Source/Scene/Scene.js | 18 +- 2 files changed, 175 insertions(+), 32 deletions(-) diff --git a/Apps/Sandcastle/gallery/Classification.html b/Apps/Sandcastle/gallery/Classification.html index ccfbf4192d41..bafb8cf32ffa 100644 --- a/Apps/Sandcastle/gallery/Classification.html +++ b/Apps/Sandcastle/gallery/Classification.html @@ -22,6 +22,7 @@

Loading...

+