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

Polygon on Terrain #2618

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
65 changes: 65 additions & 0 deletions Apps/Sandcastle/gallery/development/Ground Polygon.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> <!-- Use Chrome Frame in IE -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<meta name="description" content="Draw a polygon or extruded polygon on the globe surface.">
<meta name="cesium-sandcastle-labels" content="Development">
<title>Cesium Demo</title>
<script type="text/javascript" src="../Sandcastle-header.js"></script>
<script type="text/javascript" src="../../../ThirdParty/requirejs-2.1.9/require.js"></script>
<script type="text/javascript">
require.config({
baseUrl : '../../../Source',
waitSeconds : 60
});
</script>
</head>
<body class="sandcastle-loading" data-sandcastle-bucket="bucket-requirejs.html">
<style>
@import url(../templates/bucket.css);
</style>
<div id="cesiumContainer" class="fullSize"></div>
<div id="loadingOverlay"><h1>Loading...</h1></div>
<div id="toolbar"></div>
<script id="cesium_sandcastle_script">
function startup(Cesium) {
"use strict";
//Sandcastle_Begin

//Create the viewer.
var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene;
scene.terrainProvider = new Cesium.CesiumTerrainProvider({
url: '//cesiumjs.org/stk-terrain/tilesets/world/tiles',
requestVertexNormals : true
});
scene.globe.depthTestAgainstTerrain = true;

var positions = [new Cesium.Cartesian3(-2358138.847340281, -3744072.459541374, 4581158.5714175375),
new Cesium.Cartesian3(-2357231.4925370603, -3745103.7886602185, 4580702.9757762635),
new Cesium.Cartesian3(-2355912.902205431, -3744249.029778454, 4582402.154378103),
new Cesium.Cartesian3(-2357208.0209552636, -3743553.4420488174, 4581961.863286629)];

var polygonHierarchy = { positions : positions };

var groundPolygon = scene.primitives.add(new Cesium.GroundPolygon({
//debugVolume : true,
polygonHierarchy : polygonHierarchy
}));

viewer.camera.lookAt(new Cesium.Cartesian3(-2354331.3069306486, -3742016.2427205616, 4581875.591571755), new Cesium.HeadingPitchRange(Cesium.Math.toRadians(20.0), Cesium.Math.toRadians(-35.0), 10000.0));
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);

//Sandcastle_End
Sandcastle.finishedLoading();
}
if (typeof Cesium !== "undefined") {
startup(Cesium);
} else if (typeof require === "function") {
require(["Cesium"], startup);
}
</script>
</body>
</html>
217 changes: 11 additions & 206 deletions Source/Core/PolygonGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ define([
'./Matrix3',
'./PolygonGeometryLibrary',
'./PolygonPipeline',
'./PrimitiveType',
'./Quaternion',
'./Queue',
'./VertexFormat',
'./WindingOrder'
], function(
Expand All @@ -46,9 +44,7 @@ define([
Matrix3,
PolygonGeometryLibrary,
PolygonPipeline,
PrimitiveType,
Quaternion,
Queue,
VertexFormat,
WindingOrder) {
"use strict";
Expand Down Expand Up @@ -89,55 +85,6 @@ define([
return result;
}

var createGeometryFromPositionsPositions = [];

function createGeometryFromPositions(ellipsoid, positions, granularity, perPositionHeight) {
var tangentPlane = EllipsoidTangentPlane.fromPoints(positions, ellipsoid);
var positions2D = tangentPlane.projectPointsOntoPlane(positions, createGeometryFromPositionsPositions);

var originalWindingOrder = PolygonPipeline.computeWindingOrder2D(positions2D);
if (originalWindingOrder === WindingOrder.CLOCKWISE) {
positions2D.reverse();
positions.reverse();
}

var indices = PolygonPipeline.triangulate(positions2D);
/* If polygon is completely unrenderable, just use the first three vertices */
if (indices.length < 3) {
indices = [0, 1, 2];
}

var geo;
if (!perPositionHeight) {
geo = PolygonPipeline.computeSubdivision(ellipsoid, positions, indices, granularity);
} else {
var length = positions.length;
var flattenedPositions = new Array(length * 3);
var index = 0;
for ( var i = 0; i < length; i++) {
var p = positions[i];
flattenedPositions[index++] = p.x;
flattenedPositions[index++] = p.y;
flattenedPositions[index++] = p.z;
}
geo = new Geometry({
attributes : {
position : new GeometryAttribute({
componentDatatype : ComponentDatatype.DOUBLE,
componentsPerAttribute : 3,
values : flattenedPositions
})
},
indices : indices,
primitiveType : PrimitiveType.TRIANGLES
});
}

return new GeometryInstance({
geometry : geo
});
}

var scratchBoundingRectangle = new BoundingRectangle();
var scratchPosition = new Cartesian3();
var scratchNormal = new Cartesian3();
Expand Down Expand Up @@ -329,114 +276,10 @@ define([
return geometry;
}

var computeWallIndicesSubdivided = [];

function computeWallIndices(positions, ellipsoid, granularity, perPositionHeight){
var edgePositions;
var topEdgeLength;
var i;
var p1;
var p2;

var length = positions.length;
var index = 0;

if (!perPositionHeight) {
var minDistance = CesiumMath.chordLength(granularity, ellipsoid.maximumRadius);

var numVertices = 0;
for (i = 0; i < length; i++) {
numVertices += PolygonGeometryLibrary.subdivideLineCount(positions[i], positions[(i + 1) % length], minDistance);
}

topEdgeLength = (numVertices + length) * 3;
edgePositions = new Array(topEdgeLength * 2);
for (i = 0; i < length; i++) {
p1 = positions[i];
p2 = positions[(i + 1) % length];

var tempPositions = PolygonGeometryLibrary.subdivideLine(p1, p2, minDistance, computeWallIndicesSubdivided);
var tempPositionsLength = tempPositions.length;
for (var j = 0; j < tempPositionsLength; ++j, ++index) {
edgePositions[index] = tempPositions[j];
edgePositions[index + topEdgeLength] = tempPositions[j];
}

edgePositions[index] = p2.x;
edgePositions[index + topEdgeLength] = p2.x;
++index;

edgePositions[index] = p2.y;
edgePositions[index + topEdgeLength] = p2.y;
++index;

edgePositions[index] = p2.z;
edgePositions[index + topEdgeLength] = p2.z;
++index;
}
} else {
topEdgeLength = length * 3 * 2;
edgePositions = new Array(topEdgeLength * 2);
for (i = 0; i < length; i++) {
p1 = positions[i];
p2 = positions[(i + 1) % length];
edgePositions[index] = edgePositions[index + topEdgeLength] = p1.x;
++index;
edgePositions[index] = edgePositions[index + topEdgeLength] = p1.y;
++index;
edgePositions[index] = edgePositions[index + topEdgeLength] = p1.z;
++index;
edgePositions[index] = edgePositions[index + topEdgeLength] = p2.x;
++index;
edgePositions[index] = edgePositions[index + topEdgeLength] = p2.y;
++index;
edgePositions[index] = edgePositions[index + topEdgeLength] = p2.z;
++index;
}
}

length = edgePositions.length;
var indices = IndexDatatype.createTypedArray(length / 3, length - positions.length * 6);
var edgeIndex = 0;
length /= 6;

for (i = 0; i < length; i++) {
var UL = i;
var UR = UL + 1;
var LL = UL + length;
var LR = LL + 1;

p1 = Cartesian3.fromArray(edgePositions, UL * 3, p1Scratch);
p2 = Cartesian3.fromArray(edgePositions, UR * 3, p2Scratch);
if (Cartesian3.equalsEpsilon(p1, p2, CesiumMath.EPSILON14)) {
continue;
}

indices[edgeIndex++] = UL;
indices[edgeIndex++] = LL;
indices[edgeIndex++] = UR;
indices[edgeIndex++] = UR;
indices[edgeIndex++] = LL;
indices[edgeIndex++] = LR;
}

return new Geometry({
attributes : new GeometryAttributes({
position : new GeometryAttribute({
componentDatatype : ComponentDatatype.DOUBLE,
componentsPerAttribute : 3,
values : edgePositions
})
}),
indices : indices,
primitiveType : PrimitiveType.TRIANGLES
});
}

var createGeometryFromPositionsExtrudedPositions = [];

function createGeometryFromPositionsExtruded(ellipsoid, positions, granularity, hierarchy, perPositionHeight) {
var topGeo = createGeometryFromPositions(ellipsoid, positions, granularity, perPositionHeight).geometry;
var topGeo = PolygonGeometryLibrary.createGeometryFromPositions(ellipsoid, positions, granularity, perPositionHeight);

var edgePoints = topGeo.attributes.position.values;
var indices = topGeo.indices;
Expand Down Expand Up @@ -489,7 +332,7 @@ define([
outerRing.reverse();
}

var wallGeo = computeWallIndices(outerRing, ellipsoid, granularity, perPositionHeight);
var wallGeo = PolygonGeometryLibrary.computeWallGeometry(outerRing, ellipsoid, granularity, perPositionHeight);
geos.walls.push(new GeometryInstance({
geometry : wallGeo
}));
Expand All @@ -506,7 +349,7 @@ define([
hole.reverse();
}

wallGeo = computeWallIndices(hole, ellipsoid, granularity);
wallGeo = PolygonGeometryLibrary.computeWallGeometry(hole, ellipsoid, granularity);
geos.walls.push(new GeometryInstance({
geometry : wallGeo
}));
Expand Down Expand Up @@ -812,50 +655,9 @@ define([
var topAndBottom;
var outerPositions;

// create from a polygon hierarchy
// Algorithm adapted from http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
var polygons = [];
var queue = new Queue();
queue.enqueue(polygonHierarchy);
polygonHierarchy = [];
var i;
while (queue.length !== 0) {
var outerNode = queue.dequeue();
var outerRing = outerNode.positions;
var holes = outerNode.holes;
outerRing = PolygonPipeline.removeDuplicates(outerRing);
if (outerRing.length < 3) {
continue;
}

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;
}

for ( var j = 0; j < numGrandchildren; j++) {
queue.enqueue(hole.holes[j]);
}
}

polygonHierarchy.push({
outerRing : outerRing,
holes : polygonHoles
});

var combinedPolygon = polygonHoles.length > 0 ? PolygonPipeline.eliminateHoles(outerRing, polygonHoles) : outerRing;
polygons.push(combinedPolygon);
}
var results = PolygonGeometryLibrary.polygonsFromHierarchy(polygonHierarchy);
var hierarchy = results.hierarchy;
var polygons = results.polygons;

if (polygons.length === 0) {
return undefined;
Expand All @@ -865,10 +667,11 @@ define([

var geometry;
var geometries = [];
var i;

if (extrude) {
for (i = 0; i < polygons.length; i++) {
geometry = createGeometryFromPositionsExtruded(ellipsoid, polygons[i], granularity, polygonHierarchy[i], perPositionHeight);
geometry = createGeometryFromPositionsExtruded(ellipsoid, polygons[i], granularity, hierarchy[i], perPositionHeight);
topAndBottom = geometry.topAndBottom;
topAndBottom.geometry = PolygonGeometryLibrary.scaleToGeodeticHeightExtruded(topAndBottom.geometry, height, extrudedHeight, ellipsoid, perPositionHeight);
topAndBottom.geometry = computeAttributes(vertexFormat, topAndBottom.geometry, outerPositions, ellipsoid, stRotation, true, false);
Expand All @@ -884,7 +687,9 @@ define([
}
} else {
for (i = 0; i < polygons.length; i++) {
geometry = createGeometryFromPositions(ellipsoid, polygons[i], granularity, perPositionHeight);
geometry = new GeometryInstance({
geometry : PolygonGeometryLibrary.createGeometryFromPositions(ellipsoid, polygons[i], granularity, perPositionHeight)
});
geometry.geometry = PolygonPipeline.scaleToGeodeticHeight(geometry.geometry, height, ellipsoid, !perPositionHeight);
geometry.geometry = computeAttributes(vertexFormat, geometry.geometry, outerPositions, ellipsoid, stRotation, false, false);
geometries.push(geometry);
Expand Down
Loading