Skip to content

Commit

Permalink
Merge pull request #6717 from AnalyticalGraphicsInc/entity-geometry-h…
Browse files Browse the repository at this point in the history
…eight-reference

Height Reference for Corridor, Ellipse, Polygon and Rectangle
  • Loading branch information
mramato authored Jun 29, 2018
2 parents 4ddc4c6 + 04a8259 commit 11ea6b0
Show file tree
Hide file tree
Showing 25 changed files with 1,307 additions and 158 deletions.
102 changes: 102 additions & 0 deletions Apps/Sandcastle/gallery/Geometry Height Reference.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<!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="An example for how to use the GeometryHeightProperty to height reference a corridor, ellipse, polygon or rectangle.">
<meta name="cesium-sandcastle-labels" content="Geometries">
<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">
if(typeof require === "function") {
require.config({
baseUrl : '../../../Source',
waitSeconds : 120
});
}
</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
var cesiumTerrainProvider = Cesium.createWorldTerrain();
var ellipsoidTerrainProvider = new Cesium.EllipsoidTerrainProvider();

var viewer = new Cesium.Viewer('cesiumContainer', {
baseLayerPicker : false,
terrainProvider : cesiumTerrainProvider
});

// depth test against terrain is required to make the polygons clamp to terrain
// instead of showing through it from underground
viewer.scene.globe.depthTestAgainstTerrain = true;

Sandcastle.addToolbarMenu([{
text : 'Terrain Enabled',
onselect : function() {
viewer.scene.terrainProvider = cesiumTerrainProvider;
}
}, {
text : 'Terrain Disabled',
onselect : function() {
viewer.scene.terrainProvider = ellipsoidTerrainProvider;
}
}]);

var longitude = 6.850615989890521;
var latitude = 45.89546589994886;
var delta = 0.001;

function addEntity(i, j) {
var west = longitude + delta * i;
var east = longitude + delta * i + delta;

var south = latitude + delta * j;
var north = latitude + delta * j + delta;
var a = Cesium.Cartesian3.fromDegrees(west, south);
var b = Cesium.Cartesian3.fromDegrees(west, north);
var c = Cesium.Cartesian3.fromDegrees(east, north);
var d = Cesium.Cartesian3.fromDegrees(east, south);

var positions = [a, b, c, d];
viewer.entities.add({
polygon : {
hierarchy : positions,
material : Cesium.Color.fromRandom({alpha : 1}),
height : 40.0,
heightReference : Cesium.HeightReference.RELATIVE_TO_GROUND,
extrudedHeight : 0.0,
extrudedHeightReference : Cesium.HeightReference.CLAMP_TO_GROUND
}
});
}

// create 16 polygons that are side-by-side
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
addEntity(i, j);
}
}

viewer.camera.lookAt(Cesium.Cartesian3.fromDegrees(longitude, latitude, 500), new Cesium.HeadingPitchRange(Cesium.Math.PI, -Cesium.Math.PI_OVER_FOUR, 2000));
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>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ Change Log
* Requires depth texture support (`WEBGL_depth_texture` or `WEBKIT_WEBGL_depth_texture`), otherwise `clampToGround` will be ignored. Use `Entity.supportsPolylinesOnTerrain` to check for support.
* Added `GroundPolylinePrimitive` and `GroundPolylineGeometry`.
* `PostProcessStage` has a `selected` property which is an array of primitives used for selectively applying a post-process stage. [#6476](https://github.com/AnalyticalGraphicsInc/cesium/pull/6476)
* The `PostProcessStageLibrary.createBlackAndWhiteStage` and `PostProcessStageLibrary.createSilhouetteStage` have per-feature support.
* The `PostProcessStageLibrary.createBlackAndWhiteStage` and `PostProcessStageLibrary.createSilhouetteStage` have per-feature support.
* Added CZML support for `zIndex` for `corridor`, `ellipse`, `polygon`, `polyline` and `rectangle`. [#6708](https://github.com/AnalyticalGraphicsInc/cesium/pull/6708)
* Added CZML `clampToGround` option for `polyline`. [#6706](https://github.com/AnalyticalGraphicsInc/cesium/pull/6706)
* Added `heightReference` and `extrudedHeightReference` properties to `CorridorGraphics`, `EllipseGraphics`, `PolygonGraphics` and `RectangleGraphics`. [#6717](https://github.com/AnalyticalGraphicsInc/cesium/pull/6717)
* This can be used in conjunction with the `height` and/or `extrudedHeight` properties to clamp the geometry to terrain or set the height relative to terrain.
* Note, this will not make the geometry conform to terrain. Extruded geoemtry that is clamped to the ground will have a flat top will sinks into the terrain at the base.

##### Fixes :wrench:
* Fixed a bug that caused Cesium to be unable to load local resources in Electron. [#6726](https://github.com/AnalyticalGraphicsInc/cesium/pull/6726)
Expand Down
110 changes: 77 additions & 33 deletions Source/DataSources/CorridorGeometryUpdater.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
define([
'../Core/ApproximateTerrainHeights',
'../Core/Cartesian3',
'../Core/Check',
'../Core/Color',
'../Core/ColorGeometryInstanceAttribute',
Expand All @@ -8,9 +10,13 @@ define([
'../Core/DeveloperError',
'../Core/DistanceDisplayConditionGeometryInstanceAttribute',
'../Core/GeometryInstance',
'../Core/GeometryOffsetAttribute',
'../Core/Iso8601',
'../Core/OffsetGeometryInstanceAttribute',
'../Core/Rectangle',
'../Core/ShowGeometryInstanceAttribute',
'../Scene/GroundPrimitive',
'../Scene/HeightReference',
'../Scene/MaterialAppearance',
'../Scene/PerInstanceColorAppearance',
'./ColorMaterialProperty',
Expand All @@ -19,6 +25,8 @@ define([
'./GroundGeometryUpdater',
'./Property'
], function(
ApproximateTerrainHeights,
Cartesian3,
Check,
Color,
ColorGeometryInstanceAttribute,
Expand All @@ -28,9 +36,13 @@ define([
DeveloperError,
DistanceDisplayConditionGeometryInstanceAttribute,
GeometryInstance,
GeometryOffsetAttribute,
Iso8601,
OffsetGeometryInstanceAttribute,
Rectangle,
ShowGeometryInstanceAttribute,
GroundPrimitive,
HeightReference,
MaterialAppearance,
PerInstanceColorAppearance,
ColorMaterialProperty,
Expand All @@ -41,6 +53,9 @@ define([
'use strict';

var scratchColor = new Color();
var defaultOffset = Cartesian3.ZERO;
var offsetScratch = new Cartesian3();
var scratchRectangle = new Rectangle();

function CorridorGeometryOptions(entity) {
this.id = entity;
Expand All @@ -51,6 +66,7 @@ define([
this.height = undefined;
this.extrudedHeight = undefined;
this.granularity = undefined;
this.offsetAttribute = undefined;
}

/**
Expand Down Expand Up @@ -99,11 +115,13 @@ define([
var entity = this._entity;
var isAvailable = entity.isAvailable(time);

var attributes;
var attributes = {
show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time)),
distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(this._distanceDisplayConditionProperty.getValue(time)),
offset : undefined,
color : undefined
};

var color;
var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time));
var distanceDisplayCondition = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(this._distanceDisplayConditionProperty.getValue(time));
if (this._materialProperty instanceof ColorMaterialProperty) {
var currentColor;
if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) {
Expand All @@ -112,17 +130,11 @@ define([
if (!defined(currentColor)) {
currentColor = Color.WHITE;
}
color = ColorGeometryInstanceAttribute.fromColor(currentColor);
attributes = {
show : show,
distanceDisplayCondition : distanceDisplayCondition,
color : color
};
} else {
attributes = {
show : show,
distanceDisplayCondition : distanceDisplayCondition
};
attributes.color = ColorGeometryInstanceAttribute.fromColor(currentColor);
}

if (defined(this._options.offsetAttribute)) {
attributes.offset = OffsetGeometryInstanceAttribute.fromCartesian3(Property.getValueOrDefault(this._terrainOffsetProperty, time, defaultOffset, offsetScratch));
}

return new GeometryInstance({
Expand Down Expand Up @@ -153,19 +165,34 @@ define([
var isAvailable = entity.isAvailable(time);
var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK, scratchColor);

var attributes = {
show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)),
color : ColorGeometryInstanceAttribute.fromColor(outlineColor),
distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(this._distanceDisplayConditionProperty.getValue(time)),
offset : undefined
};

if (defined(this._options.offsetAttribute)) {
attributes.offset = OffsetGeometryInstanceAttribute.fromCartesian3(Property.getValueOrDefault(this._terrainOffsetProperty, time, defaultOffset, offsetScratch));
}

return new GeometryInstance({
id : entity,
geometry : new CorridorOutlineGeometry(this._options),
attributes : {
show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)),
color : ColorGeometryInstanceAttribute.fromColor(outlineColor),
distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(this._distanceDisplayConditionProperty.getValue(time))
}
attributes : attributes
});
};

CorridorGeometryUpdater.prototype._computeCenter = function(time, result) {
var positions = Property.getValueOrUndefined(this._entity.corridor.positions, time);
if (!defined(positions) || positions.length === 0) {
return;
}
return Cartesian3.clone(positions[Math.floor(positions.length / 2.0)], result);
};

CorridorGeometryUpdater.prototype._isHidden = function(entity, corridor) {
return !defined(corridor.positions) || GeometryUpdater.prototype._isHidden.call(this, entity, corridor);
return !defined(corridor.positions) || !defined(corridor.width) || GeometryUpdater.prototype._isHidden.call(this, entity, corridor);
};

CorridorGeometryUpdater.prototype._isOnTerrain = function(entity, corridor) {
Expand Down Expand Up @@ -193,20 +220,25 @@ define([

CorridorGeometryUpdater.prototype._setStaticOptions = function(entity, corridor) {
var height = corridor.height;
var heightReference = corridor.heightReference;
var extrudedHeight = corridor.extrudedHeight;
var granularity = corridor.granularity;
var width = corridor.width;
var cornerType = corridor.cornerType;
var isColorMaterial = this._materialProperty instanceof ColorMaterialProperty;
var extrudedHeightReference = corridor.extrudedHeightReference;

var options = this._options;
options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat;
options.vertexFormat = (this._materialProperty instanceof ColorMaterialProperty) ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat;
options.positions = corridor.positions.getValue(Iso8601.MINIMUM_VALUE, options.positions);
options.height = defined(height) ? height.getValue(Iso8601.MINIMUM_VALUE) : undefined;
options.extrudedHeight = defined(extrudedHeight) ? extrudedHeight.getValue(Iso8601.MINIMUM_VALUE) : undefined;
options.granularity = defined(granularity) ? granularity.getValue(Iso8601.MINIMUM_VALUE) : undefined;
options.width = defined(width) ? width.getValue(Iso8601.MINIMUM_VALUE) : undefined;
options.cornerType = defined(cornerType) ? cornerType.getValue(Iso8601.MINIMUM_VALUE) : undefined;
options.width = corridor.width.getValue(Iso8601.MINIMUM_VALUE);
options.granularity = Property.getValueOrUndefined(corridor.granularity, Iso8601.MINIMUM_VALUE);
options.cornerType = Property.getValueOrUndefined(corridor.cornerType, Iso8601.MINIMUM_VALUE);
options.offsetAttribute = GroundGeometryUpdater.computeGeometryOffsetAttribute(heightReference, extrudedHeightReference, Iso8601.MINIMUM_VALUE);
options.height = GroundGeometryUpdater.getGeometryHeight(height, heightReference, Iso8601.MINIMUM_VALUE);

var extrudedHeightValue = GroundGeometryUpdater.getGeometryExtrudedHeight(extrudedHeight, extrudedHeightReference, Iso8601.MINIMUM_VALUE);
if (extrudedHeightValue === GroundGeometryUpdater.CLAMP_TO_GROUND) {
extrudedHeightValue = ApproximateTerrainHeights.getApproximateTerrainHeights(CorridorGeometry.computeRectangle(options, scratchRectangle)).minimumTerrainHeight;
}

options.extrudedHeight = extrudedHeightValue;
};

CorridorGeometryUpdater.DynamicGeometryUpdater = DynamicCorridorGeometryUpdater;
Expand All @@ -230,12 +262,24 @@ define([

DynamicCorridorGeometryUpdater.prototype._setOptions = function(entity, corridor, time) {
var options = this._options;
var height = corridor.height;
var heightReference = corridor.heightReference;
var extrudedHeight = corridor.extrudedHeight;
var extrudedHeightReference = corridor.extrudedHeightReference;

options.positions = Property.getValueOrUndefined(corridor.positions, time);
options.width = Property.getValueOrUndefined(corridor.width, time);
options.height = Property.getValueOrUndefined(corridor.height, time);
options.extrudedHeight = Property.getValueOrUndefined(corridor.extrudedHeight, time);
options.granularity = Property.getValueOrUndefined(corridor.granularity, time);
options.cornerType = Property.getValueOrUndefined(corridor.cornerType, time);
options.offsetAttribute = GroundGeometryUpdater.computeGeometryOffsetAttribute(heightReference, extrudedHeightReference, time);
options.height = GroundGeometryUpdater.getGeometryHeight(height, heightReference, time);

var extrudedHeightValue = GroundGeometryUpdater.getGeometryExtrudedHeight(extrudedHeight, extrudedHeightReference, time);
if (extrudedHeightValue === GroundGeometryUpdater.CLAMP_TO_GROUND) {
extrudedHeightValue = ApproximateTerrainHeights.getApproximateTerrainHeights(CorridorGeometry.computeRectangle(options, scratchRectangle)).minimumTerrainHeight;
}

options.extrudedHeight = extrudedHeightValue;
};

return CorridorGeometryUpdater;
Expand Down
26 changes: 26 additions & 0 deletions Source/DataSources/CorridorGraphics.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ define([
* @param {Property} [options.width] A numeric Property specifying the distance between the edges of the corridor.
* @param {Property} [options.cornerType=CornerType.ROUNDED] A {@link CornerType} Property specifying the style of the corners.
* @param {Property} [options.height=0] A numeric Property specifying the altitude of the corridor relative to the ellipsoid surface.
* @param {Property} [options.heightReference] A Property specifying what the height is relative to.
* @param {Property} [options.extrudedHeight] A numeric Property specifying the altitude of the corridor's extruded face relative to the ellipsoid surface.
* @param {Property} [options.extrudedHeightReference] A Property specifying what the extrudedHeight is relative to.
* @param {Property} [options.show=true] A boolean Property specifying the visibility of the corridor.
* @param {Property} [options.fill=true] A boolean Property specifying whether the corridor is filled with the provided material.
* @param {MaterialProperty} [options.material=Color.WHITE] A Property specifying the material used to fill the corridor.
Expand All @@ -53,8 +55,12 @@ define([
this._positionsSubscription = undefined;
this._height = undefined;
this._heightSubscription = undefined;
this._heightReference = undefined;
this._heightReferenceSubscription = undefined;
this._extrudedHeight = undefined;
this._extrudedHeightSubscription = undefined;
this._extrudedHeightReference = undefined;
this._extrudedHeightReferenceSubscription = undefined;
this._granularity = undefined;
this._granularitySubscription = undefined;
this._width = undefined;
Expand Down Expand Up @@ -126,6 +132,14 @@ define([
*/
height : createPropertyDescriptor('height'),

/**
* Gets or sets the Property specifying the {@link HeightReference}.
* @memberof CorridorGraphics.prototype
* @type {Property}
* @default HeightReference.NONE
*/
heightReference : createPropertyDescriptor('heightReference'),

/**
* Gets or sets the numeric Property specifying the altitude of the corridor extrusion.
* Setting this property creates a corridor shaped volume starting at height and ending
Expand All @@ -135,6 +149,14 @@ define([
*/
extrudedHeight : createPropertyDescriptor('extrudedHeight'),

/**
* Gets or sets the Property specifying the extruded {@link HeightReference}.
* @memberof CorridorGraphics.prototype
* @type {Property}
* @default HeightReference.NONE
*/
extrudedHeightReference : createPropertyDescriptor('extrudedHeightReference'),

/**
* Gets or sets the numeric Property specifying the sampling distance between each latitude and longitude point.
* @memberof CorridorGraphics.prototype
Expand Down Expand Up @@ -237,7 +259,9 @@ define([
result.material = this.material;
result.positions = this.positions;
result.height = this.height;
result.heightReference = this.heightReference;
result.extrudedHeight = this.extrudedHeight;
result.extrudedHeightReference = this.extrudedHeightReference;
result.granularity = this.granularity;
result.width = this.width;
result.fill = this.fill;
Expand Down Expand Up @@ -269,7 +293,9 @@ define([
this.material = defaultValue(this.material, source.material);
this.positions = defaultValue(this.positions, source.positions);
this.height = defaultValue(this.height, source.height);
this.heightReference = defaultValue(this.heightReference, source.heightReference);
this.extrudedHeight = defaultValue(this.extrudedHeight, source.extrudedHeight);
this.extrudedHeightReference = defaultValue(this.extrudedHeightReference, source.extrudedHeightReference);
this.granularity = defaultValue(this.granularity, source.granularity);
this.width = defaultValue(this.width, source.width);
this.fill = defaultValue(this.fill, source.fill);
Expand Down
Loading

0 comments on commit 11ea6b0

Please sign in to comment.