diff --git a/CHANGES.md b/CHANGES.md index a7cd37ccf261..40441451e1b3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ Change Log * Removed `Camera.heading` and `Camera.tilt`. They were deprecated in Cesium 1.6. Use `Camera.setView`. * Removed `Camera.setPositionCartographic`, which was was deprecated in Cesium 1.6. Use `Camera.setView`. * Fixed incorrect ellipse texture coordinates. [#2363](https://github.com/AnalyticalGraphicsInc/cesium/issues/2363) and [#2465](https://github.com/AnalyticalGraphicsInc/cesium/issues/2465) +* Fixed a bug that would cause incorrect geometry for long Corridors and Polyline Volumes. [#2513](https://github.com/AnalyticalGraphicsInc/cesium/issues/2513) * Fixed a bug in imagery loading that could cause some or all of the globe to be missing when using an imagery layer that does not cover the entire globe. * Added support for rendering a water effect on Quantized-Mesh terrain tiles. * Added `pack` and `unpack` functions to `Matrix2` and `Matrix3`. diff --git a/Source/Core/CorridorGeometryLibrary.js b/Source/Core/CorridorGeometryLibrary.js index e20fd4392c45..d937443a23c1 100644 --- a/Source/Core/CorridorGeometryLibrary.js +++ b/Source/Core/CorridorGeometryLibrary.js @@ -160,6 +160,9 @@ define([ return positions; } + var scratchForwardProjection = new Cartesian3(); + var scratchBackwardProjection = new Cartesian3(); + /** * @private */ @@ -207,7 +210,17 @@ define([ nextPosition = positions[i + 1]; forward = Cartesian3.normalize(Cartesian3.subtract(nextPosition, position, forward), forward); cornerDirection = Cartesian3.normalize(Cartesian3.add(forward, backward, cornerDirection), cornerDirection); - var doCorner = !Cartesian3.equalsEpsilon(Cartesian3.negate(cornerDirection, scratch1), normal, CesiumMath.EPSILON2); + + var forwardProjection = Cartesian3.multiplyByScalar(normal, Cartesian3.dot(forward, normal), scratchForwardProjection); + Cartesian3.subtract(forward, forwardProjection, forwardProjection); + Cartesian3.normalize(forwardProjection, forwardProjection); + + var backwardProjection = Cartesian3.multiplyByScalar(normal, Cartesian3.dot(backward, normal), scratchBackwardProjection); + Cartesian3.subtract(backward, backwardProjection, backwardProjection); + Cartesian3.normalize(backwardProjection, backwardProjection); + + var doCorner = !CesiumMath.equalsEpsilon(Math.abs(Cartesian3.dot(forwardProjection, backwardProjection)), 1.0, CesiumMath.EPSILON1); + if (doCorner) { cornerDirection = Cartesian3.cross(cornerDirection, normal, cornerDirection); cornerDirection = Cartesian3.cross(normal, cornerDirection, cornerDirection); diff --git a/Source/Core/PolylineVolumeGeometryLibrary.js b/Source/Core/PolylineVolumeGeometryLibrary.js index 53ae79aa0bf9..9df76e151611 100644 --- a/Source/Core/PolylineVolumeGeometryLibrary.js +++ b/Source/Core/PolylineVolumeGeometryLibrary.js @@ -290,6 +290,9 @@ define([ return cleanedPositions; }; + var scratchForwardProjection = new Cartesian3(); + var scratchBackwardProjection = new Cartesian3(); + PolylineVolumeGeometryLibrary.computePositions = function(positions, shape2D, boundingRectangle, geometry, duplicatePoints) { var ellipsoid = geometry._ellipsoid; var heights = scaleToSurface(positions, ellipsoid); @@ -338,7 +341,17 @@ define([ cornerDirection = Cartesian3.add(forward, backward, cornerDirection); cornerDirection = Cartesian3.normalize(cornerDirection, cornerDirection); surfaceNormal = ellipsoid.geodeticSurfaceNormal(position, surfaceNormal); - var doCorner = !Cartesian3.equalsEpsilon(Cartesian3.negate(cornerDirection, scratch1), surfaceNormal, CesiumMath.EPSILON2); + + var forwardProjection = Cartesian3.multiplyByScalar(surfaceNormal, Cartesian3.dot(forward, surfaceNormal), scratchForwardProjection); + Cartesian3.subtract(forward, forwardProjection, forwardProjection); + Cartesian3.normalize(forwardProjection, forwardProjection); + + var backwardProjection = Cartesian3.multiplyByScalar(surfaceNormal, Cartesian3.dot(backward, surfaceNormal), scratchBackwardProjection); + Cartesian3.subtract(backward, backwardProjection, backwardProjection); + Cartesian3.normalize(backwardProjection, backwardProjection); + + var doCorner = !CesiumMath.equalsEpsilon(Math.abs(Cartesian3.dot(forwardProjection, backwardProjection)), 1.0, CesiumMath.EPSILON1); + if (doCorner) { cornerDirection = Cartesian3.cross(cornerDirection, surfaceNormal, cornerDirection); cornerDirection = Cartesian3.cross(surfaceNormal, cornerDirection, cornerDirection); diff --git a/Specs/Core/CorridorGeometrySpec.js b/Specs/Core/CorridorGeometrySpec.js index d283bda6076e..1a6a3bdea42a 100644 --- a/Specs/Core/CorridorGeometrySpec.js +++ b/Specs/Core/CorridorGeometrySpec.js @@ -180,6 +180,23 @@ defineSuite([ expect(m.indices.length).toEqual(3 * 8); }); + it('computes straight corridors', function() { + var m = CorridorGeometry.createGeometry(new CorridorGeometry({ + vertexFormat : VertexFormat.POSITION_ONLY, + positions : Cartesian3.fromDegreesArray([ + -67.655, 0.0, + -67.655, 15.0, + -67.655, 20.0 + ]), + cornerType: CornerType.BEVELED, + width : 400000, + granularity : Math.PI / 6.0 + })); + + expect(m.attributes.position.values.length).toEqual(3 * 4); + expect(m.indices.length).toEqual(3 * 2); + }); + var positions = Cartesian3.fromDegreesArray([ 90.0, -30.0, 90.0, -31.0 diff --git a/Specs/Core/PolylineVolumeGeometrySpec.js b/Specs/Core/PolylineVolumeGeometrySpec.js index 1bae1ed4d866..973d03065ba5 100644 --- a/Specs/Core/PolylineVolumeGeometrySpec.js +++ b/Specs/Core/PolylineVolumeGeometrySpec.js @@ -169,6 +169,23 @@ defineSuite([ expect(m.indices.length).toEqual(3 * (8 * 2 + 4 * 7 * 2 + 4)); }); + it('computes straight volume', function() { + var m = PolylineVolumeGeometry.createGeometry(new PolylineVolumeGeometry({ + vertexFormat : VertexFormat.POSITION_ONLY, + polylinePositions : Cartesian3.fromDegreesArray([ + -67.655, 0.0, + -67.655, 15.0, + -67.655, 20.0 + ]), + cornerType: CornerType.BEVELED, + shapePositions: shape, + granularity : Math.PI / 6.0 + })); + + expect(m.attributes.position.values.length).toEqual(3 * 32); + expect(m.indices.length).toEqual(3 * 20); + }); + 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)]; var volumeShape = [new Cartesian2(0.0, 0.0), new Cartesian2(1.0, 0.0), new Cartesian2(0.0, 1.0)]; var volume = new PolylineVolumeGeometry({