-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Added terrain drawing sandcastle example #6692
Changes from 10 commits
b6a1068
bf07321
5c39a4b
137398d
38a2a3a
2b49eda
7acde7a
eb4db3f
d1b8b64
17e9447
ee49788
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> | ||
<meta name="description" content="Draw lines and polygons on terrain with mouse clicks."> | ||
<meta name="cesium-sandcastle-labels" content="Showcases"> | ||
<title>Cesium Demo</title> | ||
<script type="text/javascript" src="../Sandcastle-header.js"></script> | ||
<script type="text/javascript" src="../../../ThirdParty/requirejs-2.1.20/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"> | ||
<table class="infoPanel"> | ||
<tbody> | ||
<tr> | ||
<td>Left click to add a vertex.</td> | ||
</tr> | ||
<tr> | ||
<td>Right click to start new shape.</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
</div> | ||
<script id="cesium_sandcastle_script"> | ||
function startup(Cesium) { | ||
'use strict'; | ||
//Sandcastle_Begin | ||
var viewer = new Cesium.Viewer('cesiumContainer', { | ||
selectionIndicator : false, | ||
infoBox : false, | ||
terrainProvider : Cesium.createWorldTerrain() | ||
}); | ||
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); | ||
function createPoint(worldPosition) { | ||
var point = viewer.entities.add({ | ||
position : worldPosition, | ||
point : { | ||
color : Cesium.Color.WHITE, | ||
pixelSize : 5, | ||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND | ||
} | ||
}); | ||
return point; | ||
} | ||
var drawingMode = 'line'; | ||
function drawShape(positionData) { | ||
var shape; | ||
if (drawingMode === 'line') { | ||
shape = viewer.entities.add({ | ||
polyline : { | ||
positions : positionData, | ||
clampToGround : true, | ||
width : 3 | ||
} | ||
}); | ||
} | ||
else if (drawingMode === 'polygon') { | ||
shape = viewer.entities.add({ | ||
polygon: { | ||
hierarchy: positionData, | ||
outline: true, | ||
material: new Cesium.ColorMaterialProperty(Cesium.Color.WHITE.withAlpha(0.7)) | ||
} | ||
}); | ||
} | ||
return shape; | ||
} | ||
var activeShapePoints = []; | ||
var activeShape; | ||
var floatingPoint; | ||
var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas); | ||
handler.setInputAction(function(event) { | ||
// We use `viewer.scene.pickPosition` here instead of `viewer.camera.pickEllipsoid` so that | ||
// we get the correct point when mousing over terrain. | ||
var earthPosition = viewer.scene.pickPosition(event.position); | ||
// `earthPosition` will be undefined if our mouse is not over the globe. | ||
if (Cesium.defined(earthPosition)) { | ||
if (activeShapePoints.length === 0) { | ||
floatingPoint = createPoint(earthPosition); | ||
activeShapePoints.push(earthPosition); | ||
var dynamicPositions = new Cesium.CallbackProperty(function () { | ||
return activeShapePoints; | ||
}, false); | ||
activeShape = drawShape(dynamicPositions); | ||
} | ||
activeShapePoints.push(earthPosition); | ||
createPoint(earthPosition); | ||
} | ||
}, Cesium.ScreenSpaceEventType.LEFT_CLICK); | ||
|
||
handler.setInputAction(function(event) { | ||
if (Cesium.defined(floatingPoint)) { | ||
var newPosition = viewer.scene.pickPosition(event.endPosition); | ||
if (Cesium.defined(newPosition)) { | ||
floatingPoint.position.setValue(newPosition); | ||
activeShapePoints.pop(); | ||
activeShapePoints.push(newPosition); | ||
} | ||
} | ||
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE); | ||
// Redraw the shape so it's not dynamic and remove the dynamic shape. | ||
function terminateShape() { | ||
activeShapePoints.pop(); | ||
drawShape(activeShapePoints); | ||
viewer.entities.remove(floatingPoint); | ||
viewer.entities.remove(activeShape); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The shapes flash when you terminate the shape. Is it possible to re-use the same entity and create the position property, or do we have to delete the old one and create a new dynamic one? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just tested that out, and it'll still take a few seconds to render when you switch the I talked briefly with @mramato about this. We could do any of the following to remove that flicker:
But none of those seem like good practices we want to encourage in an official Sandcastle example. It might be nice to have a "flush" command that would try to immediately render an entity. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a long standing issue in "sometimes changing" geometry data in Cesium. I recommend this PR keeps whatever is cleanest for example code. I would love to see us improve interactive geometry like this, but it's probably going to result in a request-render style method for entities that needs to be thought through. |
||
floatingPoint = undefined; | ||
activeShape = undefined; | ||
activeShapePoints = []; | ||
} | ||
handler.setInputAction(function(event) { | ||
terminateShape(); | ||
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK); | ||
|
||
var options = [{ | ||
text : 'Draw Lines', | ||
onselect : function() { | ||
terminateShape(); | ||
drawingMode = 'line'; | ||
} | ||
}, { | ||
text : 'Draw Polygons', | ||
onselect : function() { | ||
terminateShape(); | ||
drawingMode = 'polygon'; | ||
} | ||
}]; | ||
|
||
Sandcastle.addToolbarMenu(options); | ||
// Zoom in to an area with mountains | ||
viewer.camera.lookAt(Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0), new Cesium.Cartesian3(5000.0, 5000.0, 5000.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> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be combined with the above if statement.
if (Cesium.defined(earthPosition) && activeShapePoints.length === 0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's actually a couple of things that happen even if
activeShapePoints.length != 0
that's why it's 2 statements.