diff --git a/CHANGES.md b/CHANGES.md index d56a8aa4fcb4..95d07f133d0d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,6 +19,7 @@ Change Log * `GeoJsonDataSource` now supports polygons with holes. * `ConstantProperty` can now hold any value; previously it was limited to values that implemented `equals` and `clones` functions, as well as a few special cases. * Fixed a bug in `EllipsoidGeodesic` that caused it to modify the `height` of the positions passed to the constructor or to to `setEndPoints`. +* Instead of throwing an exception when there are not enough unique positions to define a geometry, creating a `Primitive` will succeed, but not render. [#2375](https://github.com/AnalyticalGraphicsInc/cesium/issues/2375) ### 1.5 - 2015-01-05 diff --git a/Source/Core/CorridorGeometry.js b/Source/Core/CorridorGeometry.js index 184e2bdc167b..8bf439e34e06 100644 --- a/Source/Core/CorridorGeometry.js +++ b/Source/Core/CorridorGeometry.js @@ -794,9 +794,7 @@ define([ * Computes the geometric representation of a corridor, including its vertices, indices, and a bounding sphere. * * @param {CorridorGeometry} corridorGeometry A description of the corridor. - * @returns {Geometry} The computed vertices and indices. - * - * @exception {DeveloperError} Count of unique positions must be greater than 1. + * @returns {Geometry|undefined} The computed vertices and indices. */ CorridorGeometry.createGeometry = function(corridorGeometry) { var positions = corridorGeometry._positions; @@ -809,11 +807,9 @@ define([ cleanPositions = positions; } - //>>includeStart('debug', pragmas.debug); if (cleanPositions.length < 2) { - throw new DeveloperError('Count of unique positions must be greater than 1.'); + return undefined; } - //>>includeEnd('debug'); var ellipsoid = corridorGeometry._ellipsoid; var vertexFormat = corridorGeometry._vertexFormat; diff --git a/Source/Core/CorridorOutlineGeometry.js b/Source/Core/CorridorOutlineGeometry.js index 851175437a9c..579cb3a30561 100644 --- a/Source/Core/CorridorOutlineGeometry.js +++ b/Source/Core/CorridorOutlineGeometry.js @@ -461,9 +461,7 @@ define([ * Computes the geometric representation of a corridor, including its vertices, indices, and a bounding sphere. * * @param {CorridorOutlineGeometry} corridorOutlineGeometry A description of the corridor. - * @returns {Geometry} The computed vertices and indices. - * - * @exception {DeveloperError} Count of unique positions must be greater than 1. + * @returns {Geometry|undefined} The computed vertices and indices. */ CorridorOutlineGeometry.createGeometry = function(corridorOutlineGeometry) { var positions = corridorOutlineGeometry._positions; @@ -476,11 +474,9 @@ define([ cleanPositions = positions; } - //>>includeStart('debug', pragmas.debug); if (cleanPositions.length < 2) { - throw new DeveloperError('Count of unique positions must be greater than 1.'); + return undefined; } - //>>includeEnd('debug'); var ellipsoid = corridorOutlineGeometry._ellipsoid; var params = { diff --git a/Source/Core/PolygonGeometry.js b/Source/Core/PolygonGeometry.js index e57f3c5b523f..e048732a9f2f 100644 --- a/Source/Core/PolygonGeometry.js +++ b/Source/Core/PolygonGeometry.js @@ -806,10 +806,7 @@ define([ * Computes the geometric representation of a polygon, including its vertices, indices, and a bounding sphere. * * @param {PolygonGeometry} polygonGeometry A description of the polygon. - * @returns {Geometry} The computed vertices and indices. - * - * @exception {DeveloperError} At least three positions are required. - * @exception {DeveloperError} Duplicate positions result in not enough positions to form a polygon. + * @returns {Geometry|undefined} The computed vertices and indices. */ PolygonGeometry.createGeometry = function(polygonGeometry) { var vertexFormat = polygonGeometry._vertexFormat; @@ -839,44 +836,40 @@ define([ var holes = outerNode.holes; outerRing = PolygonPipeline.removeDuplicates(outerRing); if (outerRing.length < 3) { - throw new DeveloperError('At least three positions are required.'); + continue; } - var numChildren = holes ? holes.length : 0; - if (numChildren === 0) { - // The outer polygon is a simple polygon with no nested inner polygon. - polygonHierarchy.push({ - outerRing : outerRing, - holes : [] - }); - polygons.push(outerRing); - } else { - // The outer polygon contains inner polygons - var polygonHoles = []; - for (i = 0; i < numChildren; i++) { - var hole = holes[i]; - hole.positions = PolygonPipeline.removeDuplicates(hole.positions); - if (hole.positions.length < 3) { - throw new DeveloperError('At least three positions are required.'); - } - polygonHoles.push(hole.positions); + var numChildren = defined(holes) ? holes.length : 0; + var polygonHoles = []; + for (i = 0; i < numChildren; i++) { + var hole = holes[i]; + hole.positions = PolygonPipeline.removeDuplicates(hole.positions); + if (hole.positions.length < 3) { + continue; + } + polygonHoles.push(hole.positions); - var numGrandchildren = 0; - if (defined(hole.holes)) { - numGrandchildren = hole.holes.length; - } + var numGrandchildren = 0; + if (defined(hole.holes)) { + numGrandchildren = hole.holes.length; + } - for ( var j = 0; j < numGrandchildren; j++) { - queue.enqueue(hole.holes[j]); - } + for ( var j = 0; j < numGrandchildren; j++) { + queue.enqueue(hole.holes[j]); } - polygonHierarchy.push({ - outerRing : outerRing, - holes : polygonHoles - }); - var combinedPolygon = PolygonPipeline.eliminateHoles(outerRing, polygonHoles); - polygons.push(combinedPolygon); } + + polygonHierarchy.push({ + outerRing : outerRing, + holes : polygonHoles + }); + + var combinedPolygon = polygonHoles.length > 0 ? PolygonPipeline.eliminateHoles(outerRing, polygonHoles) : outerRing; + polygons.push(combinedPolygon); + } + + if (polygons.length === 0) { + return undefined; } outerPositions = polygons[0]; diff --git a/Source/Core/PolygonOutlineGeometry.js b/Source/Core/PolygonOutlineGeometry.js index d7ae8bf92bc4..cc27d600ff38 100644 --- a/Source/Core/PolygonOutlineGeometry.js +++ b/Source/Core/PolygonOutlineGeometry.js @@ -44,37 +44,29 @@ define([ var createGeometryFromPositionsSubdivided = []; function createGeometryFromPositions(ellipsoid, positions, minDistance, perPositionHeight) { - var cleanedPositions = PolygonPipeline.removeDuplicates(positions); - - //>>includeStart('debug', pragmas.debug); - if (cleanedPositions.length < 3) { - throw new DeveloperError('Duplicate positions result in not enough positions to form a polygon.'); - } - //>>includeEnd('debug'); - - var tangentPlane = EllipsoidTangentPlane.fromPoints(cleanedPositions, ellipsoid); - var positions2D = tangentPlane.projectPointsOntoPlane(cleanedPositions, createGeometryFromPositionsPositions); + var tangentPlane = EllipsoidTangentPlane.fromPoints(positions, ellipsoid); + var positions2D = tangentPlane.projectPointsOntoPlane(positions, createGeometryFromPositionsPositions); var originalWindingOrder = PolygonPipeline.computeWindingOrder2D(positions2D); if (originalWindingOrder === WindingOrder.CLOCKWISE) { positions2D.reverse(); - cleanedPositions.reverse(); + positions.reverse(); } var subdividedPositions; var i; - var length = cleanedPositions.length; + var length = positions.length; var index = 0; if (!perPositionHeight) { var numVertices = 0; for (i = 0; i < length; i++) { - numVertices += PolygonGeometryLibrary.subdivideLineCount(cleanedPositions[i], cleanedPositions[(i + 1) % length], minDistance); + numVertices += PolygonGeometryLibrary.subdivideLineCount(positions[i], positions[(i + 1) % length], minDistance); } subdividedPositions = new Float64Array(numVertices * 3); for (i = 0; i < length; i++) { - var tempPositions = PolygonGeometryLibrary.subdivideLine(cleanedPositions[i], cleanedPositions[(i + 1) % length], minDistance, createGeometryFromPositionsSubdivided); + var tempPositions = PolygonGeometryLibrary.subdivideLine(positions[i], positions[(i + 1) % length], minDistance, createGeometryFromPositionsSubdivided); var tempPositionsLength = tempPositions.length; for (var j = 0; j < tempPositionsLength; ++j) { subdividedPositions[index++] = tempPositions[j]; @@ -83,8 +75,8 @@ define([ } else { subdividedPositions = new Float64Array(length * 2 * 3); for (i = 0; i < length; i++) { - var p0 = cleanedPositions[i]; - var p1 = cleanedPositions[(i + 1) % length]; + var p0 = positions[i]; + var p1 = positions[(i + 1) % length]; subdividedPositions[index++] = p0.x; subdividedPositions[index++] = p0.y; subdividedPositions[index++] = p0.z; @@ -121,40 +113,32 @@ define([ } function createGeometryFromPositionsExtruded(ellipsoid, positions, minDistance, perPositionHeight) { - var cleanedPositions = PolygonPipeline.removeDuplicates(positions); - - //>>includeStart('debug', pragmas.debug); - if (cleanedPositions.length < 3) { - throw new DeveloperError('Duplicate positions result in not enough positions to form a polygon.'); - } - //>>includeEnd('debug'); - - var tangentPlane = EllipsoidTangentPlane.fromPoints(cleanedPositions, ellipsoid); - var positions2D = tangentPlane.projectPointsOntoPlane(cleanedPositions, createGeometryFromPositionsPositions); + var tangentPlane = EllipsoidTangentPlane.fromPoints(positions, ellipsoid); + var positions2D = tangentPlane.projectPointsOntoPlane(positions, createGeometryFromPositionsPositions); var originalWindingOrder = PolygonPipeline.computeWindingOrder2D(positions2D); if (originalWindingOrder === WindingOrder.CLOCKWISE) { positions2D.reverse(); - cleanedPositions.reverse(); + positions.reverse(); } var subdividedPositions; var i; - var length = cleanedPositions.length; + var length = positions.length; var corners = new Array(length); var index = 0; if (!perPositionHeight) { var numVertices = 0; for (i = 0; i < length; i++) { - numVertices += PolygonGeometryLibrary.subdivideLineCount(cleanedPositions[i], cleanedPositions[(i + 1) % length], minDistance); + numVertices += PolygonGeometryLibrary.subdivideLineCount(positions[i], positions[(i + 1) % length], minDistance); } subdividedPositions = new Float64Array(numVertices * 3 * 2); for (i = 0; i < length; ++i) { corners[i] = index / 3; - var tempPositions = PolygonGeometryLibrary.subdivideLine(cleanedPositions[i], cleanedPositions[(i + 1) % length], minDistance, createGeometryFromPositionsSubdivided); + var tempPositions = PolygonGeometryLibrary.subdivideLine(positions[i], positions[(i + 1) % length], minDistance, createGeometryFromPositionsSubdivided); var tempPositionsLength = tempPositions.length; for (var j = 0; j < tempPositionsLength; ++j) { subdividedPositions[index++] = tempPositions[j]; @@ -164,8 +148,8 @@ define([ subdividedPositions = new Float64Array(length * 2 * 3 * 2); for (i = 0; i < length; ++i) { corners[i] = index / 3; - var p0 = cleanedPositions[i]; - var p1 = cleanedPositions[(i + 1) % length]; + var p0 = positions[i]; + var p1 = positions[(i + 1) % length]; subdividedPositions[index++] = p0.x; subdividedPositions[index++] = p0.y; @@ -479,10 +463,7 @@ define([ * Computes the geometric representation of a polygon outline, including its vertices, indices, and a bounding sphere. * * @param {PolygonOutlineGeometry} polygonGeometry A description of the polygon outline. - * @returns {Geometry} The computed vertices and indices. - * - * @exception {DeveloperError} At least three positions are required. - * @exception {DeveloperError} Duplicate positions result in not enough positions to form a polygon. + * @returns {Geometry|undefined} The computed vertices and indices. */ PolygonOutlineGeometry.createGeometry = function(polygonGeometry) { var ellipsoid = polygonGeometry._ellipsoid; @@ -502,15 +483,19 @@ define([ while (queue.length !== 0) { var outerNode = queue.dequeue(); var outerRing = outerNode.positions; - + outerRing = PolygonPipeline.removeDuplicates(outerRing); if (outerRing.length < 3) { - throw new DeveloperError('At least three positions are required.'); + continue; } var numChildren = outerNode.holes ? outerNode.holes.length : 0; // The outer polygon contains inner polygons for (i = 0; i < numChildren; i++) { var hole = outerNode.holes[i]; + hole.positions = PolygonPipeline.removeDuplicates(hole.positions); + if (hole.positions.length < 3) { + continue; + } polygons.push(hole.positions); var numGrandchildren = 0; @@ -526,6 +511,10 @@ define([ polygons.push(outerRing); } + if (polygons.length === 0) { + return undefined; + } + var geometry; var geometries = []; var minDistance = CesiumMath.chordLength(granularity, ellipsoid.maximumRadius); diff --git a/Source/Core/PolylineGeometry.js b/Source/Core/PolylineGeometry.js index 026ee480ab76..8dfebf97286a 100644 --- a/Source/Core/PolylineGeometry.js +++ b/Source/Core/PolylineGeometry.js @@ -286,10 +286,7 @@ define([ * Computes the geometric representation of a polyline, including its vertices, indices, and a bounding sphere. * * @param {PolylineGeometry} polylineGeometry A description of the polyline. - * @returns {Geometry} The computed vertices and indices. - * - * @exception {DeveloperError} At least two unique positions are required. - * + * @returns {Geometry|undefined} The computed vertices and indices. */ PolylineGeometry.createGeometry = function(polylineGeometry) { var width = polylineGeometry._width; @@ -310,13 +307,11 @@ define([ if (!defined(positions)) { positions = polylineGeometry._positions; } - var positionsLength = positions.length; - //>>includeStart('debug', pragmas.debug); + var positionsLength = positions.length; if (positionsLength < 2) { - throw new DeveloperError('At least two unique positions are required.'); + return undefined; } - //>>includeEnd('debug'); if (followSurface) { var heights = PolylinePipeline.extractHeights(positions, ellipsoid); diff --git a/Source/Core/PolylineVolumeGeometry.js b/Source/Core/PolylineVolumeGeometry.js index e17a26928f34..1867466fb4ae 100644 --- a/Source/Core/PolylineVolumeGeometry.js +++ b/Source/Core/PolylineVolumeGeometry.js @@ -369,10 +369,7 @@ define([ * Computes the geometric representation of a polyline with a volume, including its vertices, indices, and a bounding sphere. * * @param {PolylineVolumeGeometry} polylineVolumeGeometry A description of the polyline volume. - * @returns {Geometry} The computed vertices and indices. - * - * @exception {DeveloperError} Count of unique polyline positions must be greater than 1. - * @exception {DeveloperError} Count of unique shape positions must be at least 3. + * @returns {Geometry|undefined} The computed vertices and indices. */ PolylineVolumeGeometry.createGeometry = function(polylineVolumeGeometry) { var positions = polylineVolumeGeometry._positions; @@ -380,14 +377,9 @@ define([ var shape2D = polylineVolumeGeometry._shape; shape2D = PolylineVolumeGeometryLibrary.removeDuplicatesFromShape(shape2D); - //>>includeStart('debug', pragmas.debug); - if (cleanPositions.length < 2) { - throw new DeveloperError('Count of unique polyline positions must be greater than 1.'); + if (cleanPositions.length < 2 || shape2D.length < 3) { + return undefined; } - if (shape2D.length < 3) { - throw new DeveloperError('Count of unique shape positions must be at least 3.'); - } - //>>includeEnd('debug'); if (PolygonPipeline.computeWindingOrder2D(shape2D) === WindingOrder.CLOCKWISE) { shape2D.reverse(); diff --git a/Source/Core/PolylineVolumeOutlineGeometry.js b/Source/Core/PolylineVolumeOutlineGeometry.js index fa1a0226377e..25b4eed8253e 100644 --- a/Source/Core/PolylineVolumeOutlineGeometry.js +++ b/Source/Core/PolylineVolumeOutlineGeometry.js @@ -275,10 +275,7 @@ define([ * Computes the geometric representation of the outline of a polyline with a volume, including its vertices, indices, and a bounding sphere. * * @param {PolylineVolumeOutlineGeometry} polylineVolumeOutlineGeometry A description of the polyline volume outline. - * @returns {Geometry} The computed vertices and indices. - * - * @exception {DeveloperError} Count of unique polyline positions must be greater than 1. - * @exception {DeveloperError} Count of unique shape positions must be at least 3. + * @returns {Geometry|undefined} The computed vertices and indices. */ PolylineVolumeOutlineGeometry.createGeometry = function(polylineVolumeOutlineGeometry) { var positions = polylineVolumeOutlineGeometry._positions; @@ -286,14 +283,9 @@ define([ var shape2D = polylineVolumeOutlineGeometry._shape; shape2D = PolylineVolumeGeometryLibrary.removeDuplicatesFromShape(shape2D); - //>>includeStart('debug', pragmas.debug); - if (cleanPositions.length < 2) { - throw new DeveloperError('Count of unique polyline positions must be greater than 1.'); + if (cleanPositions.length < 2 || shape2D.length < 3) { + return undefined; } - if (shape2D.length < 3) { - throw new DeveloperError('Count of unique shape positions must be at least 3.'); - } - //>>includeEnd('debug'); if (PolygonPipeline.computeWindingOrder2D(shape2D) === WindingOrder.CLOCKWISE) { shape2D.reverse(); diff --git a/Source/Core/WallGeometry.js b/Source/Core/WallGeometry.js index 79bdf9a77925..88d7faab55e9 100644 --- a/Source/Core/WallGeometry.js +++ b/Source/Core/WallGeometry.js @@ -59,6 +59,7 @@ define([ * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for coordinate manipulation * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed. * + * @exception {DeveloperError} positions length must be greater than or equal to 2. * @exception {DeveloperError} positions and maximumHeights must have the same length. * @exception {DeveloperError} positions and minimumHeights must have the same length. * @@ -91,6 +92,9 @@ define([ if (!defined(wallPositions)) { throw new DeveloperError('options.positions is required.'); } + if (wallPositions.length < 2) { + throw new DeveloperError('options.positions length must be greater than or equal to 2.'); + } if (defined(maximumHeights) && maximumHeights.length !== wallPositions.length) { throw new DeveloperError('options.positions and options.maximumHeights must have the same length.'); } @@ -344,9 +348,7 @@ define([ * Computes the geometric representation of a wall, including its vertices, indices, and a bounding sphere. * * @param {WallGeometry} wallGeometry A description of the wall. - * @returns {Geometry} The computed vertices and indices. - * - * @exception {DeveloperError} unique positions must be greater than or equal to 2. + * @returns {Geometry|undefined} The computed vertices and indices. */ WallGeometry.createGeometry = function(wallGeometry) { var wallPositions = wallGeometry._positions; @@ -357,6 +359,10 @@ define([ var ellipsoid = wallGeometry._ellipsoid; var pos = WallGeometryLibrary.computePositions(ellipsoid, wallPositions, maximumHeights, minimumHeights, granularity, true); + if (!defined(pos)) { + return undefined; + } + var bottomPositions = pos.bottomPositions; var topPositions = pos.topPositions; diff --git a/Source/Core/WallGeometryLibrary.js b/Source/Core/WallGeometryLibrary.js index e98408ded1bf..12b09ffac4a6 100644 --- a/Source/Core/WallGeometryLibrary.js +++ b/Source/Core/WallGeometryLibrary.js @@ -114,11 +114,9 @@ define([ maximumHeights = o.topHeights; minimumHeights = o.bottomHeights; - //>>includeStart('debug', pragmas.debug); if (wallPositions.length < 2) { - throw new DeveloperError('unique positions must be greater than or equal to 2'); + return undefined; } - //>>includeEnd('debug'); if (wallPositions.length >= 3) { // Order positions counter-clockwise diff --git a/Source/Core/WallOutlineGeometry.js b/Source/Core/WallOutlineGeometry.js index 4ebc9e0a6df4..af9f26da28e5 100644 --- a/Source/Core/WallOutlineGeometry.js +++ b/Source/Core/WallOutlineGeometry.js @@ -50,6 +50,7 @@ define([ * wall at positions. If undefined, the height at each position is 0.0. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid for coordinate manipulation * + * @exception {DeveloperError} positions length must be greater than or equal to 2. * @exception {DeveloperError} positions and maximumHeights must have the same length. * @exception {DeveloperError} positions and minimumHeights must have the same length. * @@ -82,6 +83,9 @@ define([ if (!defined(wallPositions)) { throw new DeveloperError('options.positions is required.'); } + if (wallPositions.length < 2) { + throw new DeveloperError('options.positions length must be greater than or equal to 2.'); + } if (defined(maximumHeights) && maximumHeights.length !== wallPositions.length) { throw new DeveloperError('options.positions and options.maximumHeights must have the same length.'); } @@ -322,9 +326,7 @@ define([ * Computes the geometric representation of a wall outline, including its vertices, indices, and a bounding sphere. * * @param {WallOutlineGeometry} wallGeometry A description of the wall outline. - * @returns {Geometry} The computed vertices and indices. - * - * @exception {DeveloperError} unique positions must be greater than or equal to 2. + * @returns {Geometry|undefined} The computed vertices and indices. */ WallOutlineGeometry.createGeometry = function(wallGeometry) { var wallPositions = wallGeometry._positions; @@ -334,6 +336,10 @@ define([ var ellipsoid = wallGeometry._ellipsoid; var pos = WallGeometryLibrary.computePositions(ellipsoid, wallPositions, maximumHeights, minimumHeights, granularity, false); + if (!defined(pos)) { + return undefined; + } + var bottomPositions = pos.bottomPositions; var topPositions = pos.topPositions; diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index aaa2b30b12e6..96fbbbbee4a7 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -404,7 +404,7 @@ define([ */ ready : { get : function() { - return this._state === PrimitiveState.COMPLETE; + return this._state === PrimitiveState.COMPLETE || this._state === PrimitiveState.FAILED; } } }); @@ -462,7 +462,9 @@ define([ return new GeometryInstance({ geometry : geometry, modelMatrix : Matrix4.clone(instance.modelMatrix), - attributes : newAttributes + attributes : newAttributes, + pickPrimitive : instance.pickPrimitive, + id : instance.id }); } @@ -699,6 +701,14 @@ define([ return; } + if (defined(this._error)) { + throw this._error; + } + + if (this._state === PrimitiveState.FAILED) { + return; + } + var projection = frameState.mapProjection; var colorCommand; var pickCommand; @@ -710,6 +720,7 @@ define([ var j; var index; var promise; + var instance; var instances; var clonedInstances; var geometries; @@ -720,9 +731,7 @@ define([ if (this._state !== PrimitiveState.COMPLETE && this._state !== PrimitiveState.COMBINED) { if (this.asynchronous) { - if (this._state === PrimitiveState.FAILED) { - throw this._error; - } else if (this._state === PrimitiveState.READY) { + if (this._state === PrimitiveState.READY) { instances = (isArray(this.geometryInstances)) ? this.geometryInstances : [this.geometryInstances]; this._numberOfInstances = length = instances.length; @@ -817,9 +826,27 @@ define([ that._attributeLocations = result.attributeLocations; that._vaAttributes = result.vaAttributes; that._perInstanceAttributeLocations = result.perInstanceAttributeLocations; - that._state = PrimitiveState.COMBINED; that.modelMatrix = Matrix4.clone(result.modelMatrix, that.modelMatrix); that._validModelMatrix = !Matrix4.equals(that.modelMatrix, Matrix4.IDENTITY); + + var validInstancesIndices = packedResult.validInstancesIndices; + var invalidInstancesIndices = packedResult.invalidInstancesIndices; + var instanceIds = that._instanceIds; + var reorderedInstanceIds = new Array(instanceIds.length); + + var validLength = validInstancesIndices.length; + for (var i = 0; i < validLength; ++i) { + reorderedInstanceIds[i] = instanceIds[validInstancesIndices[i]]; + } + + var invalidLength = invalidInstancesIndices.length; + for (var j = 0; j < invalidLength; ++j) { + reorderedInstanceIds[validLength + j] = instanceIds[invalidInstancesIndices[j]]; + } + + that._instanceIds = reorderedInstanceIds; + + that._state = defined(that._geometries) ? PrimitiveState.COMBINED : PrimitiveState.FAILED; }, function(error) { that._error = error; that._state = PrimitiveState.FAILED; @@ -828,13 +855,16 @@ define([ } else { instances = (isArray(this.geometryInstances)) ? this.geometryInstances : [this.geometryInstances]; this._numberOfInstances = length = instances.length; + geometries = new Array(length); - clonedInstances = new Array(instances.length); + clonedInstances = new Array(length); + + var invalidInstances = []; + var geometryIndex = 0; for (i = 0; i < length; i++) { - var instance = instances[i]; + instance = instances[i]; geometry = instance.geometry; - instanceIds.push(instance.id); var createdGeometry; if (defined(geometry.attributes) && defined(geometry.primitiveType)) { @@ -842,13 +872,23 @@ define([ } else { createdGeometry = geometry.constructor.createGeometry(geometry); } - geometries[i] = createdGeometry; - clonedInstances[i] = cloneInstance(instance, createdGeometry); + + if (defined(createdGeometry)) { + geometries[geometryIndex] = createdGeometry; + clonedInstances[geometryIndex++] = cloneInstance(instance, createdGeometry); + instanceIds.push(instance.id); + } else { + invalidInstances.push(instance); + } } + geometries.length = geometryIndex; + clonedInstances.length = geometryIndex; + var result = PrimitivePipeline.combineGeometry({ instances : clonedInstances, - pickIds : allowPicking ? createPickIds(context, this, instances) : undefined, + invalidInstances : invalidInstances, + pickIds : allowPicking ? createPickIds(context, this, clonedInstances) : undefined, ellipsoid : projection.ellipsoid, projection : projection, elementIndexUintSupported : context.elementIndexUint, @@ -863,9 +903,15 @@ define([ this._attributeLocations = result.attributeLocations; this._vaAttributes = result.vaAttributes; this._perInstanceAttributeLocations = result.vaAttributeLocations; - this._state = PrimitiveState.COMBINED; this.modelMatrix = Matrix4.clone(result.modelMatrix, this.modelMatrix); this._validModelMatrix = !Matrix4.equals(this.modelMatrix, Matrix4.IDENTITY); + + for (i = 0; i < invalidInstances.length; ++i) { + instance = invalidInstances[i]; + instanceIds.push(instance.id); + } + + this._state = defined(this._geometries) ? PrimitiveState.COMBINED : PrimitiveState.FAILED; } } @@ -1216,7 +1262,7 @@ define([ var attribute = perInstanceAttributes[name]; attribute.value = value; - if (!attribute.dirty) { + if (!attribute.dirty && attribute.valid) { dirtyList.push(attribute); attribute.dirty = true; } diff --git a/Source/Scene/PrimitivePipeline.js b/Source/Scene/PrimitivePipeline.js index deb3e0381a47..065a04fe9658 100644 --- a/Source/Scene/PrimitivePipeline.js +++ b/Source/Scene/PrimitivePipeline.js @@ -355,6 +355,7 @@ define([ if (!defined(indices[instanceIndex][name])) { indices[instanceIndex][name] = { dirty : false, + valid : true, value : instanceAttributes[name].value, indices : [] }; @@ -388,7 +389,7 @@ define([ } } - function computePerInstanceAttributeLocations(instances, vertexArrays, attributeLocations, names) { + function computePerInstanceAttributeLocations(instances, invalidInstances, vertexArrays, attributeLocations, names) { var indices = []; var length = instances.length; @@ -423,6 +424,26 @@ define([ } } + length = invalidInstances.length; + for (i = 0; i < length; ++i) { + instance = invalidInstances[i]; + attributes = instance.attributes; + + var instanceAttributes = {}; + indices.push(instanceAttributes); + + var namesLength = names.length; + for (var j = 0; j < namesLength; ++j) { + var name = names[j]; + instanceAttributes[name] = { + dirty : false, + valid : false, + value : attributes[name].value, + indices : [] + }; + } + } + return indices; } @@ -435,27 +456,40 @@ define([ * @private */ PrimitivePipeline.combineGeometry = function(parameters) { - var geometries = geometryPipeline(parameters); - var attributeLocations = GeometryPipeline.createAttributeLocations(geometries[0]); + var geometries; + var attributeLocations; + var perInstanceAttributes; + var perInstanceAttributeNames; + var length; var instances = parameters.instances; - var perInstanceAttributeNames = getCommonPerInstanceAttributeNames(instances); + var invalidInstances = parameters.invalidInstances; - var perInstanceAttributes = []; - var length = geometries.length; - for (var i = 0; i < length; ++i) { - var geometry = geometries[i]; - perInstanceAttributes.push(createPerInstanceVAAttributes(geometry, attributeLocations, perInstanceAttributeNames)); + if (instances.length > 0) { + geometries = geometryPipeline(parameters); + attributeLocations = GeometryPipeline.createAttributeLocations(geometries[0]); + + perInstanceAttributeNames = getCommonPerInstanceAttributeNames(instances); + + perInstanceAttributes = []; + length = geometries.length; + for (var i = 0; i < length; ++i) { + var geometry = geometries[i]; + perInstanceAttributes.push(createPerInstanceVAAttributes(geometry, attributeLocations, perInstanceAttributeNames)); + } } - var indices = computePerInstanceAttributeLocations(instances, perInstanceAttributes, attributeLocations, perInstanceAttributeNames); + perInstanceAttributeNames = defined(perInstanceAttributeNames) ? perInstanceAttributeNames : getCommonPerInstanceAttributeNames(invalidInstances); + var indices = computePerInstanceAttributeLocations(instances, invalidInstances, perInstanceAttributes, attributeLocations, perInstanceAttributeNames); return { geometries : geometries, modelMatrix : parameters.modelMatrix, attributeLocations : attributeLocations, vaAttributes : perInstanceAttributes, - vaAttributeLocations : indices + vaAttributeLocations : indices, + validInstancesIndices : parameters.validInstancesIndices, + invalidInstancesIndices : parameters.invalidInstancesIndices }; }; @@ -503,6 +537,12 @@ define([ var length = items.length; for (var i = 0; i < length; i++) { var geometry = items[i]; + ++count; + + if (!defined(geometry)) { + continue; + } + var attributes = geometry.attributes; count += 6 + 2 * BoundingSphere.packedLength + (defined(geometry.indices) ? geometry.indices.length : 0); @@ -532,6 +572,13 @@ define([ for (var i = 0; i < length; i++) { var geometry = items[i]; + var validGeometry = defined(geometry); + packedData[count++] = validGeometry ? 1.0 : 0.0; + + if (!validGeometry) { + continue; + } + packedData[count++] = geometry.primitiveType; packedData[count++] = geometry.geometryType; @@ -606,6 +653,12 @@ define([ var packedGeometryIndex = 1; while (packedGeometryIndex < packedGeometry.length) { + var valid = packedGeometry[packedGeometryIndex++] === 1.0; + if (!valid) { + result[resultIndex++] = undefined; + continue; + } + var primitiveType = packedGeometry[packedGeometryIndex++]; var geometryType = packedGeometry[packedGeometryIndex++]; @@ -806,7 +859,7 @@ define([ for ( var propertyName in instance) { if (instance.hasOwnProperty(propertyName) && defined(instance[propertyName])) { var property = instance[propertyName]; - count += 3 + (property.indices.length * 3) + property.value.length; + count += 4 + (property.indices.length * 3) + property.value.length; } } } @@ -841,6 +894,7 @@ define([ var name = propertiesToWrite[q]; var property = instance[name]; packedData[count++] = stringHash[name]; + packedData[count++] = property.valid ? 1.0 : 0.0; var indices = property.indices; var indicesLength = indices.length; @@ -886,9 +940,11 @@ define([ var numAttributes = packedData[i++]; for (var x = 0; x < numAttributes; x++) { var name = stringTable[packedData[i++]]; + var valid = packedData[i++] === 1.0; - var indices = new Array(packedData[i++]); - for (var indicesIndex = 0; indicesIndex < indices.length; indicesIndex++) { + var indicesLength = packedData[i++]; + var indices = indicesLength > 0 ? new Array(indicesLength) : undefined; + for (var indicesIndex = 0; indicesIndex < indicesLength; indicesIndex++) { var index = {}; index.count = packedData[i++]; index.offset = packedData[i++]; @@ -897,13 +953,14 @@ define([ } var valueLength = packedData[i++]; - var value = ComponentDatatype.createTypedArray(indices[0].attribute.componentDatatype, valueLength); + var value = valid ? ComponentDatatype.createTypedArray(indices[0].attribute.componentDatatype, valueLength) : new Array(valueLength); for (var valueIndex = 0; valueIndex < valueLength; valueIndex++) { value[valueIndex] = packedData[i++]; } instance[name] = { dirty : false, + valid : valid, indices : indices, value : value }; @@ -955,11 +1012,30 @@ define([ var length = createGeometryResults.length; var instanceIndex = 0; + var validInstances = []; + var invalidInstances = []; + var validInstancesIndices = []; + var invalidInstancesIndices = []; + var validPickIds = []; + for (var resultIndex = 0; resultIndex < length; resultIndex++) { var geometries = PrimitivePipeline.unpackCreateGeometryResults(createGeometryResults[resultIndex]); var geometriesLength = geometries.length; for (var geometryIndex = 0; geometryIndex < geometriesLength; geometryIndex++) { - instances[instanceIndex++].geometry = geometries[geometryIndex]; + var geometry = geometries[geometryIndex]; + var instance = instances[instanceIndex]; + + if (defined(geometry)) { + instance.geometry = geometry; + validInstances.push(instance); + validInstancesIndices.push(instanceIndex); + validPickIds.push(pickIds[instanceIndex]); + } else { + invalidInstances.push(instance); + invalidInstancesIndices.push(instanceIndex); + } + + ++instanceIndex; } } @@ -967,8 +1043,11 @@ define([ var projection = packedParameters.isGeographic ? new GeographicProjection(ellipsoid) : new WebMercatorProjection(ellipsoid); return { - instances : instances, - pickIds : pickIds, + instances : validInstances, + invalidInstances : invalidInstances, + validInstancesIndices : validInstancesIndices, + invalidInstancesIndices : invalidInstancesIndices, + pickIds : validPickIds, ellipsoid : ellipsoid, projection : projection, elementIndexUintSupported : packedParameters.elementIndexUintSupported, @@ -984,15 +1063,19 @@ define([ * @private */ PrimitivePipeline.packCombineGeometryResults = function(results, transferableObjects) { - transferGeometries(results.geometries, transferableObjects); - transferPerInstanceAttributes(results.vaAttributes, transferableObjects); + if (defined(results.geometries)) { + transferGeometries(results.geometries, transferableObjects); + transferPerInstanceAttributes(results.vaAttributes, transferableObjects); + } return { geometries : results.geometries, attributeLocations : results.attributeLocations, vaAttributes : results.vaAttributes, packedVaAttributeLocations : packAttributeLocations(results.vaAttributeLocations, transferableObjects), - modelMatrix : results.modelMatrix + modelMatrix : results.modelMatrix, + validInstancesIndices : results.validInstancesIndices, + invalidInstancesIndices : results.invalidInstancesIndices }; }; diff --git a/Source/Workers/createGeometry.js b/Source/Workers/createGeometry.js index 24570db39d42..2044426aa312 100644 --- a/Source/Workers/createGeometry.js +++ b/Source/Workers/createGeometry.js @@ -2,11 +2,13 @@ define([ '../Core/defined', '../Scene/PrimitivePipeline', + '../ThirdParty/when', './createTaskProcessorWorker', 'require' ], function( defined, PrimitivePipeline, + when, createTaskProcessorWorker, require) { "use strict"; @@ -26,20 +28,21 @@ define([ } function createGeometry(parameters, transferableObjects) { - var results = []; var subTasks = parameters.subTasks; + var length = subTasks.length; + var results = new Array(length); - for (var i = 0; i < subTasks.length; i++) { + for (var i = 0; i < length; i++) { var task = subTasks[i]; var geometry = task.geometry; var moduleName = task.moduleName; if (defined(moduleName)) { var createFunction = getModule(moduleName); - results.push(createFunction(geometry, task.offset)); + results[i] = createFunction(geometry, task.offset); } else { //Already created geometry - results.push(geometry); + results[i] = geometry; } } diff --git a/Specs/Core/CorridorGeometrySpec.js b/Specs/Core/CorridorGeometrySpec.js index 39ee05d6e0ab..d283bda6076e 100644 --- a/Specs/Core/CorridorGeometrySpec.js +++ b/Specs/Core/CorridorGeometrySpec.js @@ -22,18 +22,6 @@ defineSuite([ }).toThrowDeveloperError(); }); - it('throws without 2 unique positions', function() { - expect(function() { - return CorridorGeometry.createGeometry(new CorridorGeometry({ - positions : Cartesian3.fromDegreesArray([ - 90.0, -30.0, - 90.0, -30.0 - ]), - width: 10000 - })); - }).toThrowDeveloperError(); - }); - it('throws without width', function() { expect(function() { return new CorridorGeometry({ @@ -42,6 +30,17 @@ defineSuite([ }).toThrowDeveloperError(); }); + it('createGeometry returns undefined without 2 unique positions', function() { + var geometry = CorridorGeometry.createGeometry(new CorridorGeometry({ + positions : Cartesian3.fromDegreesArray([ + 90.0, -30.0, + 90.0, -30.0 + ]), + width: 10000 + })); + expect(geometry).not.toBeDefined(); + }); + it('computes positions', function() { var m = CorridorGeometry.createGeometry(new CorridorGeometry({ vertexFormat : VertexFormat.POSITION_ONLY, diff --git a/Specs/Core/CorridorOutlineGeometrySpec.js b/Specs/Core/CorridorOutlineGeometrySpec.js index d56039c7f3b4..b3933c478da3 100644 --- a/Specs/Core/CorridorOutlineGeometrySpec.js +++ b/Specs/Core/CorridorOutlineGeometrySpec.js @@ -20,18 +20,6 @@ defineSuite([ }).toThrowDeveloperError(); }); - it('throws without 2 unique positions', function() { - expect(function() { - return CorridorOutlineGeometry.createGeometry(new CorridorOutlineGeometry({ - positions : Cartesian3.fromDegreesArray([ - 90.0, -30.0, - 90.0, -30.0 - ]), - width: 10000 - })); - }).toThrowDeveloperError(); - }); - it('throws without width', function() { expect(function() { return new CorridorOutlineGeometry({ @@ -40,6 +28,17 @@ defineSuite([ }).toThrowDeveloperError(); }); + it('createGeometry returns undefined without 2 unique positions', function() { + var geometry = CorridorOutlineGeometry.createGeometry(new CorridorOutlineGeometry({ + positions : Cartesian3.fromDegreesArray([ + 90.0, -30.0, + 90.0, -30.0 + ]), + width: 10000 + })); + expect(geometry).not.toBeDefined(); + }); + it('computes positions', function() { var m = CorridorOutlineGeometry.createGeometry(new CorridorOutlineGeometry({ positions : Cartesian3.fromDegreesArray([ diff --git a/Specs/Core/PolygonGeometrySpec.js b/Specs/Core/PolygonGeometrySpec.js index 6ca7991832ca..b36290ed20db 100644 --- a/Specs/Core/PolygonGeometrySpec.js +++ b/Specs/Core/PolygonGeometrySpec.js @@ -47,32 +47,30 @@ defineSuite([ }).toThrowDeveloperError(); }); - it('throws due to duplicate positions', function() { - expect(function() { - return PolygonGeometry.createGeometry(PolygonGeometry.fromPositions({ - positions : Cartesian3.fromDegreesArray([ - 0.0, 0.0, - 0.0, 0.0, - 0.0, 0.0 - ]) - })); - }).toThrowDeveloperError(); + it('createGeometry returns undefined due to duplicate positions', function() { + var geometry = PolygonGeometry.createGeometry(PolygonGeometry.fromPositions({ + positions : Cartesian3.fromDegreesArray([ + 0.0, 0.0, + 0.0, 0.0, + 0.0, 0.0 + ]) + })); + expect(geometry).not.toBeDefined(); }); - it('throws due to duplicate positions extruded', function() { - expect(function() { - return PolygonGeometry.createGeometry(PolygonGeometry.fromPositions({ - positions : Cartesian3.fromDegreesArray([ - 0.0, 0.0, - 0.0, 0.0, - 0.0, 0.0 - ]), - extrudedHeight: 2 - })); - }).toThrowDeveloperError(); + it('createGeometry returns undefined due to duplicate positions extruded', function() { + var geometry = PolygonGeometry.createGeometry(PolygonGeometry.fromPositions({ + positions : Cartesian3.fromDegreesArray([ + 0.0, 0.0, + 0.0, 0.0, + 0.0, 0.0 + ]), + extrudedHeight: 2 + })); + expect(geometry).not.toBeDefined(); }); - it('throws due to duplicate hierarchy positions', function() { + it('createGeometry returns undefined due to duplicate hierarchy positions', function() { var hierarchy = { positions : Cartesian3.fromDegreesArray([ 1.0, 1.0, @@ -88,11 +86,8 @@ defineSuite([ }] }; - expect(function() { - return PolygonGeometry.createGeometry(new PolygonGeometry({ - polygonHierarchy : hierarchy - })); - }).toThrowDeveloperError(); + var geometry = PolygonGeometry.createGeometry(new PolygonGeometry({ polygonHierarchy : hierarchy })); + expect(geometry).not.toBeDefined(); }); it('computes positions', function() { diff --git a/Specs/Core/PolygonOutlineGeometrySpec.js b/Specs/Core/PolygonOutlineGeometrySpec.js index f029d3adebef..d4b77e487a33 100644 --- a/Specs/Core/PolygonOutlineGeometrySpec.js +++ b/Specs/Core/PolygonOutlineGeometrySpec.js @@ -36,7 +36,7 @@ defineSuite([ it('throws with polygon hierarchy with less than three positions', function() { var hierarchy = { - positions : [Cartesian3.fromDegrees(0, 0)] + positions : [Cartesian3.fromDegrees(0,0)] }; expect(function() { @@ -44,33 +44,30 @@ defineSuite([ }).toThrowDeveloperError(); }); - it('throws due to duplicate positions', function() { - expect(function() { - return PolygonOutlineGeometry.createGeometry(PolygonOutlineGeometry.fromPositions({ - positions : Cartesian3.fromDegreesArray([ - 0.0, 0.0, - 0.0, 0.0, - 0.0, 0.0 - ]) - })); - }).toThrowDeveloperError(); + it('createGeometry returns undefined due to duplicate positions', function() { + var geometry = PolygonOutlineGeometry.createGeometry(PolygonOutlineGeometry.fromPositions({ + positions : Cartesian3.fromDegreesArray([ + 0.0, 0.0, + 0.0, 0.0, + 0.0, 0.0 + ]) + })); + expect(geometry).not.toBeDefined(); }); - - it('throws due to duplicate positions extruded', function() { - expect(function() { - return PolygonOutlineGeometry.createGeometry(PolygonOutlineGeometry.fromPositions({ - positions : Cartesian3.fromDegreesArray([ - 0.0, 0.0, - 0.0, 0.0, - 0.0, 0.0 - ]), - extrudedeHeight: 2 - })); - }).toThrowDeveloperError(); + it('createGeometry returns undefined due to duplicate positions extruded', function() { + var geometry = PolygonOutlineGeometry.createGeometry(PolygonOutlineGeometry.fromPositions({ + positions : Cartesian3.fromDegreesArray([ + 0.0, 0.0, + 0.0, 0.0, + 0.0, 0.0 + ]), + extrudedHeight: 2 + })); + expect(geometry).not.toBeDefined(); }); - it('throws due to duplicate hierarchy positions', function() { + it('createGeometry returns undefined due to duplicate hierarchy positions', function() { var hierarchy = { positions : Cartesian3.fromDegreesArray([ 1.0, 1.0, @@ -86,11 +83,8 @@ defineSuite([ }] }; - expect(function() { - return PolygonOutlineGeometry.createGeometry(new PolygonOutlineGeometry({ - polygonHierarchy : hierarchy - })); - }).toThrowDeveloperError(); + var geometry = PolygonOutlineGeometry.createGeometry(new PolygonOutlineGeometry({ polygonHierarchy : hierarchy })); + expect(geometry).not.toBeDefined(); }); it('computes positions', function() { diff --git a/Specs/Core/PolylineGeometrySpec.js b/Specs/Core/PolylineGeometrySpec.js index c30f221bda46..b646d270f278 100644 --- a/Specs/Core/PolylineGeometrySpec.js +++ b/Specs/Core/PolylineGeometrySpec.js @@ -148,18 +148,17 @@ defineSuite([ expect(line.attributes.position.values.length).toEqual(numVertices * 3); }); - it('throws without at least 2 unique positions', function() { + it('createGeometry returns undefined without at least 2 unique positions', function() { var position = new Cartesian3(100000.0, -200000.0, 300000.0); var positions = [position, Cartesian3.clone(position)]; - expect(function() { - PolylineGeometry.createGeometry(new PolylineGeometry({ - positions : positions, - width : 10.0, - vertexFormat : VertexFormat.POSITION_ONLY, - followSurface : false - })); - }).toThrowDeveloperError(); + var geometry = PolylineGeometry.createGeometry(new PolylineGeometry({ + positions : positions, + width : 10.0, + vertexFormat : VertexFormat.POSITION_ONLY, + followSurface : false + })); + expect(geometry).not.toBeDefined(); }); var positions = [new Cartesian3(1.0, 0.0, 0.0), new Cartesian3(0.0, 1.0, 0.0), new Cartesian3(0.0, 0.0, 1.0)]; diff --git a/Specs/Core/PolylineVolumeGeometrySpec.js b/Specs/Core/PolylineVolumeGeometrySpec.js index 2a4f9a38e09e..1bae1ed4d866 100644 --- a/Specs/Core/PolylineVolumeGeometrySpec.js +++ b/Specs/Core/PolylineVolumeGeometrySpec.js @@ -37,22 +37,20 @@ defineSuite([ }).toThrowDeveloperError(); }); - it('throws without 2 unique polyline positions', function() { - expect(function() { - return PolylineVolumeGeometry.createGeometry(new PolylineVolumeGeometry({ - polylinePositions: [new Cartesian3()], - shapePositions: shape - })); - }).toThrowDeveloperError(); + it('createGeometry returnes undefined without 2 unique polyline positions', function() { + var geometry = PolylineVolumeGeometry.createGeometry(new PolylineVolumeGeometry({ + polylinePositions: [new Cartesian3()], + shapePositions: shape + })); + expect(geometry).not.toBeDefined(); }); - it('throws without 3 unique shape positions', function() { - expect(function() { - return PolylineVolumeGeometry.createGeometry(new PolylineVolumeGeometry({ - polylinePositions: [Cartesian3.UNIT_X, Cartesian3.UNIT_Y], - shapePositions: [Cartesian2.UNIT_X, Cartesian2.UNIT_X, Cartesian2.UNIT_X] - })); - }).toThrowDeveloperError(); + it('createGeometry returnes undefined without 3 unique shape positions', function() { + var geometry = PolylineVolumeGeometry.createGeometry(new PolylineVolumeGeometry({ + polylinePositions: [Cartesian3.UNIT_X, Cartesian3.UNIT_Y], + shapePositions: [Cartesian2.UNIT_X, Cartesian2.UNIT_X, Cartesian2.UNIT_X] + })); + expect(geometry).not.toBeDefined(); }); it('computes positions', function() { diff --git a/Specs/Core/PolylineVolumeOutlineGeometrySpec.js b/Specs/Core/PolylineVolumeOutlineGeometrySpec.js index 8786e3476a37..ecc10c288af4 100644 --- a/Specs/Core/PolylineVolumeOutlineGeometrySpec.js +++ b/Specs/Core/PolylineVolumeOutlineGeometrySpec.js @@ -36,22 +36,20 @@ defineSuite([ }).toThrowDeveloperError(); }); - it('throws without 2 unique polyline positions', function() { - expect(function() { - return PolylineVolumeOutlineGeometry.createGeometry(new PolylineVolumeOutlineGeometry({ - polylinePositions: [new Cartesian3()], - shapePositions: shape - })); - }).toThrowDeveloperError(); + it('createGeometry returnes undefined without 2 unique polyline positions', function() { + var geometry = PolylineVolumeOutlineGeometry.createGeometry(new PolylineVolumeOutlineGeometry({ + polylinePositions: [new Cartesian3()], + shapePositions: shape + })); + expect(geometry).not.toBeDefined(); }); - it('throws without 3 unique shape positions', function() { - expect(function() { - return PolylineVolumeOutlineGeometry.createGeometry(new PolylineVolumeOutlineGeometry({ - polylinePositions: [Cartesian3.UNIT_X, Cartesian3.UNIT_Y], - shapePositions: [Cartesian2.UNIT_X, Cartesian2.UNIT_X, Cartesian2.UNIT_X] - })); - }).toThrowDeveloperError(); + it('createGeometry returnes undefined without 3 unique shape positions', function() { + var geometry = PolylineVolumeOutlineGeometry.createGeometry(new PolylineVolumeOutlineGeometry({ + polylinePositions: [Cartesian3.UNIT_X, Cartesian3.UNIT_Y], + shapePositions: [Cartesian2.UNIT_X, Cartesian2.UNIT_X, Cartesian2.UNIT_X] + })); + expect(geometry).not.toBeDefined(); }); it('computes positions', function() { diff --git a/Specs/Core/WallGeometrySpec.js b/Specs/Core/WallGeometrySpec.js index be36eb936314..5b55de69510a 100644 --- a/Specs/Core/WallGeometrySpec.js +++ b/Specs/Core/WallGeometrySpec.js @@ -51,17 +51,15 @@ defineSuite([ }).toThrowDeveloperError(); }); - it('throws with less than 2 unique positions', function() { - expect(function() { - return WallGeometry.createGeometry(new WallGeometry({ - vertexFormat : VertexFormat.POSITION_ONLY, - positions : Cartesian3.fromDegreesArrayHeights([ - 49.0, 18.0, 1000.0, - 49.0, 18.0, 5000.0, - 49.0, 18.0, 1000.0 - ]) - })); - }).toThrowDeveloperError(); + it('createGeometry returnes undefined with less than 2 unique positions', function() { + var geometry = WallGeometry.createGeometry(new WallGeometry({ + positions : Cartesian3.fromDegreesArrayHeights([ + 49.0, 18.0, 1000.0, + 49.0, 18.0, 5000.0, + 49.0, 18.0, 1000.0 + ]) + })); + expect(geometry).not.toBeDefined(); }); it('does not throw when positions are unique but close', function() { diff --git a/Specs/Core/WallOutlineGeometrySpec.js b/Specs/Core/WallOutlineGeometrySpec.js index f724b7c06a92..94f92efba558 100644 --- a/Specs/Core/WallOutlineGeometrySpec.js +++ b/Specs/Core/WallOutlineGeometrySpec.js @@ -48,16 +48,15 @@ defineSuite([ }).toThrowDeveloperError(); }); - it('throws with less than 2 unique positions', function() { - expect(function() { - return WallOutlineGeometry.createGeometry(new WallOutlineGeometry({ - positions : Cartesian3.fromDegreesArrayHeights([ - 49.0, 18.0, 1000.0, - 49.0, 18.0, 5000.0, - 49.0, 18.0, 1000.0 - ]) - })); - }).toThrowDeveloperError(); + it('createGeometry returnes undefined with less than 2 unique positions', function() { + var geometry = WallOutlineGeometry.createGeometry(new WallOutlineGeometry({ + positions : Cartesian3.fromDegreesArrayHeights([ + 49.0, 18.0, 1000.0, + 49.0, 18.0, 5000.0, + 49.0, 18.0, 1000.0 + ]) + })); + expect(geometry).not.toBeDefined(); }); it('creates positions relative to ellipsoid', function() { diff --git a/Specs/Scene/PolygonSpec.js b/Specs/Scene/PolygonSpec.js index 1c4351d5c2f2..d2baf2d90709 100644 --- a/Specs/Scene/PolygonSpec.js +++ b/Specs/Scene/PolygonSpec.js @@ -326,50 +326,6 @@ defineSuite([ destroyScene(scene); }); - it('throws without positions due to duplicates', function() { - var ellipsoid = Ellipsoid.UNIT_SPHERE; - - polygon = new Polygon(); - polygon.ellipsoid = ellipsoid; - polygon.positions = Cartesian3.fromDegreesArray([ - 0.0, 0.0, - 0.0, 0.0, - 0.0, 0.0 - ], ellipsoid); - polygon.asynchronous = false; - - expect(function() { - render(context, frameState, polygon); - }).toThrowDeveloperError(); - }); - - it('throws without hierarchy positions due to duplicates', function() { - var ellipsoid = Ellipsoid.UNIT_SPHERE; - var hierarchy = { - positions : Cartesian3.fromDegreesArray([ - 1.0, 1.0, - 1.0, 1.0, - 1.0, 1.0 - ], ellipsoid), - holes : [{ - positions : Cartesian3.fromDegreesArray([ - 0.0, 0.0, - 0.0, 0.0, - 0.0, 0.0 - ], ellipsoid) - }] - }; - - polygon = new Polygon(); - polygon.ellipsoid = ellipsoid; - polygon.configureFromPolygonHierarchy(hierarchy); - polygon.asynchronous = false; - - expect(function () { - render(context, frameState, polygon); - }).toThrowDeveloperError(); - }); - it('is picked', function() { polygon = createPolygon({ id : 'id'