diff --git a/Apps/SampleData/ClampToGround.czml b/Apps/SampleData/ClampToGround.czml index 04139df57883..9d5abaccd264 100644 --- a/Apps/SampleData/ClampToGround.czml +++ b/Apps/SampleData/ClampToGround.czml @@ -37,5 +37,33 @@ 0.7686388857813198 ] } + }, + { + "id": "Polyline", + "polyline": { + "positions": { + "cartesian": [ + 1216348.1632364073, + -4736348.958775471, + 4081284.5528982095, + 1216369.1229444197, + -4736377.467107148, + 4081240.888485707 + ] + }, + "material": { + "polylineOutline": { + "color": { + "rgba": [255, 255, 0, 255] + }, + "outlineColor": { + "rgba": [0, 0, 0, 255] + }, + "outlineWidth": 2 + } + }, + "width": 10, + "clampToGround": true + } } ] diff --git a/Apps/Sandcastle/gallery/Clamp to 3D Tiles.jpg b/Apps/Sandcastle/gallery/Clamp to 3D Tiles.jpg index 711e53fc19db..8164f073a8e6 100644 Binary files a/Apps/Sandcastle/gallery/Clamp to 3D Tiles.jpg and b/Apps/Sandcastle/gallery/Clamp to 3D Tiles.jpg differ diff --git a/Apps/Sandcastle/gallery/Classification Types.html b/Apps/Sandcastle/gallery/Classification Types.html index c1d6c8d3d4b4..59a8182ed9da 100644 --- a/Apps/Sandcastle/gallery/Classification Types.html +++ b/Apps/Sandcastle/gallery/Classification Types.html @@ -40,7 +40,7 @@ viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); }); -var entity = viewer.entities.add({ +var polygon = viewer.entities.add({ polygon : { hierarchy : new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromRadiansArray([-1.3194369277314022, 0.6988062530900625, -1.3193955980204217, 0.6988091578771254, -1.3193931220959367, 0.698743632490865, -1.3194358224045408, 0.6987471965556998])), material : Cesium.Color.RED.withAlpha(0.5), @@ -48,32 +48,60 @@ } }); +var polyline = viewer.entities.add({ + polyline : { + positions : Cesium.Cartesian3.fromDegreesArray([ + -75.60217330403601, 40.04102882709425, + -75.59968252414251, 40.04093615560871, + -75.59802015382800, 40.04079437042357, + -75.59674934074435, 40.040816173283304, + -75.59630042791713, 40.03986900370842, + -75.59563636849978, 40.03930996506271, + -75.59492397899098, 40.03873932846581, + -75.59457991226778, 40.038392701955786, + -75.59424838652453, 40.03775403572295, + -75.59387104290336, 40.03677022167725, + -75.59355000490342, 40.03588760913535 + ]), + width : 8, + material : new Cesium.PolylineOutlineMaterialProperty({ + color : Cesium.Color.YELLOW, + outlineWidth : 2, + outlineColor : Cesium.Color.BLACK + }), + clampToGround : true + } +}); + var classificationOptions = [{ text : 'Classify Both', onselect : function() { - entity.polygon.classificationType = Cesium.ClassificationType.BOTH; + polygon.polygon.classificationType = Cesium.ClassificationType.BOTH; + polyline.polyline.classificationType = Cesium.ClassificationType.BOTH; } }, { text : 'Classify Terrain', onselect : function() { - entity.polygon.classificationType = Cesium.ClassificationType.TERRAIN; + polygon.polygon.classificationType = Cesium.ClassificationType.TERRAIN; + polyline.polyline.classificationType = Cesium.ClassificationType.TERRAIN; } }, { text : 'Classify 3D Tiles', onselect : function() { - entity.polygon.classificationType = Cesium.ClassificationType.CESIUM_3D_TILE; + polygon.polygon.classificationType = Cesium.ClassificationType.CESIUM_3D_TILE; + polyline.polyline.classificationType = Cesium.ClassificationType.CESIUM_3D_TILE; } }]; var materialOptions = [{ text : 'Red Material', onselect : function() { - entity.polygon.material = Cesium.Color.RED.withAlpha(0.5); + polygon.polygon.material = Cesium.Color.RED.withAlpha(0.5); } }, { text : 'Textured Material', onselect : function() { - entity.polygon.material = '../images/Cesium_Logo_Color.jpg'; + polygon.polygon.material = '../images/Cesium_Logo_Color.jpg'; } }]; diff --git a/CHANGES.md b/CHANGES.md index 516df500175b..08f4833a9082 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,8 @@ Change Log ##### Additions :tada: * Added support for textured ground entities (entities with unspecified `height`) and `GroundPrimitives` on 3D Tiles. +* Added support for polylines on 3D Tiles. +* Added `classificationType` property to `PolylineGraphics` and `GroundPolylinePrimitive` which specifies whether a polyline clamped to ground should be clamped to terrain, 3D Tiles, or both. ##### Fixes :wrench: * Fixed an issue where classification primitives with the `CESIUM_3D_TILE` classification type would render on terrain. diff --git a/Source/Core/GroundPolylineGeometry.js b/Source/Core/GroundPolylineGeometry.js index 1c03744df648..c29e2748f5d7 100644 --- a/Source/Core/GroundPolylineGeometry.js +++ b/Source/Core/GroundPolylineGeometry.js @@ -70,7 +70,7 @@ define([ var WALL_INITIAL_MAX_HEIGHT = 1000.0; /** - * A description of a polyline on terrain. Only to be used with {@link GroundPolylinePrimitive}. + * A description of a polyline on terrain or 3D Tiles. Only to be used with {@link GroundPolylinePrimitive}. * * @alias GroundPolylineGeometry * @constructor @@ -159,7 +159,7 @@ define([ * Set the GroundPolylineGeometry's projection and ellipsoid. * Used by GroundPolylinePrimitive to signal scene information to the geometry for generating 2D attributes. * - * @param {GroundPolylineGeometry} groundPolylineGeometry GroundPolylinGeometry describing a polyline on terrain. + * @param {GroundPolylineGeometry} groundPolylineGeometry GroundPolylinGeometry describing a polyline on terrain or 3D Tiles. * @param {Projection} mapProjection A MapProjection used for projecting cartographic coordinates to 2D. * @private */ @@ -386,7 +386,7 @@ define([ var intersectionScratch = new Cartesian3(); /** * Computes shadow volumes for the ground polyline, consisting of its vertices, indices, and a bounding sphere. - * Vertices are "fat," packing all the data needed in each volume to describe a line on terrain. + * Vertices are "fat," packing all the data needed in each volume to describe a line on terrain or 3D Tiles. * Should not be called independent of {@link GroundPolylinePrimitive}. * * @param {GroundPolylineGeometry} groundPolylineGeometry diff --git a/Source/DataSources/CorridorGraphics.js b/Source/DataSources/CorridorGraphics.js index 268f4e7da314..aef29581bf11 100644 --- a/Source/DataSources/CorridorGraphics.js +++ b/Source/DataSources/CorridorGraphics.js @@ -41,6 +41,7 @@ define([ * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the distance between each latitude and longitude. * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the corridor casts or receives shadows from each light source. * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this corridor will be displayed. + * @param {Property} [options.classificationType=ClassificationType.BOTH] An enum Property specifying whether this corridor will classify terrain, 3D Tiles, or both when on the ground. * @param {ConstantProperty} [options.zIndex] A Property specifying the zIndex of the corridor, used for ordering. Only has an effect if height and extrudedHeight are undefined, and if the corridor is static. * * @see Entity @@ -232,7 +233,7 @@ define([ * Gets or sets the {@link ClassificationType} Property specifying whether this corridor will classify terrain, 3D Tiles, or both when on the ground. * @memberof CorridorGraphics.prototype * @type {Property} - * @default ClassificationType.TERRAIN + * @default ClassificationType.BOTH */ classificationType : createPropertyDescriptor('classificationType'), diff --git a/Source/DataSources/EllipseGraphics.js b/Source/DataSources/EllipseGraphics.js index c120ffc691c1..acdf7b9e1d29 100644 --- a/Source/DataSources/EllipseGraphics.js +++ b/Source/DataSources/EllipseGraphics.js @@ -44,6 +44,7 @@ define([ * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between points on the ellipse. * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the ellipse casts or receives shadows from each light source. * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this ellipse will be displayed. + * @param {Property} [options.classificationType=ClassificationType.BOTH] An enum Property specifying whether this ellipse will classify terrain, 3D Tiles, or both when on the ground. * @param {ConstantProperty} [options.zIndex=0] A property specifying the zIndex of the Ellipse. Used for ordering ground geometry. Only has an effect if the ellipse is constant and neither height or exturdedHeight are specified. * * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Circles and Ellipses.html|Cesium Sandcastle Circles and Ellipses Demo} @@ -254,7 +255,7 @@ define([ * Gets or sets the {@link ClassificationType} Property specifying whether this ellipse will classify terrain, 3D Tiles, or both when on the ground. * @memberof EllipseGraphics.prototype * @type {Property} - * @default ClassificationType.TERRAIN + * @default ClassificationType.BOTH */ classificationType : createPropertyDescriptor('classificationType'), diff --git a/Source/DataSources/Entity.js b/Source/DataSources/Entity.js index f3b8eb4411ca..dae9820c5d4d 100644 --- a/Source/DataSources/Entity.js +++ b/Source/DataSources/Entity.js @@ -676,12 +676,12 @@ define([ }; /** - * Checks if the given Scene supports polylines clamped to the ground.. + * Checks if the given Scene supports polylines clamped to terrain or 3D Tiles. * If this feature is not supported, Entities with PolylineGraphics will be rendered with vertices at * the provided heights and using the `followSurface` parameter instead of clamped to the ground. * * @param {Scene} scene The current scene. - * @returns {Boolean} Whether or not the current scene supports Polylines on Terrain. + * @returns {Boolean} Whether or not the current scene supports polylines on terrain or 3D TIles. */ Entity.supportsPolylinesOnTerrain = function(scene) { return GroundPolylinePrimitive.isSupported(scene); diff --git a/Source/DataSources/PolygonGraphics.js b/Source/DataSources/PolygonGraphics.js index 5eb968df4d59..fb65382cb61e 100644 --- a/Source/DataSources/PolygonGraphics.js +++ b/Source/DataSources/PolygonGraphics.js @@ -43,6 +43,7 @@ define([ * @param {Boolean} [options.closeBottom=true] When false, leaves off the bottom of an extruded polygon open. * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the polygon casts or receives shadows from each light source. * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this polygon will be displayed. + * @param {Property} [options.classificationType=ClassificationType.BOTH] An enum Property specifying whether this polygon will classify terrain, 3D Tiles, or both when on the ground. * @param {ConstantProperty} [options.zIndex=0] A property specifying the zIndex used for ordering ground geometry. Only has an effect if the polygon is constant and neither height or extrudedHeight are specified. * * @see Entity @@ -255,7 +256,7 @@ define([ * Gets or sets the {@link ClassificationType} Property specifying whether this polygon will classify terrain, 3D Tiles, or both when on the ground. * @memberof PolygonGraphics.prototype * @type {Property} - * @default ClassificationType.TERRAIN + * @default ClassificationType.BOTH */ classificationType : createPropertyDescriptor('classificationType'), diff --git a/Source/DataSources/PolylineGeometryUpdater.js b/Source/DataSources/PolylineGeometryUpdater.js index 87e1258e9005..8cc63def39b1 100644 --- a/Source/DataSources/PolylineGeometryUpdater.js +++ b/Source/DataSources/PolylineGeometryUpdater.js @@ -18,6 +18,7 @@ define([ '../Core/PolylinePipeline', '../Core/ShowGeometryInstanceAttribute', '../DataSources/Entity', + '../Scene/ClassificationType', '../Scene/GroundPolylinePrimitive', '../Scene/PolylineCollection', '../Scene/PolylineColorAppearance', @@ -48,6 +49,7 @@ define([ PolylinePipeline, ShowGeometryInstanceAttribute, Entity, + ClassificationType, GroundPolylinePrimitive, PolylineCollection, PolylineColorAppearance, @@ -70,6 +72,7 @@ define([ var defaultShow = new ConstantProperty(true); var defaultShadows = new ConstantProperty(ShadowMode.DISABLED); var defaultDistanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + var defaultClassificationType = new ConstantProperty(ClassificationType.BOTH); function GeometryOptions() { this.vertexFormat = undefined; @@ -113,6 +116,7 @@ define([ this._materialProperty = undefined; this._shadowsProperty = undefined; this._distanceDisplayConditionProperty = undefined; + this._classificationTypeProperty = undefined; this._depthFailMaterialProperty = undefined; this._geometryOptions = new GeometryOptions(); this._groundGeometryOptions = new GroundGeometryOptions(); @@ -252,6 +256,18 @@ define([ return this._distanceDisplayConditionProperty; } }, + /** + * Gets or sets the {@link ClassificationType} Property specifying if this geometry will classify terrain, 3D Tiles, or both when on the ground. + * @memberof PolylineGeometryUpdater.prototype + * + * @type {Property} + * @readonly + */ + classificationTypeProperty : { + get : function() { + return this._classificationTypeProperty; + } + }, /** * Gets a value indicating if the geometry is time-varying. * If true, all visualization is delegated to the {@link DynamicGeometryUpdater} @@ -473,6 +489,7 @@ define([ this._showProperty = defaultValue(show, defaultShow); this._shadowsProperty = defaultValue(polyline.shadows, defaultShadows); this._distanceDisplayConditionProperty = defaultValue(polyline.distanceDisplayCondition, defaultDistanceDisplayCondition); + this._classificationTypeProperty = defaultValue(polyline.classificationType, defaultClassificationType); this._fillEnabled = true; this._zIndex = defaultValue(zIndex, defaultZIndex); @@ -493,7 +510,7 @@ define([ var positions = positionsProperty.getValue(Iso8601.MINIMUM_VALUE, geometryOptions.positions); //Because of the way we currently handle reference properties, - //we can't automatically assume the positions are always valid. + //we can't automatically assume the positions are always valid. if (!defined(positions) || positions.length < 2) { if (this._fillEnabled) { this._fillEnabled = false; @@ -635,6 +652,7 @@ define([ this._groundPolylinePrimitive = groundPrimitives.add(new GroundPolylinePrimitive({ geometryInstances : geometryUpdater.createFillGeometryInstance(time), appearance : appearance, + classificationType : geometryUpdater.classificationTypeProperty.getValue(time), asynchronous : false }), Property.getValueOrUndefined(geometryUpdater.zIndex, time)); diff --git a/Source/DataSources/PolylineGraphics.js b/Source/DataSources/PolylineGraphics.js index 3700d18ec149..8f1e912d3cfc 100644 --- a/Source/DataSources/PolylineGraphics.js +++ b/Source/DataSources/PolylineGraphics.js @@ -31,10 +31,11 @@ define([ * @param {Property} [options.width=1.0] A numeric Property specifying the width in pixels. * @param {Property} [options.show=true] A boolean Property specifying the visibility of the polyline. * @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to draw the polyline. - * @param {MaterialProperty} [options.depthFailMaterial] A property specifiying the material used to draw the polyline when it is below the terrain. + * @param {MaterialProperty} [options.depthFailMaterial] A property specifying the material used to draw the polyline when it is below the terrain. * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between each latitude and longitude if followSurface is true. * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the polyline casts or receives shadows from each light source. * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this polyline will be displayed. + * @param {Property} [options.classificationType=ClassificationType.BOTH] An enum Property specifying whether this polyline will classify terrain, 3D Tiles, or both when on the ground. * @param {Property} [options.zIndex=0] A Property specifying the zIndex used for ordering ground geometry. Only has an effect if `clampToGround` is true and polylines on terrain is supported. * * @see Entity @@ -62,6 +63,8 @@ define([ this._shadowsSubscription = undefined; this._distanceDisplayCondition = undefined; this._distanceDisplayConditionSubscription = undefined; + this._classificationType = undefined; + this._classificationTypeSubscription = undefined; this._zIndex = undefined; this._zIndexSubscription = undefined; @@ -170,6 +173,14 @@ define([ */ distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition'), + /** + * Gets or sets the {@link ClassificationType} Property specifying whether this polyline will classify terrain, 3D Tiles, or both when on the ground. + * @memberof PolylineGraphics.prototype + * @type {Property} + * @default ClassificationType.BOTH + */ + classificationType : createPropertyDescriptor('classificationType'), + /** * Gets or sets the zIndex Property specifying the ordering of the polyline. Only has an effect if `clampToGround` is true and polylines on terrain is supported. * @memberof RectangleGraphics.prototype @@ -199,6 +210,7 @@ define([ result.granularity = this.granularity; result.shadows = this.shadows; result.distanceDisplayCondition = this.distanceDisplayCondition; + result.classificationType = this.classificationType; result.zIndex = this.zIndex; return result; @@ -227,6 +239,7 @@ define([ this.granularity = defaultValue(this.granularity, source.granularity); this.shadows = defaultValue(this.shadows, source.shadows); this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition); + this.classificationType = defaultValue(this.classificationType, source.classificationType); this.zIndex = defaultValue(this.zIndex, source.zIndex); }; diff --git a/Source/DataSources/PolylineVisualizer.js b/Source/DataSources/PolylineVisualizer.js index 7bf86fc489ae..a8c7b9d7925a 100644 --- a/Source/DataSources/PolylineVisualizer.js +++ b/Source/DataSources/PolylineVisualizer.js @@ -5,6 +5,7 @@ define([ '../Core/defaultValue', '../Core/defined', '../Core/destroyObject', + '../Scene/ClassificationType', '../Scene/PolylineColorAppearance', '../Scene/PolylineMaterialAppearance', '../Scene/ShadowMode', @@ -22,6 +23,7 @@ define([ defaultValue, defined, destroyObject, + ClassificationType, PolylineColorAppearance, PolylineMaterialAppearance, ShadowMode, @@ -52,7 +54,8 @@ define([ } if (updater.clampToGround && updater.fillEnabled) { // Also checks for support - that._groundBatch.add(time, updater); + var classificationType = updater.classificationTypeProperty.getValue(time); + that._groundBatches[classificationType].add(time, updater); return; } @@ -106,11 +109,12 @@ define([ this._removedObjects = new AssociativeArray(); this._changedObjects = new AssociativeArray(); + var i; var numberOfShadowModes = ShadowMode.NUMBER_OF_SHADOW_MODES; this._colorBatches = new Array(numberOfShadowModes * 3); this._materialBatches = new Array(numberOfShadowModes * 3); - for (var i = 0; i < numberOfShadowModes; ++i) { + for (i = 0; i < numberOfShadowModes; ++i) { this._colorBatches[i] = new StaticGeometryColorBatch(primitives, PolylineColorAppearance, undefined, false, i); // no depth fail appearance this._materialBatches[i] = new StaticGeometryPerMaterialBatch(primitives, PolylineMaterialAppearance, undefined, false, i); @@ -122,10 +126,15 @@ define([ } this._dynamicBatch = new DynamicGeometryBatch(primitives, groundPrimitives); - // Only available for terrain classification - this._groundBatch = new StaticGroundPolylinePerMaterialBatch(groundPrimitives); - this._batches = this._colorBatches.concat(this._materialBatches, this._dynamicBatch, this._groundBatch); + var numberOfClassificationTypes = ClassificationType.NUMBER_OF_CLASSIFICATION_TYPES; + this._groundBatches = new Array(numberOfClassificationTypes); + + for (i = 0; i < numberOfClassificationTypes; ++i) { + this._groundBatches[i] = new StaticGroundPolylinePerMaterialBatch(groundPrimitives, i); + } + + this._batches = this._colorBatches.concat(this._materialBatches, this._dynamicBatch, this._groundBatches); this._subscriptions = new AssociativeArray(); this._updaters = new AssociativeArray(); diff --git a/Source/DataSources/RectangleGraphics.js b/Source/DataSources/RectangleGraphics.js index 9840679d75d0..69b251c1a684 100644 --- a/Source/DataSources/RectangleGraphics.js +++ b/Source/DataSources/RectangleGraphics.js @@ -41,6 +41,7 @@ define([ * @param {Property} [options.granularity=Cesium.Math.RADIANS_PER_DEGREE] A numeric Property specifying the angular distance between points on the rectangle. * @param {Property} [options.shadows=ShadowMode.DISABLED] An enum Property specifying whether the rectangle casts or receives shadows from each light source. * @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this rectangle will be displayed. + * @param {Property} [options.classificationType=ClassificationType.BOTH] An enum Property specifying whether this rectangle will classify terrain, 3D Tiles, or both when on the ground. * @param {Property} [options.zIndex=0] A Property specifying the zIndex used for ordering ground geometry. Only has an effect if the rectangle is constant and neither height or extrudedHeight are specified. * * @see Entity @@ -234,7 +235,7 @@ define([ * Gets or sets the {@link ClassificationType} Property specifying whether this rectangle will classify terrain, 3D Tiles, or both when on the ground. * @memberof RectangleGraphics.prototype * @type {Property} - * @default ClassificationType.TERRAIN + * @default ClassificationType.BOTH */ classificationType : createPropertyDescriptor('classificationType'), diff --git a/Source/DataSources/StaticGroundPolylinePerMaterialBatch.js b/Source/DataSources/StaticGroundPolylinePerMaterialBatch.js index 5770e15b8183..399348c4c529 100644 --- a/Source/DataSources/StaticGroundPolylinePerMaterialBatch.js +++ b/Source/DataSources/StaticGroundPolylinePerMaterialBatch.js @@ -37,7 +37,7 @@ define([ var defaultDistanceDisplayCondition = new DistanceDisplayCondition(); // Encapsulates a Primitive and all the entities that it represents. - function Batch(orderedGroundPrimitives, materialProperty, zIndex, asynchronous) { + function Batch(orderedGroundPrimitives, classificationType, materialProperty, zIndex, asynchronous) { var appearanceType; if (materialProperty instanceof ColorMaterialProperty) { appearanceType = PolylineColorAppearance; @@ -46,6 +46,7 @@ define([ } this.orderedGroundPrimitives = orderedGroundPrimitives; // scene level primitive collection + this.classificationType = classificationType; this.appearanceType = appearanceType; this.materialProperty = materialProperty; this.updaters = new AssociativeArray(); @@ -139,7 +140,8 @@ define([ show : false, asynchronous : this._asynchronous, geometryInstances : geometries, - appearance : new this.appearanceType() + appearance : new this.appearanceType(), + classificationType : this.classificationType }); if (this.appearanceType === PolylineMaterialAppearance) { @@ -278,9 +280,10 @@ define([ /** * @private */ - function StaticGroundPolylinePerMaterialBatch(orderedGroundPrimitives, asynchronous) { + function StaticGroundPolylinePerMaterialBatch(orderedGroundPrimitives, classificationType, asynchronous) { this._items = []; this._orderedGroundPrimitives = orderedGroundPrimitives; + this._classificationType = classificationType; this._asynchronous = defaultValue(asynchronous, true); } @@ -299,7 +302,7 @@ define([ } } // If a compatible batch wasn't found, create a new batch. - var batch = new Batch(this._orderedGroundPrimitives, updater.fillMaterialProperty, zIndex, this._asynchronous); + var batch = new Batch(this._orderedGroundPrimitives, this._classificationType, updater.fillMaterialProperty, zIndex, this._asynchronous); batch.add(time, updater, geometryInstance); items.push(batch); }; diff --git a/Source/Scene/ClassificationPrimitive.js b/Source/Scene/ClassificationPrimitive.js index d0dcc4695b7a..764ee174c20a 100644 --- a/Source/Scene/ClassificationPrimitive.js +++ b/Source/Scene/ClassificationPrimitive.js @@ -766,7 +766,6 @@ define([ // Then derive from the 3D Tiles command derived2DCommand = DrawCommand.shallowClone(derivedCommand, derivedCommand.derivedCommands.appearance2D); derived2DCommand.shaderProgram = classificationPrimitive._spColor2D; - derived2DCommand.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION; derivedCommand.derivedCommands.appearance2D = derived2DCommand; } } @@ -908,7 +907,6 @@ define([ // Then derive from the 3D Tiles command derived2DCommand = DrawCommand.shallowClone(derivedCommand, derivedCommand.derivedCommands.pick2D); derived2DCommand.shaderProgram = classificationPrimitive._spPick2D; - derived2DCommand.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION; derivedCommand.derivedCommands.pick2D = derived2DCommand; } } diff --git a/Source/Scene/GroundPolylinePrimitive.js b/Source/Scene/GroundPolylinePrimitive.js index 7d052e567843..b8ebf53ea7a9 100644 --- a/Source/Scene/GroundPolylinePrimitive.js +++ b/Source/Scene/GroundPolylinePrimitive.js @@ -21,11 +21,15 @@ define([ '../Renderer/ShaderSource', '../ThirdParty/when', './BlendingState', + './ClassificationType', './CullFace', './PolylineColorAppearance', './PolylineMaterialAppearance', './Primitive', - './SceneMode' + './SceneMode', + './StencilConstants', + './StencilFunction', + './StencilOperation' ], function( ApproximateTerrainHeights, ComponentDatatype, @@ -49,18 +53,22 @@ define([ ShaderSource, when, BlendingState, + ClassificationType, CullFace, PolylineColorAppearance, PolylineMaterialAppearance, Primitive, - SceneMode) { + SceneMode, + StencilConstants, + StencilFunction, + StencilOperation) { 'use strict'; /** - * A GroundPolylinePrimitive represents a polyline draped over the terrain in the {@link Scene}. + * A GroundPolylinePrimitive represents a polyline draped over the terrain or 3D Tiles in the {@link Scene}. *
- * * Only to be used with GeometryInstances containing {@link GroundPolylineGeometry}. + *
* * @alias GroundPolylinePrimitive * @constructor @@ -73,6 +81,7 @@ define([ * @param {Boolean} [options.releaseGeometryInstances=true] Whentrue
, 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 {ClassificationType} [options.classificationType=ClassificationType.BOTH] Determines whether terrain, 3D Tiles or both will be classified.
* @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 to have effect.
*
@@ -168,6 +177,15 @@ define([
*/
this.show = defaultValue(options.show, true);
+ /**
+ * Determines whether terrain, 3D Tiles or both will be classified.
+ *
+ * @type {ClassificationType}
+ *
+ * @default ClassificationType.BOTH
+ */
+ this.classificationType = defaultValue(options.classificationType, ClassificationType.BOTH);
+
/**
* This property is for debugging only; it is not for production use nor is it optimized.
* @@ -209,13 +227,8 @@ define([ this._sp2D = undefined; this._spMorph = undefined; - this._renderState = RenderState.fromCache({ - cull : { - enabled : true // prevent double-draw. Geometry is "inverted" (reversed winding order) so we're drawing backfaces. - }, - blending : BlendingState.ALPHA_BLEND, - depthMask : false - }); + this._renderState = getRenderState(false); + this._renderState3DTiles = getRenderState(true); this._renderStateMorph = RenderState.fromCache({ cull : { @@ -454,6 +467,33 @@ define([ groundPolylinePrimitive._spMorph = colorProgramMorph; } + function getRenderState(mask3DTiles) { + return RenderState.fromCache({ + cull : { + enabled : true // prevent double-draw. Geometry is "inverted" (reversed winding order) so we're drawing backfaces. + }, + blending : BlendingState.ALPHA_BLEND, + depthMask : false, + stencilTest : { + enabled : mask3DTiles, + frontFunction : StencilFunction.EQUAL, + frontOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.KEEP + }, + backFunction : StencilFunction.EQUAL, + backOperation : { + fail : StencilOperation.KEEP, + zFail : StencilOperation.KEEP, + zPass : StencilOperation.KEEP + }, + reference : StencilConstants.CESIUM_3D_TILE_MASK, + mask : StencilConstants.CESIUM_3D_TILE_MASK + } + }); + } + function createCommands(groundPolylinePrimitive, appearance, material, translucent, colorCommands, pickCommands) { var primitive = groundPolylinePrimitive._primitive; var length = primitive._va.length; @@ -462,16 +502,13 @@ define([ var isPolylineColorAppearance = appearance instanceof PolylineColorAppearance; - var i; - var command; var materialUniforms = isPolylineColorAppearance ? {} : material._uniforms; var uniformMap = primitive._batchTable.getUniformMapCallback()(materialUniforms); - var pass = Pass.TERRAIN_CLASSIFICATION; - for (i = 0; i < length; i++) { + for (var i = 0; i < length; i++) { var vertexArray = primitive._va[i]; - command = colorCommands[i]; + var command = colorCommands[i]; if (!defined(command)) { command = colorCommands[i] = new DrawCommand({ owner : groundPolylinePrimitive, @@ -483,37 +520,47 @@ define([ command.renderState = groundPolylinePrimitive._renderState; command.shaderProgram = groundPolylinePrimitive._sp; command.uniformMap = uniformMap; - command.pass = pass; + command.pass = Pass.TERRAIN_CLASSIFICATION; command.pickId = 'czm_batchTable_pickColor(v_endPlaneNormalEcAndBatchId.w)'; + var derivedTilesetCommand = DrawCommand.shallowClone(command, command.derivedCommands.tileset); + derivedTilesetCommand.renderState = groundPolylinePrimitive._renderState3DTiles; + derivedTilesetCommand.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION; + command.derivedCommands.tileset = derivedTilesetCommand; + // derive for 2D - var derivedColorCommand = command.derivedCommands.color2D; - if (!defined(derivedColorCommand)) { - derivedColorCommand = DrawCommand.shallowClone(command); - command.derivedCommands.color2D = derivedColorCommand; - } - derivedColorCommand.vertexArray = vertexArray; - derivedColorCommand.renderState = groundPolylinePrimitive._renderState; - derivedColorCommand.shaderProgram = groundPolylinePrimitive._sp2D; - derivedColorCommand.uniformMap = uniformMap; - derivedColorCommand.pass = pass; - derivedColorCommand.pickId = 'czm_batchTable_pickColor(v_endPlaneNormalEcAndBatchId.w)'; + var derived2DCommand = DrawCommand.shallowClone(command, command.derivedCommands.color2D); + derived2DCommand.shaderProgram = groundPolylinePrimitive._sp2D; + command.derivedCommands.color2D = derived2DCommand; + + var derived2DTilesetCommand = DrawCommand.shallowClone(derivedTilesetCommand, derivedTilesetCommand.derivedCommands.color2D); + derived2DTilesetCommand.shaderProgram = groundPolylinePrimitive._sp2D; + derivedTilesetCommand.derivedCommands.color2D = derived2DTilesetCommand; // derive for Morph - derivedColorCommand = command.derivedCommands.colorMorph; - if (!defined(derivedColorCommand)) { - derivedColorCommand = DrawCommand.shallowClone(command); - command.derivedCommands.colorMorph = derivedColorCommand; - } - derivedColorCommand.vertexArray = vertexArray; - derivedColorCommand.renderState = groundPolylinePrimitive._renderStateMorph; - derivedColorCommand.shaderProgram = groundPolylinePrimitive._spMorph; - derivedColorCommand.uniformMap = uniformMap; - derivedColorCommand.pass = pass; - derivedColorCommand.pickId = 'czm_batchTable_pickColor(v_batchId)'; + var derivedMorphCommand = DrawCommand.shallowClone(command, command.derivedCommands.colorMorph); + derivedMorphCommand.renderState = groundPolylinePrimitive._renderStateMorph; + derivedMorphCommand.shaderProgram = groundPolylinePrimitive._spMorph; + derivedMorphCommand.pickId = 'czm_batchTable_pickColor(v_batchId)'; + command.derivedCommands.colorMorph = derivedMorphCommand; } } + function updateAndQueueCommand(groundPolylinePrimitive, command, frameState, modelMatrix, cull, boundingVolume, debugShowBoundingVolume) { + // Use derived appearance command for morph and 2D + if (frameState.mode === SceneMode.MORPHING) { + command = command.derivedCommands.colorMorph; + } else if (frameState.mode !== SceneMode.SCENE3D) { + command = command.derivedCommands.color2D; + } + command.modelMatrix = modelMatrix; + command.boundingVolume = boundingVolume; + command.cull = cull; + command.debugShowBoundingVolume = debugShowBoundingVolume; + + frameState.commandList.push(command); + } + function updateAndQueueCommands(groundPolylinePrimitive, frameState, colorCommands, pickCommands, modelMatrix, cull, debugShowBoundingVolume) { var primitive = groundPolylinePrimitive._primitive; @@ -530,25 +577,25 @@ define([ boundingSpheres = primitive._boundingSphereMorph; } - var commandList = frameState.commandList; + var morphing = frameState.mode === SceneMode.MORPHING; + var classificationType = groundPolylinePrimitive.classificationType; + var queueTerrainCommands = (classificationType !== ClassificationType.CESIUM_3D_TILE); + var queue3DTilesCommands = (classificationType !== ClassificationType.TERRAIN) && !morphing; + + var command; var passes = frameState.passes; if (passes.render || (passes.pick && primitive.allowPicking)) { var colorLength = colorCommands.length; - for (var j = 0; j < colorLength; ++j) { - var colorCommand = colorCommands[j]; - // Use derived appearance command for morph and 2D - if (frameState.mode === SceneMode.MORPHING && colorCommand.shaderProgram !== groundPolylinePrimitive._spMorph) { - colorCommand = colorCommand.derivedCommands.colorMorph; - } else if (frameState.mode !== SceneMode.SCENE3D && colorCommand.shaderProgram !== groundPolylinePrimitive._sp2D) { - colorCommand = colorCommand.derivedCommands.color2D; + var boundingVolume = boundingSpheres[j]; + if (queueTerrainCommands) { + command = colorCommands[j]; + updateAndQueueCommand(groundPolylinePrimitive, command, frameState, modelMatrix, cull, boundingVolume, debugShowBoundingVolume); + } + if (queue3DTilesCommands) { + command = colorCommands[j].derivedCommands.tileset; + updateAndQueueCommand(groundPolylinePrimitive, command, frameState, modelMatrix, cull, boundingVolume, debugShowBoundingVolume); } - colorCommand.modelMatrix = modelMatrix; - colorCommand.boundingVolume = boundingSpheres[j]; - colorCommand.cull = cull; - colorCommand.debugShowBoundingVolume = debugShowBoundingVolume; - - commandList.push(colorCommand); } } } diff --git a/Specs/DataSources/GeometryVisualizerSpec.js b/Specs/DataSources/GeometryVisualizerSpec.js index 489d7694c243..f7f0ba49c965 100644 --- a/Specs/DataSources/GeometryVisualizerSpec.js +++ b/Specs/DataSources/GeometryVisualizerSpec.js @@ -82,6 +82,24 @@ defineSuite([ }); + function visualizerUpdated(visualizer) { + return pollToPromise(function() { + scene.initializeFrame(); + var isUpdated = visualizer.update(time); + scene.render(time); + return isUpdated; + }); + } + + function visualizerEmpty(visualizer) { + return pollToPromise(function() { + scene.initializeFrame(); + expect(visualizer.update(time)).toBe(true); + scene.render(time); + return scene.primitives.length === 0 && scene.groundPrimitives.length === 0; + }); + } + it('Can create and destroy', function() { var objects = new EntityCollection(); var visualizer = new GeometryVisualizer(scene, objects, scene.primitives, scene.groundPrimitives); @@ -107,12 +125,7 @@ defineSuite([ entity.ellipse = ellipse; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -123,12 +136,7 @@ defineSuite([ objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.primitives.length === 0; - }).then(function(){ + return visualizerEmpty(visualizer).then(function(){ visualizer.destroy(); }); }); @@ -149,12 +157,7 @@ defineSuite([ entity.ellipse = ellipse; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -165,12 +168,7 @@ defineSuite([ objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.primitives.length === 0; - }).then(function(){ + return visualizerEmpty(visualizer).then(function(){ visualizer.destroy(); }); }); @@ -191,12 +189,7 @@ defineSuite([ entity.ellipse = ellipse; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -207,12 +200,7 @@ defineSuite([ objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.primitives.length === 0; - }).then(function(){ + return visualizerEmpty(visualizer).then(function(){ visualizer.destroy(); }); }); @@ -233,12 +221,7 @@ defineSuite([ entity.ellipse = ellipse; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -249,12 +232,7 @@ defineSuite([ objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.primitives.length === 0; - }).then(function(){ + return visualizerEmpty(visualizer).then(function(){ visualizer.destroy(); }); }); @@ -276,12 +254,7 @@ defineSuite([ entity.ellipse = ellipse; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -291,12 +264,7 @@ defineSuite([ objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.primitives.length === 0; - }).then(function(){ + return visualizerEmpty(visualizer).then(function(){ visualizer.destroy(); }); }); @@ -318,23 +286,13 @@ defineSuite([ entity.ellipse = ellipse; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); expect(primitive.shadows).toBe(shadows); objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.primitives.length === 0; - }).then(function(){ + return visualizerEmpty(visualizer).then(function(){ visualizer.destroy(); }); }); @@ -371,23 +329,13 @@ defineSuite([ entity.ellipse = ellipse; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.groundPrimitives.get(0); expect(primitive.classificationType).toBe(type); objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.primitives.length === 0; - }).then(function(){ + return visualizerEmpty(visualizer).then(function(){ visualizer.destroy(); }); }); @@ -420,12 +368,7 @@ defineSuite([ entity.ellipse = ellipse; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -435,12 +378,7 @@ defineSuite([ ellipse.material = new GridMaterialProperty(); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { primitive = scene.primitives.get(0); attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -476,12 +414,7 @@ defineSuite([ } }); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -490,12 +423,7 @@ defineSuite([ color = Color.RED.withAlpha(0.5); entity.ellipse.outlineColor.setValue(color); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }); + return visualizerUpdated(visualizer); }).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); @@ -662,12 +590,7 @@ defineSuite([ }); objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { objects.remove(entity); var entity2 = new Entity({ @@ -682,13 +605,7 @@ defineSuite([ }); objects.add(entity2); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { - + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity2); expect(attributes).toBeDefined(); @@ -698,12 +615,7 @@ defineSuite([ objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.primitives.length === 0; - }).then(function() { + return visualizerEmpty(visualizer).then(function() { visualizer.destroy(); }); }); @@ -724,12 +636,7 @@ defineSuite([ } }); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -737,12 +644,7 @@ defineSuite([ entity.show = false; - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }); + return visualizerUpdated(visualizer); }).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); @@ -769,12 +671,7 @@ defineSuite([ } }); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -782,12 +679,7 @@ defineSuite([ entity.show = false; - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }); + return visualizerUpdated(visualizer); }).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); @@ -815,12 +707,7 @@ defineSuite([ } }); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -828,12 +715,7 @@ defineSuite([ entity.show = false; - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }); + return visualizerUpdated(visualizer); }).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); @@ -862,12 +744,7 @@ defineSuite([ } }); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { expect(scene.groundPrimitives.length).toEqual(1); entities.add({ @@ -879,12 +756,7 @@ defineSuite([ } }); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }); + return visualizerUpdated(visualizer); }).then(function() { expect(scene.groundPrimitives.length).toEqual(1); @@ -897,12 +769,7 @@ defineSuite([ } }); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }); + return visualizerUpdated(visualizer); }).then(function() { expect(scene.groundPrimitives.length).toEqual(2); @@ -930,12 +797,7 @@ defineSuite([ } }); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { expect(scene.groundPrimitives.length).toEqual(1); entities.add({ @@ -948,12 +810,7 @@ defineSuite([ } }); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }); + return visualizerUpdated(visualizer); }).then(function() { expect(scene.groundPrimitives.length).toEqual(1); @@ -967,12 +824,7 @@ defineSuite([ } }); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }); + return visualizerUpdated(visualizer); }).then(function() { expect(scene.groundPrimitives.length).toEqual(1); @@ -986,12 +838,7 @@ defineSuite([ } }); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }); + return visualizerUpdated(visualizer); }).then(function() { expect(scene.groundPrimitives.length).toEqual(2); @@ -1005,12 +852,7 @@ defineSuite([ } }); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }); + return visualizerUpdated(visualizer); }).then(function() { expect(scene.groundPrimitives.length).toEqual(3); diff --git a/Specs/DataSources/PolylineGraphicsSpec.js b/Specs/DataSources/PolylineGraphicsSpec.js index 97a69c5a8a19..b44bb4244dfe 100644 --- a/Specs/DataSources/PolylineGraphicsSpec.js +++ b/Specs/DataSources/PolylineGraphicsSpec.js @@ -4,6 +4,7 @@ defineSuite([ 'Core/DistanceDisplayCondition', 'DataSources/ColorMaterialProperty', 'DataSources/ConstantProperty', + 'Scene/ClassificationType', 'Scene/ShadowMode', 'Specs/testDefinitionChanged', 'Specs/testMaterialDefinitionChanged' @@ -13,6 +14,7 @@ defineSuite([ DistanceDisplayCondition, ColorMaterialProperty, ConstantProperty, + ClassificationType, ShadowMode, testDefinitionChanged, testMaterialDefinitionChanged) { @@ -30,6 +32,7 @@ defineSuite([ granularity : 2, shadows : ShadowMode.DISABLED, distanceDisplayCondition : new DistanceDisplayCondition(), + classificationType : ClassificationType.TERRAIN, zIndex : 0 }; @@ -44,6 +47,7 @@ defineSuite([ expect(polyline.granularity).toBeInstanceOf(ConstantProperty); expect(polyline.shadows).toBeInstanceOf(ConstantProperty); expect(polyline.distanceDisplayCondition).toBeInstanceOf(ConstantProperty); + expect(polyline.classificationType).toBeInstanceOf(ConstantProperty); expect(polyline.zIndex).toBeInstanceOf(ConstantProperty); expect(polyline.material.color.getValue()).toEqual(options.material); @@ -56,6 +60,7 @@ defineSuite([ expect(polyline.granularity.getValue()).toEqual(options.granularity); expect(polyline.shadows.getValue()).toEqual(options.shadows); expect(polyline.distanceDisplayCondition.getValue()).toEqual(options.distanceDisplayCondition); + expect(polyline.classificationType.getValue()).toEqual(options.classificationType); expect(polyline.zIndex.getValue()).toEqual(options.zIndex); }); @@ -71,6 +76,7 @@ defineSuite([ source.granularity = new ConstantProperty(); source.shadows = new ConstantProperty(ShadowMode.ENABLED); source.distanceDisplayCondition = new ConstantProperty(new DistanceDisplayCondition()); + source.classificationType = new ConstantProperty(ClassificationType.TERRAIN); source.zIndex = new ConstantProperty(); var target = new PolylineGraphics(); @@ -85,6 +91,7 @@ defineSuite([ expect(target.granularity).toBe(source.granularity); expect(target.shadows).toBe(source.shadows); expect(target.distanceDisplayCondition).toBe(source.distanceDisplayCondition); + expect(target.classificationType).toBe(source.classificationType); expect(target.zIndex).toBe(source.zIndex); }); @@ -100,6 +107,7 @@ defineSuite([ source.granularity = new ConstantProperty(); source.shadows = new ConstantProperty(); source.distanceDisplayCondition = new ConstantProperty(); + source.classificationType = new ConstantProperty(); source.zIndex = new ConstantProperty(); var color = new ColorMaterialProperty(); @@ -112,6 +120,7 @@ defineSuite([ var granularity = new ConstantProperty(); var shadows = new ConstantProperty(); var distanceDisplayCondition = new ConstantProperty(); + var classificationType = new ConstantProperty(); var zIndex = new ConstantProperty(); var target = new PolylineGraphics(); @@ -125,6 +134,7 @@ defineSuite([ target.granularity = granularity; target.shadows = shadows; target.distanceDisplayCondition = distanceDisplayCondition; + target.classificationType = classificationType; target.zIndex = zIndex; target.merge(source); @@ -138,6 +148,7 @@ defineSuite([ expect(target.granularity).toBe(granularity); expect(target.shadows).toBe(shadows); expect(target.distanceDisplayCondition).toBe(distanceDisplayCondition); + expect(target.classificationType).toBe(classificationType); expect(target.zIndex).toBe(zIndex); }); @@ -153,6 +164,7 @@ defineSuite([ source.granularity = new ConstantProperty(); source.shadows = new ConstantProperty(); source.distanceDisplayCondition = new ConstantProperty(); + source.classificationType = new ConstantProperty(); source.zIndex = new ConstantProperty(); var result = source.clone(); @@ -166,6 +178,7 @@ defineSuite([ expect(result.granularity).toBe(source.granularity); expect(result.shadows).toBe(source.shadows); expect(result.distanceDisplayCondition).toBe(source.distanceDisplayCondition); + expect(result.classificationType).toBe(source.classificationType); expect(result.zIndex).toBe(source.zIndex); }); @@ -188,6 +201,7 @@ defineSuite([ testDefinitionChanged(property, 'granularity', 2, 1); testDefinitionChanged(property, 'shadows', ShadowMode.ENABLED, ShadowMode.DISABLED); testDefinitionChanged(property, 'distanceDisplayCondition', new DistanceDisplayCondition(), new DistanceDisplayCondition(10.0, 20.0)); + testDefinitionChanged(property, 'classificationType', ClassificationType.TERRAIN); testDefinitionChanged(property, 'zIndex', 20, 5); }); }); diff --git a/Specs/DataSources/PolylineVisualizerSpec.js b/Specs/DataSources/PolylineVisualizerSpec.js index 34722cf0a608..e288753d9002 100644 --- a/Specs/DataSources/PolylineVisualizerSpec.js +++ b/Specs/DataSources/PolylineVisualizerSpec.js @@ -16,6 +16,7 @@ defineSuite([ 'DataSources/EntityCollection', 'DataSources/PolylineArrowMaterialProperty', 'DataSources/PolylineGraphics', + 'Scene/ClassificationType', 'Scene/PolylineColorAppearance', 'Scene/PolylineMaterialAppearance', 'Scene/ShadowMode', @@ -40,6 +41,7 @@ defineSuite([ EntityCollection, PolylineArrowMaterialProperty, PolylineGraphics, + ClassificationType, PolylineColorAppearance, PolylineMaterialAppearance, ShadowMode, @@ -64,6 +66,24 @@ defineSuite([ ApproximateTerrainHeights._terrainHeights = undefined; }); + function visualizerUpdated(visualizer) { + return pollToPromise(function() { + scene.initializeFrame(); + var isUpdated = visualizer.update(time); + scene.render(time); + return isUpdated; + }); + } + + function visualizerEmpty(visualizer) { + return pollToPromise(function() { + scene.initializeFrame(); + expect(visualizer.update(time)).toBe(true); + scene.render(time); + return scene.primitives.length === 0 && scene.groundPrimitives.length === 0; + }); + } + it('Can create and destroy', function() { var objects = new EntityCollection(); var visualizer = new PolylineVisualizer(scene, objects); @@ -79,19 +99,14 @@ defineSuite([ var visualizer = new PolylineVisualizer(scene, objects); var polyline = new PolylineGraphics(); - polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)]); + polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)]); polyline.material = new ColorMaterialProperty(); var entity = new Entity(); entity.polyline = polyline; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -102,12 +117,7 @@ defineSuite([ objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.primitives.length === 0; - }).then(function(){ + return visualizerEmpty(visualizer).then(function(){ visualizer.destroy(); }); }); @@ -118,19 +128,14 @@ defineSuite([ var visualizer = new PolylineVisualizer(scene, objects); var polyline = new PolylineGraphics(); - polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)]); + polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)]); polyline.material = new PolylineArrowMaterialProperty(); var entity = new Entity(); entity.polyline = polyline; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -141,12 +146,7 @@ defineSuite([ objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.primitives.length === 0; - }).then(function(){ + return visualizerEmpty(visualizer).then(function(){ visualizer.destroy(); }); }); @@ -158,10 +158,10 @@ defineSuite([ } var objects = new EntityCollection(); - var visualizer = new PolylineVisualizer(scene, objects, scene.groundPrimitives); + var visualizer = new PolylineVisualizer(scene, objects); var polyline = new PolylineGraphics(); - polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)]); + polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)]); polyline.material = new ColorMaterialProperty(); polyline.clampToGround = new ConstantProperty(true); @@ -169,12 +169,7 @@ defineSuite([ entity.polyline = polyline; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.groundPrimitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -185,12 +180,7 @@ defineSuite([ objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.groundPrimitives.length === 0; - }).then(function(){ + return visualizerEmpty(visualizer).then(function(){ visualizer.destroy(); }); }); @@ -201,7 +191,7 @@ defineSuite([ var visualizer = new PolylineVisualizer(scene, objects); var polyline = new PolylineGraphics(); - polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)]); + polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)]); polyline.material = new ColorMaterialProperty(); polyline.shadows = new ConstantProperty(shadows); @@ -209,23 +199,13 @@ defineSuite([ entity.polyline = polyline; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); expect(primitive.shadows).toBe(shadows); objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.primitives.length === 0; - }).then(function(){ + return visualizerEmpty(visualizer).then(function(){ visualizer.destroy(); }); }); @@ -252,7 +232,7 @@ defineSuite([ var visualizer = new PolylineVisualizer(scene, objects); var polyline = new PolylineGraphics(); - polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)]); + polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)]); polyline.material = new ColorMaterialProperty(); polyline.depthFailMaterial = new ColorMaterialProperty(); @@ -261,12 +241,7 @@ defineSuite([ entity.polyline = polyline; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -278,12 +253,7 @@ defineSuite([ objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.primitives.length === 0; - }).then(function(){ + return visualizerEmpty(visualizer).then(function(){ visualizer.destroy(); }); }); @@ -294,7 +264,7 @@ defineSuite([ var visualizer = new PolylineVisualizer(scene, objects); var polyline = new PolylineGraphics(); - polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)]); + polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)]); polyline.material = new ColorMaterialProperty(); polyline.depthFailMaterial = new PolylineArrowMaterialProperty(); @@ -303,12 +273,7 @@ defineSuite([ entity.polyline = polyline; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -320,12 +285,7 @@ defineSuite([ objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.primitives.length === 0; - }).then(function(){ + return visualizerEmpty(visualizer).then(function(){ visualizer.destroy(); }); }); @@ -336,7 +296,7 @@ defineSuite([ var visualizer = new PolylineVisualizer(scene, objects); var polyline = new PolylineGraphics(); - polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)]); + polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)]); polyline.material = new PolylineArrowMaterialProperty(); polyline.depthFailMaterial = new PolylineArrowMaterialProperty(); @@ -345,12 +305,7 @@ defineSuite([ entity.polyline = polyline; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -362,12 +317,7 @@ defineSuite([ objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.primitives.length === 0; - }).then(function(){ + return visualizerEmpty(visualizer).then(function(){ visualizer.destroy(); }); }); @@ -378,7 +328,7 @@ defineSuite([ var visualizer = new PolylineVisualizer(scene, objects); var polyline = new PolylineGraphics(); - polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)]); + polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)]); polyline.material = new PolylineArrowMaterialProperty(); polyline.depthFailMaterial = new ColorMaterialProperty(); @@ -387,12 +337,7 @@ defineSuite([ entity.polyline = polyline; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -404,15 +349,52 @@ defineSuite([ objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.primitives.length === 0; - }).then(function(){ + return visualizerEmpty(visualizer).then(function(){ + visualizer.destroy(); + }); + }); + }); + + function createAndRemoveGeometryWithClassificationType(classificationType) { + if (!Entity.supportsPolylinesOnTerrain(scene)) { + return; + } + + var objects = new EntityCollection(); + var visualizer = new PolylineVisualizer(scene, objects); + + var polyline = new PolylineGraphics(); + polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)]); + polyline.material = new ColorMaterialProperty(); + polyline.classificationType = new ConstantProperty(classificationType); + polyline.clampToGround = true; + + var entity = new Entity(); + entity.polyline = polyline; + objects.add(entity); + + return visualizerUpdated(visualizer).then(function() { + var primitive = scene.groundPrimitives.get(0); + expect(primitive.classificationType).toBe(classificationType); + + objects.remove(entity); + + return visualizerEmpty(visualizer).then(function(){ visualizer.destroy(); }); }); + } + + it('Creates and removes geometry classifying terrain', function() { + return createAndRemoveGeometryWithClassificationType(ClassificationType.TERRAIN); + }); + + it('Creates and removes geometry classifying 3D Tiles', function() { + return createAndRemoveGeometryWithClassificationType(ClassificationType.CESIUM_3D_TILE); + }); + + it('Creates and removes geometry classifying both terrain and 3D Tiles', function() { + return createAndRemoveGeometryWithClassificationType(ClassificationType.BOTH); }); it('Correctly handles geometry changing batches', function() { @@ -420,19 +402,14 @@ defineSuite([ var visualizer = new PolylineVisualizer(scene, objects); var polyline = new PolylineGraphics(); - polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)]); + polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)]); polyline.material = new ColorMaterialProperty(); var entity = new Entity(); entity.polyline = polyline; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -442,12 +419,7 @@ defineSuite([ polyline.material = new PolylineArrowMaterialProperty(); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { primitive = scene.primitives.get(0); attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -473,7 +445,7 @@ defineSuite([ var polyline = new PolylineGraphics(); polyline.positions = new CallbackProperty(function() { - return [Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)]; + return [Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)]; }, false); polyline.material = new ColorMaterialProperty(); @@ -520,7 +492,7 @@ defineSuite([ var visualizer = new PolylineVisualizer(scene, entityCollection); var polyline = new PolylineGraphics(); - polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)]); + polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)]); polyline.material = new PolylineArrowMaterialProperty(); var entity = new Entity(); @@ -578,37 +550,26 @@ defineSuite([ var entity = new Entity({ id : 'test', polyline : { - positions: [Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)], + positions: [Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)], material: Color.ORANGE } }); objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { objects.remove(entity); var entity2 = new Entity({ id : 'test', position : Cartesian3.fromDegrees(0, 0, 0), polyline : { - positions: [Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)], + positions: [Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)], material : Color.BLUE } }); objects.add(entity2); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { - + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity2); expect(attributes).toBeDefined(); @@ -618,12 +579,7 @@ defineSuite([ objects.remove(entity); - return pollToPromise(function() { - scene.initializeFrame(); - expect(visualizer.update(time)).toBe(true); - scene.render(time); - return scene.primitives.length === 0; - }).then(function() { + return visualizerEmpty(visualizer).then(function() { visualizer.destroy(); }); }); @@ -636,17 +592,12 @@ defineSuite([ var entity = entities.add({ polyline : { - positions: [Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)], + positions: [Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)], material : new ColorMaterialProperty(createDynamicProperty(Color.BLUE)) } }); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -654,12 +605,7 @@ defineSuite([ entity.show = false; - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }); + return visualizerUpdated(visualizer); }).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); @@ -678,17 +624,12 @@ defineSuite([ var entity = entities.add({ position : new Cartesian3(1234, 5678, 9101112), polyline : { - positions: [Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)], + positions: [Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)], material : new PolylineArrowMaterialProperty(createDynamicProperty(Color.BLUE)) } }); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -696,12 +637,7 @@ defineSuite([ entity.show = false; - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }); + return visualizerUpdated(visualizer); }).then(function() { var primitive = scene.primitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); @@ -719,10 +655,10 @@ defineSuite([ } var objects = new EntityCollection(); - var visualizer = new PolylineVisualizer(scene, objects, scene.groundPrimitives); + var visualizer = new PolylineVisualizer(scene, objects); var polyline = new PolylineGraphics(); - polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 1.0)]); + polyline.positions = new ConstantProperty([Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)]); polyline.material = new ColorMaterialProperty(); polyline.clampToGround = new ConstantProperty(true); @@ -730,12 +666,7 @@ defineSuite([ entity.polyline = polyline; objects.add(entity); - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }).then(function() { + return visualizerUpdated(visualizer).then(function() { var primitive = scene.groundPrimitives.get(0); var attributes = primitive.getGeometryInstanceAttributes(entity); expect(attributes).toBeDefined(); @@ -746,12 +677,7 @@ defineSuite([ entity.polyline.show = false; - return pollToPromise(function() { - scene.initializeFrame(); - var isUpdated = visualizer.update(time); - scene.render(time); - return isUpdated; - }); + return visualizerUpdated(visualizer); }).then(function() { expect(scene.primitives.length).toEqual(0); @@ -759,4 +685,85 @@ defineSuite([ visualizer.destroy(); }); }); + + it('batches ground poylines by material if ground polylines are supported', function() { + if (!Entity.supportsPolylinesOnTerrain(scene)) { + return; + } + + var entities = new EntityCollection(); + var visualizer = new PolylineVisualizer(scene, entities); + + var blueColor = Color.BLUE.withAlpha(0.5); + var redColor = Color.RED.withAlpha(0.5); + var positions = [Cartesian3.fromDegrees(0.0, 0.0), Cartesian3.fromDegrees(0.0, 0.000001)]; + entities.add({ + polyline : { + positions : positions, + material : blueColor, + classificationType : ClassificationType.TERRAIN, + clampToGround : true + } + }); + + return visualizerUpdated(visualizer).then(function() { + expect(scene.groundPrimitives.length).toEqual(1); + + entities.add({ + polyline : { + positions : positions, + material : blueColor, + classificationType : ClassificationType.TERRAIN, + clampToGround : true + } + }); + + return visualizerUpdated(visualizer); + }).then(function() { + expect(scene.groundPrimitives.length).toEqual(1); + + entities.add({ + polyline : { + positions : positions, + material : redColor, + classificationType : ClassificationType.TERRAIN, + clampToGround : true + } + }); + + return visualizerUpdated(visualizer); + }).then(function() { + expect(scene.groundPrimitives.length).toEqual(1); + + entities.add({ + polyline : { + positions : positions, + material : new PolylineArrowMaterialProperty(), + classificationType : ClassificationType.TERRAIN, + clampToGround : true + } + }); + + return visualizerUpdated(visualizer); + }).then(function() { + expect(scene.groundPrimitives.length).toEqual(2); + + entities.add({ + polyline : { + positions : positions, + material : new PolylineArrowMaterialProperty(), + classificationType : ClassificationType.CESIUM_3D_TILE, + clampToGround : true + } + }); + + return visualizerUpdated(visualizer); + }).then(function() { + expect(scene.groundPrimitives.length).toEqual(3); + + entities.removeAll(); + visualizer.destroy(); + }); + }); + }, 'WebGL'); diff --git a/Specs/DataSources/StaticGroundPolylinePerMaterialBatchSpec.js b/Specs/DataSources/StaticGroundPolylinePerMaterialBatchSpec.js index 6fbd74d96407..14bff2aae491 100644 --- a/Specs/DataSources/StaticGroundPolylinePerMaterialBatchSpec.js +++ b/Specs/DataSources/StaticGroundPolylinePerMaterialBatchSpec.js @@ -18,6 +18,7 @@ defineSuite([ 'DataSources/PolylineGeometryUpdater', 'DataSources/PolylineGraphics', 'DataSources/TimeIntervalCollectionProperty', + 'Scene/ClassificationType', 'Scene/GroundPolylinePrimitive', 'Specs/createScene', 'Specs/pollToPromise' @@ -41,6 +42,7 @@ defineSuite([ PolylineGeometryUpdater, PolylineGraphics, TimeIntervalCollectionProperty, + ClassificationType, GroundPolylinePrimitive, createScene, pollToPromise) { @@ -90,7 +92,7 @@ defineSuite([ return; } - batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, false); + batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, ClassificationType.BOTH, false); var polyline1 = createGroundPolyline(); polyline1.material = new PolylineOutlineMaterialProperty(); @@ -151,7 +153,7 @@ defineSuite([ polyline: polyline }); - batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, false); + batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, ClassificationType.BOTH, false); var updater = new PolylineGeometryUpdater(entity, scene); batch.add(validTime, updater); @@ -197,7 +199,7 @@ defineSuite([ polyline: polyline }); - batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, false); + batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, ClassificationType.BOTH, false); var updater = new PolylineGeometryUpdater(entity, scene); batch.add(validTime, updater); @@ -230,7 +232,7 @@ defineSuite([ return; } - batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, false); + batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, ClassificationType.BOTH, false); function buildEntity() { var polyline = createGroundPolyline(); @@ -299,7 +301,7 @@ defineSuite([ return; } - batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, false); + batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, ClassificationType.BOTH, false); var polyline1 = createGroundPolyline(); polyline1.material = Color.RED; var entity = new Entity({ @@ -335,7 +337,7 @@ defineSuite([ return; } - batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, false); + batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, ClassificationType.BOTH, false); var polyline1 = createGroundPolyline(); polyline1.material = new PolylineOutlineMaterialProperty(); @@ -376,7 +378,7 @@ defineSuite([ return; } - batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, false); + batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, ClassificationType.BOTH, false); var polyline1 = createGroundPolyline(); polyline1.material = new PolylineOutlineMaterialProperty(); @@ -417,7 +419,7 @@ defineSuite([ } var resultSphere = new BoundingSphere(); - batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, false); + batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, ClassificationType.BOTH, false); var polyline1 = createGroundPolyline(); polyline1.material = new PolylineOutlineMaterialProperty(); @@ -457,7 +459,7 @@ defineSuite([ // Don't fail if GroundPolylinePrimitive is not supported return; } - batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, false); + batch = new StaticGroundPolylinePerMaterialBatch(scene.groundPrimitives, ClassificationType.BOTH, false); function buildEntity() { var polyline = createGroundPolyline();