Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Polylines on terrain via Primitive API #6615

Merged
merged 41 commits into from
Jun 13, 2018
Merged
Changes from 1 commit
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
bc4a24a
renderable polylines on terrain
likangning93 May 18, 2018
cbd2eb7
synchronization of ground polyline attributes by ID
likangning93 May 18, 2018
b2ac735
picking GroundPolylinePrimitive ignores material type (useful for das…
likangning93 May 21, 2018
bafa5f2
removed vertex normals for polyline shadow volumes
likangning93 May 21, 2018
0371307
Support for 2D/CV
likangning93 May 21, 2018
0c22456
add interpolation for long line segments, fixes for end normals
likangning93 May 22, 2018
ac29934
Sandcastle example for polylines on terrain via Primitive API [ci skip]
likangning93 May 22, 2018
ad8d711
fix some artifacts, fix doubledraw, add per-instance color support [c…
likangning93 May 24, 2018
4f71916
Merge branch 'master' into polylinesOnTerrain
likangning93 May 26, 2018
612152b
switch from batch table and many instances to fat vertices
likangning93 May 28, 2018
fe4849e
integrate ApproximateTerrainHeights into GroundPolylineGeometry, perm…
likangning93 May 29, 2018
5de9ded
some shader cleanup, restore automatic width attribute for polylines …
likangning93 May 29, 2018
9abaa8c
simulate morph [ci skip]
likangning93 May 30, 2018
e6e2c18
additional doc and Primitive parameters, fixed bounding volume comput…
likangning93 May 30, 2018
fe3531f
switch GroundPolylineGeometry to take cartesian positions
likangning93 May 31, 2018
02e7f22
split polyline shadow volumes across IDL and PM [ci skip]
likangning93 May 31, 2018
6a51e44
handle looping and normal projection for IDL/PM split [ci skip]
likangning93 Jun 1, 2018
63db595
fix additional IDL bugs [ci skip]
likangning93 Jun 1, 2018
9e39ecc
specs for GroundPolylineGeometry
likangning93 Jun 1, 2018
bed6ecf
special handling for lines near-parallel to IDL
likangning93 Jun 4, 2018
fd903d2
fix GroundPolylineGeometry test failure for built Cesium
likangning93 Jun 4, 2018
071a636
fix discontinuity for GroundPolylineGeometry due to plane origins bei…
likangning93 Jun 4, 2018
4aebfa1
specs for GroundPolylinePrimitive
likangning93 Jun 5, 2018
6ac0dd5
update Sandcastle example with Z-indexing demonstration
likangning93 Jun 5, 2018
5ee4a47
additional specs for GroundPolylinePrimitive, fix eslint errors
likangning93 Jun 5, 2018
436631a
reduce overdraw for tight corners
likangning93 Jun 7, 2018
d11829d
add defines to enable/disable varyings
likangning93 Jun 7, 2018
1d1850a
PR feedback
likangning93 Jun 7, 2018
1bd9695
Merge branch 'master' into polylinesOnTerrain
likangning93 Jun 7, 2018
6147990
remove custom pick commands for GroundPolylinePrimitive, picking what…
likangning93 Jun 7, 2018
43dbae2
performance tweak for polylines on terrain shader
likangning93 Jun 8, 2018
11d7bc4
adjust epsilons for polylines on terrain IDL handling
likangning93 Jun 8, 2018
7869029
typo fix
likangning93 Jun 8, 2018
eb95073
style/doc fixes, special geometry handling for sceneMode3D
likangning93 Jun 11, 2018
361c4cd
fix IDL split bug for CV and normalization error IDL/PM split bug
likangning93 Jun 11, 2018
fa7075f
push bottom vertices of volumes at far view distances
likangning93 Jun 11, 2018
81a23c8
fix artifacts in 2D and morph
likangning93 Jun 11, 2018
163d254
early discards
likangning93 Jun 11, 2018
403e500
remove unneeded options, add example doc for GroundPolylinePrimitive,…
likangning93 Jun 12, 2018
a822e15
update CHANGES.md
likangning93 Jun 12, 2018
3ec30e3
PR comments, back to breaking turns with larger angles
likangning93 Jun 12, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -135,7 +135,7 @@

polylineOnTerrainPrimitive = new Cesium.GroundPolylinePrimitive({
polylineGeometryInstances : [instance1, instance2],
debugShowShadowVolume : true
debugShowShadowVolume : false
});
scene.primitives.add(polylineOnTerrainPrimitive);

133 changes: 94 additions & 39 deletions Source/Core/GroundPolylineGeometry.js
Original file line number Diff line number Diff line change
@@ -520,19 +520,21 @@ define([
return false;
}

var positionCartographicScratch = new Cartographic();
var endPosCartographicScratch = new Cartographic();
var normalStartpointScratch = new Cartesian3();
var normalEndpointScratch = new Cartesian3();
function projectNormal(projection, position, positionLongitude, normal, projectedPosition, result) {
function projectNormal(projection, cartographic, normal, projectedPosition, result) {
var position = Cartographic.toCartesian(cartographic, projection.ellipsoid, normalStartpointScratch);
var normalEndpoint = Cartesian3.add(position, normal, normalEndpointScratch);
var flipNormal = false;

var ellipsoid = projection.ellipsoid;
var normalEndpointCartographic = ellipsoid.cartesianToCartographic(normalEndpoint, positionCartographicScratch);
var normalEndpointCartographic = ellipsoid.cartesianToCartographic(normalEndpoint, endPosCartographicScratch);
// If normal crosses the IDL, go the other way and flip the result
if (Math.abs(positionLongitude - normalEndpointCartographic.longitude) > CesiumMath.PI_OVER_TWO) {
if (Math.abs(cartographic.longitude - normalEndpointCartographic.longitude) > CesiumMath.PI_OVER_TWO) {
flipNormal = true;
normalEndpoint = Cartesian3.subtract(position, normal, normalEndpointScratch);
normalEndpointCartographic = ellipsoid.cartesianToCartographic(normalEndpoint, positionCartographicScratch);
normalEndpointCartographic = ellipsoid.cartesianToCartographic(normalEndpoint, endPosCartographicScratch);
}

normalEndpointCartographic.height = 0.0;
@@ -567,18 +569,33 @@ define([
var startToXZdistance = Plane.getPointDistance(XZ_PLANE, start);
var endToXZdistance = Plane.getPointDistance(XZ_PLANE, end);
var offset = nudgeDirectionScratch;
// Same epsilon used in GeometryPipeline
if (CesiumMath.equalsEpsilon(startToXZdistance, 0.0, CesiumMath.EPSILON6)) {
// Larger epsilon than what's used in GeometryPipeline, less than a centimeter in world space
if (CesiumMath.equalsEpsilon(startToXZdistance, 0.0, CesiumMath.EPSILON4)) {
offset = direction(end, start, offset);
Cartesian3.multiplyByScalar(offset, CesiumMath.EPSILON6, offset);
Cartesian3.multiplyByScalar(offset, CesiumMath.EPSILON4, offset);
Cartesian3.add(start, offset, start);
} else if (CesiumMath.equalsEpsilon(endToXZdistance, 0.0, CesiumMath.EPSILON6)) {
} else if (CesiumMath.equalsEpsilon(endToXZdistance, 0.0, CesiumMath.EPSILON4)) {
offset = direction(start, end, offset);
Cartesian3.multiplyByScalar(offset, CesiumMath.EPSILON6, offset);
Cartesian3.multiplyByScalar(offset, CesiumMath.EPSILON4, offset);
Cartesian3.add(end, offset, end);
}
}

function nudgeCartographic(start, end) {
var absStartLon = Math.abs(start.longitude);
var absEndLon = Math.abs(end.longitude);
if (CesiumMath.equalsEpsilon(absStartLon, CesiumMath.PI, CesiumMath.EPSILON7)) {
var endSign = Math.sign(end.longitude);
start.longitude = endSign * (absStartLon - CesiumMath.EPSILON7);
return 1;
} else if (CesiumMath.equalsEpsilon(absEndLon, CesiumMath.PI, CesiumMath.EPSILON7)) {
var startSign = Math.sign(start.longitude);
end.longitude = startSign * (absEndLon - CesiumMath.EPSILON7);
return 2;
}
return 0;
}

var startCartographicScratch = new Cartographic();
var endCartographicScratch = new Cartographic();

@@ -614,6 +631,8 @@ define([
var forwardOffset2DScratch = new Cartesian3();
var right2DScratch = new Cartesian3();

var normalNudgeScratch = new Cartesian3();

var scratchBoundingSpheres = [new BoundingSphere(), new BoundingSphere()];

// Winding order is reversed so each segment's volume is inside-out
@@ -662,21 +681,26 @@ define([
var length2D = 0.0;
var length3D = 0.0;

var cartographic = startCartographicScratch;
cartographic.latitude = cartographicsArray[0];
cartographic.longitude = cartographicsArray[1];
cartographic.height = 0.0;
var startCartographic = startCartographicScratch;
startCartographic.height = 0.0;
var endCartographic = endCartographicScratch;
endCartographic.height = 0.0;

var segmentStartCartesian = segmentStartTopScratch;
var segmentEndCartesian = projection.project(cartographic, segmentEndTopScratch);
var segmentEndCartesian = segmentEndTopScratch;

index = 2;
index = 0;
for (i = 1; i < cartographicsLength; i++) {
cartographic.latitude = cartographicsArray[index];
cartographic.longitude = cartographicsArray[index + 1];
// don't clone anything from previous segment b/c possible IDL touch
startCartographic.latitude = cartographicsArray[index];
startCartographic.longitude = cartographicsArray[index + 1];
endCartographic.latitude = cartographicsArray[index + 2];
endCartographic.longitude = cartographicsArray[index + 3];

segmentStartCartesian = Cartesian3.clone(segmentEndCartesian, segmentStartCartesian);
segmentEndCartesian = projection.project(cartographic, segmentEndCartesian);
nudgeCartographic(startCartographic, endCartographic);

segmentStartCartesian = projection.project(startCartographic, segmentStartCartesian);
segmentEndCartesian = projection.project(endCartographic, segmentEndCartesian);
length2D += Cartesian3.distance(segmentStartCartesian, segmentEndCartesian);
index += 2;
}
@@ -696,7 +720,7 @@ define([
/*** Generate segments ***/
var j;
index = 3;
var cartographicsIndex = 2;
var cartographicsIndex = 0;
var vec2sWriteIndex = 0;
var vec3sWriteIndex = 0;
var vec4sWriteIndex = 0;
@@ -713,12 +737,6 @@ define([
endGeometryNormal = Cartesian3.multiplyByScalar(endGeometryNormal, -1.0, endGeometryNormal);
}
}
var endCartographic = endCartographicScratch;
var startCartographic = startCartographicScratch;
endCartographic.latitude = cartographicsArray[0];
endCartographic.longitude = cartographicsArray[1];
var end2D = projection.project(endCartographic, segmentEnd2DScratch);
var endGeometryNormal2D = projectNormal(projection, endBottom, endCartographic.longitude, endGeometryNormal, end2D, segmentEndNormal2DScratch);

var lengthSoFar3D = 0.0;
var lengthSoFar2D = 0.0;
@@ -728,15 +746,8 @@ define([
var startTop = Cartesian3.clone(endTop, segmentStartTopScratch);
var startGeometryNormal = Cartesian3.clone(endGeometryNormal, segmentStartNormalScratch);

var start2D = Cartesian3.clone(end2D, segmentStart2DScratch);
var startGeometryNormal2D = Cartesian3.clone(endGeometryNormal2D, segmentStartNormal2DScratch);
startCartographic = Cartographic.clone(endCartographic, startCartographic);

if (miterBroken) {
// If miter was broken for the previous segment's end vertex, flip for this segment's start vertex
// These normals are "right facing."
startGeometryNormal = Cartesian3.multiplyByScalar(startGeometryNormal, -1.0, startGeometryNormal);
startGeometryNormal2D = Cartesian3.multiplyByScalar(startGeometryNormal2D, -1.0, startGeometryNormal2D);
}

endBottom = Cartesian3.unpack(bottomPositionsArray, index, segmentEndBottomScratch);
@@ -745,10 +756,36 @@ define([

miterBroken = breakMiter(endGeometryNormal, startBottom, endBottom, endTop);

endCartographic.latitude = cartographicsArray[cartographicsIndex];
endCartographic.longitude = cartographicsArray[cartographicsIndex + 1];
end2D = projection.project(endCartographic, segmentEnd2DScratch);
endGeometryNormal2D = projectNormal(projection, endBottom, endCartographic.longitude, endGeometryNormal, end2D, segmentEndNormal2DScratch);
// 2D - don't clone anything from previous segment b/c possible IDL touch
startCartographic.latitude = cartographicsArray[cartographicsIndex];
startCartographic.longitude = cartographicsArray[cartographicsIndex + 1];
endCartographic.latitude = cartographicsArray[cartographicsIndex + 2];
endCartographic.longitude = cartographicsArray[cartographicsIndex + 3];

var nudgeResult = nudgeCartographic(startCartographic, endCartographic);
var start2D = projection.project(startCartographic, segmentStart2DScratch);
var end2D = projection.project(endCartographic, segmentEnd2DScratch);

var startGeometryNormal2D = segmentStartNormal2DScratch;
var endGeometryNormal2D = segmentEndNormal2DScratch;
if (nudgeResult === 0) {
startGeometryNormal2D = projectNormal(projection, startCartographic, startGeometryNormal, start2D, segmentStartNormal2DScratch);
endGeometryNormal2D = projectNormal(projection, endCartographic, endGeometryNormal, end2D, segmentEndNormal2DScratch);
} else if (nudgeResult === 1) {
// start is close to IDL
endGeometryNormal2D = projectNormal(projection, endCartographic, endGeometryNormal, end2D, segmentEndNormal2DScratch);
startGeometryNormal2D.x = 0.0;
// If start longitude is negative and end longitude is less negative, "right" is unit -Y
// If start longitude is positive and end longitude is less positive, "right" is unit +Y
startGeometryNormal2D.y = Math.sign(startCartographic.longitude - Math.abs(endCartographic.longitude));
startGeometryNormal2D.z = 0.0;
} else {
// end is close to IDL
startGeometryNormal2D = projectNormal(projection, startCartographic, startGeometryNormal, start2D, segmentStartNormal2DScratch);
endGeometryNormal2D.x = 0.0;
endGeometryNormal2D.y = Math.sign(endCartographic.longitude - Math.abs(startCartographic.longitude));
endGeometryNormal2D.z = 0.0;
}

/****************************************
* Geometry descriptors of a "line on terrain,"
@@ -871,6 +908,13 @@ define([
adjustHeights(startBottom, startTop, minHeight, maxHeight, adjustHeightStartBottom, adjustHeightStartTop);
adjustHeights(endBottom, endTop, minHeight, maxHeight, adjustHeightEndBottom, adjustHeightEndTop);

// Nudge the positions away from the "polyline" a little bit to prevent errors in GeometryPipeline
var normalNudge = Cartesian3.multiplyByScalar(rightNormal, CesiumMath.EPSILON5, normalNudgeScratch);
Cartesian3.add(adjustHeightStartBottom, normalNudge, adjustHeightStartBottom);
Cartesian3.add(adjustHeightEndBottom, normalNudge, adjustHeightEndBottom);
Cartesian3.add(adjustHeightStartTop, normalNudge, adjustHeightStartTop);
Cartesian3.add(adjustHeightEndTop, normalNudge, adjustHeightEndTop);

// If the segment is very close to the XZ plane, nudge the vertices slightly to avoid touching it.
nudgeXZ(adjustHeightStartBottom, adjustHeightEndBottom);
nudgeXZ(adjustHeightStartTop, adjustHeightEndTop);
@@ -880,6 +924,17 @@ define([
Cartesian3.pack(adjustHeightEndTop, positionsArray, vec3sWriteIndex + 6);
Cartesian3.pack(adjustHeightStartTop, positionsArray, vec3sWriteIndex + 9);

// Nudge in opposite direction
normalNudge = Cartesian3.multiplyByScalar(rightNormal, -2.0 * CesiumMath.EPSILON5, normalNudgeScratch);
Cartesian3.add(adjustHeightStartBottom, normalNudge, adjustHeightStartBottom);
Cartesian3.add(adjustHeightEndBottom, normalNudge, adjustHeightEndBottom);
Cartesian3.add(adjustHeightStartTop, normalNudge, adjustHeightStartTop);
Cartesian3.add(adjustHeightEndTop, normalNudge, adjustHeightEndTop);

// Check against XZ plane again
nudgeXZ(adjustHeightStartBottom, adjustHeightEndBottom);
nudgeXZ(adjustHeightStartTop, adjustHeightEndTop);

Cartesian3.pack(adjustHeightStartBottom, positionsArray, vec3sWriteIndex + 12);
Cartesian3.pack(adjustHeightEndBottom, positionsArray, vec3sWriteIndex + 15);
Cartesian3.pack(adjustHeightEndTop, positionsArray, vec3sWriteIndex + 18);
@@ -893,7 +948,7 @@ define([
vec4sWriteIndex += 32;

lengthSoFar3D += segmentLength3D;
lengthSoFar2D = segmentLength2D;
lengthSoFar2D += segmentLength2D;
}

/*** Generate indices ***/