diff --git a/CHANGES.md b/CHANGES.md index 987bef965dad..dcf36e2a7773 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -23,6 +23,7 @@ Change Log * Fixed a bug causing crashes with custom vertex attributes on `Geometry` crossing the IDL. Attributes will be barycentrically interpolated. [#6644](https://github.com/AnalyticalGraphicsInc/cesium/pull/6644) * Fixed a bug causing Point Cloud tiles with unsigned int batch-ids to not load. [#6666](https://github.com/AnalyticalGraphicsInc/cesium/pull/6666) * Fixed a bug with Draco encoded i3dm tiles, and loading two Draco models with the same url. [#6668](https://github.com/AnalyticalGraphicsInc/cesium/issues/6668) +* Fixed a bug caused by creating a polygon with positions at the same longitude/latitude position but different heights [#6731](https://github.com/AnalyticalGraphicsInc/cesium/pull/6731) * Fixed terrain clipping when the camera was close to flat terrain and was using logarithmic depth. [#6701](https://github.com/AnalyticalGraphicsInc/cesium/pull/6701) * Fixed KML bug that constantly requested the same image if it failed to load. [#6710](https://github.com/AnalyticalGraphicsInc/cesium/pull/6710) * Improved billboard and label rendering so they no longer sink into terrain when clamped to ground. [#6621](https://github.com/AnalyticalGraphicsInc/cesium/pull/6621) diff --git a/Source/Core/PolygonGeometryLibrary.js b/Source/Core/PolygonGeometryLibrary.js index 58b77b2b3277..ba6cf5426414 100644 --- a/Source/Core/PolygonGeometryLibrary.js +++ b/Source/Core/PolygonGeometryLibrary.js @@ -217,6 +217,15 @@ define([ var outerRing = outerNode.positions; var holes = outerNode.holes; + var i; + var length; + if (!perPositionHeight) { + length = outerRing.length; + for (i = 0; i < length; i++) { + ellipsoid.scaleToGeodeticSurface(outerRing[i], outerRing[i]); + } + } + outerRing = arrayRemoveDuplicates(outerRing, Cartesian3.equalsEpsilon, true); if (outerRing.length < 3) { continue; @@ -234,12 +243,19 @@ define([ var positions = outerRing.slice(); var numChildren = defined(holes) ? holes.length : 0; var polygonHoles = []; - var i; var j; for (i = 0; i < numChildren; i++) { var hole = holes[i]; - var holePositions = arrayRemoveDuplicates(hole.positions, Cartesian3.equalsEpsilon, true); + var holePositions = hole.positions; + if (!perPositionHeight) { + length = holePositions.length; + for (j = 0; j < length; ++j) { + ellipsoid.scaleToGeodeticSurface(holePositions[j], holePositions[j]); + } + } + + holePositions = arrayRemoveDuplicates(holePositions, Cartesian3.equalsEpsilon, true); if (holePositions.length < 3) { continue; } @@ -267,18 +283,6 @@ define([ } } - if (!perPositionHeight) { - for (i = 0; i < outerRing.length; i++) { - ellipsoid.scaleToGeodeticSurface(outerRing[i], outerRing[i]); - } - for (i = 0; i < polygonHoles.length; i++) { - var polygonHole = polygonHoles[i]; - for (j = 0; j < polygonHole.length; ++j) { - ellipsoid.scaleToGeodeticSurface(polygonHole[j], polygonHole[j]); - } - } - } - hierarchy.push({ outerRing : outerRing, holes : polygonHoles diff --git a/Source/Core/PolygonOutlineGeometry.js b/Source/Core/PolygonOutlineGeometry.js index ed02b8938d89..95a854cd1f65 100644 --- a/Source/Core/PolygonOutlineGeometry.js +++ b/Source/Core/PolygonOutlineGeometry.js @@ -483,9 +483,17 @@ define([ var queue = new Queue(); queue.enqueue(polygonHierarchy); var i; + var j; + var length; while (queue.length !== 0) { var outerNode = queue.dequeue(); var outerRing = outerNode.positions; + if (!perPositionHeight) { + length = outerRing.length; + for (i = 0; i < length; i++) { + ellipsoid.scaleToGeodeticSurface(outerRing[i], outerRing[i]); + } + } outerRing = arrayRemoveDuplicates(outerRing, Cartesian3.equalsEpsilon, true); if (outerRing.length < 3) { continue; @@ -495,18 +503,25 @@ define([ // The outer polygon contains inner polygons for (i = 0; i < numChildren; i++) { var hole = outerNode.holes[i]; - hole.positions = arrayRemoveDuplicates(hole.positions, Cartesian3.equalsEpsilon, true); - if (hole.positions.length < 3) { + var holePositions = hole.positions; + if (!perPositionHeight) { + length = holePositions.length; + for (j = 0; j < length; ++j) { + ellipsoid.scaleToGeodeticSurface(holePositions[j], holePositions[j]); + } + } + holePositions = arrayRemoveDuplicates(holePositions, Cartesian3.equalsEpsilon, true); + if (holePositions.length < 3) { continue; } - polygons.push(hole.positions); + polygons.push(holePositions); var numGrandchildren = 0; if (defined(hole.holes)) { numGrandchildren = hole.holes.length; } - for ( var j = 0; j < numGrandchildren; j++) { + for (j = 0; j < numGrandchildren; j++) { queue.enqueue(hole.holes[j]); } } @@ -554,7 +569,7 @@ define([ geometryInstance.geometry.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(geometryInstance.geometry.attributes.position.values, height, ellipsoid, !perPositionHeight); if (defined(polygonGeometry._offsetAttribute)) { - var length = geometryInstance.geometry.attributes.position.values.length; + length = geometryInstance.geometry.attributes.position.values.length; var applyOffset = new Uint8Array(length / 3); offsetValue = polygonGeometry._offsetAttribute === GeometryOffsetAttribute.NONE ? 0 : 1; arrayFill(applyOffset, offsetValue); diff --git a/Specs/Core/PolygonGeometrySpec.js b/Specs/Core/PolygonGeometrySpec.js index 20b8f0e8e0b7..f97032f86453 100644 --- a/Specs/Core/PolygonGeometrySpec.js +++ b/Specs/Core/PolygonGeometrySpec.js @@ -84,24 +84,64 @@ defineSuite([ it('createGeometry returns undefined due to duplicate hierarchy positions', function() { var hierarchy = { + positions : Cartesian3.fromDegreesArray([ + 1.0, 1.0, + 1.0, 1.0, + 1.0, 1.0 + ]), + holes : [{ positions : Cartesian3.fromDegreesArray([ - 1.0, 1.0, - 1.0, 1.0, - 1.0, 1.0 - ]), - holes : [{ - positions : Cartesian3.fromDegreesArray([ - 0.0, 0.0, - 0.0, 0.0, - 0.0, 0.0 - ]) - }] + 0.0, 0.0, + 0.0, 0.0, + 0.0, 0.0 + ]) + }] }; var geometry = PolygonGeometry.createGeometry(new PolygonGeometry({ polygonHierarchy : hierarchy })); expect(geometry).toBeUndefined(); }); + it('createGeometry returns undefined due to duplicate hierarchy positions with different heights', function() { + var hierarchy = { + positions : Cartesian3.fromDegreesArrayHeights([ + 1.0, 1.0, 10.0, + 1.0, 1.0, 20.0, + 1.0, 1.0, 30.0 + ]), + holes : [{ + positions : Cartesian3.fromDegreesArrayHeights([ + 0.0, 0.0, 10.0, + 0.0, 0.0, 20.0, + 0.0, 0.0, 30.0 + ]) + }] + }; + + var geometry = PolygonGeometry.createGeometry(new PolygonGeometry({ polygonHierarchy : hierarchy })); + expect(geometry).toBeUndefined(); + }); + + it('createGeometry returns geometry if duplicate hierarchy positions with different heights and perPositionHeight is true', function() { + var hierarchy = { + positions : Cartesian3.fromDegreesArrayHeights([ + 1.0, 1.0, 10.0, + 1.0, 1.0, 20.0, + 1.0, 1.0, 30.0 + ]), + holes : [{ + positions : Cartesian3.fromDegreesArrayHeights([ + 0.0, 0.0, 10.0, + 0.0, 0.0, 20.0, + 0.0, 0.0, 30.0 + ]) + }] + }; + + var geometry = PolygonGeometry.createGeometry(new PolygonGeometry({ polygonHierarchy : hierarchy, perPositionHeight: true })); + expect(geometry).toBeDefined(); + }); + it('computes positions', function() { var p = PolygonGeometry.createGeometry(PolygonGeometry.fromPositions({ vertexFormat : VertexFormat.POSITION_ONLY, diff --git a/Specs/Core/PolygonOutlineGeometrySpec.js b/Specs/Core/PolygonOutlineGeometrySpec.js index 907a21fb31bb..013329d16c0b 100644 --- a/Specs/Core/PolygonOutlineGeometrySpec.js +++ b/Specs/Core/PolygonOutlineGeometrySpec.js @@ -96,6 +96,46 @@ defineSuite([ expect(geometry).toBeUndefined(); }); + it('createGeometry returns undefined due to duplicate hierarchy positions with different heights', function() { + var hierarchy = { + positions : Cartesian3.fromDegreesArrayHeights([ + 1.0, 1.0, 10.0, + 1.0, 1.0, 20.0, + 1.0, 1.0, 30.0 + ]), + holes : [{ + positions : Cartesian3.fromDegreesArrayHeights([ + 0.0, 0.0, 10.0, + 0.0, 0.0, 20.0, + 0.0, 0.0, 30.0 + ]) + }] + }; + + var geometry = PolygonOutlineGeometry.createGeometry(new PolygonOutlineGeometry({ polygonHierarchy : hierarchy })); + expect(geometry).toBeUndefined(); + }); + + it('createGeometry returns geometry if duplicate hierarchy positions with different heights and perPositionHeight is true', function() { + var hierarchy = { + positions : Cartesian3.fromDegreesArrayHeights([ + 1.0, 1.0, 10.0, + 1.0, 1.0, 20.0, + 1.0, 1.0, 30.0 + ]), + holes : [{ + positions : Cartesian3.fromDegreesArrayHeights([ + 0.0, 0.0, 10.0, + 0.0, 0.0, 20.0, + 0.0, 0.0, 30.0 + ]) + }] + }; + + var geometry = PolygonOutlineGeometry.createGeometry(new PolygonOutlineGeometry({ polygonHierarchy : hierarchy, perPositionHeight: true })); + expect(geometry).toBeDefined(); + }); + it('computes positions', function() { var p = PolygonOutlineGeometry.createGeometry(PolygonOutlineGeometry.fromPositions({ positions : Cartesian3.fromDegreesArray([ @@ -254,24 +294,24 @@ defineSuite([ granularity : CesiumMath.PI_OVER_THREE })); - expect(p).toEqual(Cartesian3.fromDegreesArray([ + expect(p).toEqualEpsilon(Cartesian3.fromDegreesArray([ -124.0, 35.0, -124.0, 40.0, -110.0, 40.0, -110.0, 35.0 - ])); - expect(h1).toEqual(Cartesian3.fromDegreesArray([ + ]), CesiumMath.EPSILON9); + expect(h1).toEqualEpsilon(Cartesian3.fromDegreesArray([ -122.0, 36.0, -112.0, 36.0, -112.0, 39.0, -122.0, 39.0 - ])); - expect(h2).toEqual(Cartesian3.fromDegreesArray([ + ]), CesiumMath.EPSILON9); + expect(h2).toEqualEpsilon(Cartesian3.fromDegreesArray([ -120.0, 36.5, -120.0, 38.5, -114.0, 38.5, -114.0, 36.5 - ])); + ]), CesiumMath.EPSILON9); }); it('computes correct bounding sphere at height 0', function() {