Skip to content

Commit

Permalink
Merge pull request #2960 from AnalyticalGraphicsInc/z-ordering
Browse files Browse the repository at this point in the history
Z-Ordering
  • Loading branch information
pjcozzi committed Aug 24, 2015
2 parents 640521d + c8f2bde commit 18e133c
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 134 deletions.
310 changes: 189 additions & 121 deletions Apps/Sandcastle/gallery/development/Ground Primitive.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,135 +36,203 @@
requestVertexNormals : true
});

// Circle geometry
scene.primitives.add(new Cesium.GroundPrimitive({
geometryInstance: new Cesium.GeometryInstance({
geometry : new Cesium.CircleGeometry({
center : Cesium.Cartesian3.fromDegrees(-95.0, 45.0),
radius : 250000.0
}),
attributes : {
color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 0.0, 0.5))
},
id : 'circle'
})
}));

// Ellipse Geometry
scene.primitives.add(new Cesium.GroundPrimitive({
geometryInstance: new Cesium.GeometryInstance({
geometry : new Cesium.EllipseGeometry({
center : Cesium.Cartesian3.fromDegrees(-105.0, 40.0),
semiMinorAxis : 300000.0,
semiMajorAxis : 400000.0
}),
attributes : {
color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(0.0, 1.0, 1.0, 0.5))
},
id : 'ellipse'
})
}));

// Corridor Geometry
scene.primitives.add(new Cesium.GroundPrimitive({
geometryInstance : new Cesium.GeometryInstance({
geometry: new Cesium.CorridorGeometry({
positions : Cesium.Cartesian3.fromDegreesArray([
-112.0, 40.0,
-117.0, 40.0,
-117.0, 35.0
]),
width : 200000.0
function offsetPositions(positions, degreeOffset) {
positions = scene.globe.ellipsoid.cartesianArrayToCartographicArray(positions);
var delta = Cesium.Math.toRadians(degreeOffset);
for (var i = 0; i < positions.length; ++i) {
var position = positions[i];
position.latitude += delta;
position.longitude += delta;
}
return scene.globe.ellipsoid.cartographicArrayToCartesianArray(positions);
}

function createOverlappingPolygons(withAlpha) {
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 color = Cesium.Color.RED;
if (withAlpha) {
color = color.withAlpha(0.5);
}

scene.groundPrimitives.add(new Cesium.GroundPrimitive({
geometryInstance : new Cesium.GeometryInstance({
geometry : new Cesium.PolygonGeometry({
polygonHierarchy : polygonHierarchy
}),
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(color)
},
id : 'polygon 1'
})
}));

// Same polygon slightly offset and overlapping.
var positionsOffset = offsetPositions(positions, 0.01);
polygonHierarchy = { positions : positionsOffset };

color = Cesium.Color.GREEN;
if (withAlpha) {
color = color.withAlpha(0.5);
}

scene.groundPrimitives.add(new Cesium.GroundPrimitive({
geometryInstance : new Cesium.GeometryInstance({
geometry : new Cesium.PolygonGeometry({
polygonHierarchy : polygonHierarchy
}),
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(color)
},
id : 'polygon 2'
})
}));

// Same polygon slightly offset and overlapping.
positionsOffset = offsetPositions(positions, -0.01);
polygonHierarchy = { positions : positionsOffset };

color = Cesium.Color.BLUE;
if (withAlpha) {
color = color.withAlpha(0.5);
}

scene.groundPrimitives.add(new Cesium.GroundPrimitive({
geometryInstance : new Cesium.GeometryInstance({
geometry : new Cesium.PolygonGeometry({
polygonHierarchy : polygonHierarchy
}),
attributes : {
color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(0.0, 0.0, 1.0, 0.5))
},
id : 'corridor'
})
}));

// Rectangle geometry
scene.primitives.add(new Cesium.GroundPrimitive({
geometryInstance : new Cesium.GeometryInstance({
geometry : new Cesium.RectangleGeometry({
rectangle : Cesium.Rectangle.fromDegrees(-100.0, 30.0, -90.0, 40.0),
rotation : Cesium.Math.toRadians(45)
}),
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(0.0, 1.0, 0.0, 0.5))
},
id : 'rectangle'
})
}));

// Polygon on Mount Saint Helens
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 primitive = scene.primitives.add(new Cesium.GroundPrimitive({
geometryInstance : new Cesium.GeometryInstance({
geometry : new Cesium.PolygonGeometry({
polygonHierarchy : polygonHierarchy
}),
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED.withAlpha(0.5))
},
id : 'polygon 1'
})
}));

// Same polygon slightly offset and overlapping.
positions = scene.globe.ellipsoid.cartesianArrayToCartographicArray(positions);
var delta = Cesium.Math.toRadians(0.01);
for (var i = 0; i < positions.length; ++i) {
var position = positions[i];
position.latitude += delta;
position.longitude += delta;
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(color)
},
id : 'polygon 3'
})
}));
}
positions = scene.globe.ellipsoid.cartographicArrayToCartesianArray(positions);
polygonHierarchy = { positions : positions };

scene.primitives.add(new Cesium.GroundPrimitive({
geometryInstance : new Cesium.GeometryInstance({
geometry : new Cesium.PolygonGeometry({
polygonHierarchy : polygonHierarchy
}),
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.BLUE.withAlpha(0.5))
},
id : 'polygon 2'
})
}));

Sandcastle.addToolbarButton('View Mount Saint Helens', function() {

function viewOverlappingPolygons() {
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);
});
}

var handler;

var currentObject = undefined;
var lastColor = undefined;
Sandcastle.addDefaultToolbarButton('Picking Example', function() {
createOverlappingPolygons(true);
viewOverlappingPolygons();

var currentObject;
var lastColor;

var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
handler.setInputAction(function(movement) {
var pickedObject = scene.pick(movement.endPosition);
if (Cesium.defined(pickedObject) && pickedObject !== currentObject) {
if (Cesium.defined(currentObject)) {
handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
handler.setInputAction(function(movement) {
var pickedObject = scene.pick(movement.endPosition);
if (Cesium.defined(pickedObject) && pickedObject !== currentObject) {
if (Cesium.defined(currentObject)) {
currentObject.primitive.getGeometryInstanceAttributes(currentObject.id).color = lastColor;
}

currentObject = pickedObject;

var attributes = currentObject.primitive.getGeometryInstanceAttributes(currentObject.id);
lastColor = attributes.color;
attributes.color = [255, 255, 0, 128];
} else if (!Cesium.defined(pickedObject) && Cesium.defined(currentObject)) {
currentObject.primitive.getGeometryInstanceAttributes(currentObject.id).color = lastColor;
currentObject = undefined;
}

currentObject = pickedObject;

var attributes = currentObject.primitive.getGeometryInstanceAttributes(currentObject.id);
lastColor = attributes.color;
attributes.color = [255, 255, 0, 128];
} else if (!Cesium.defined(pickedObject) && Cesium.defined(currentObject)) {
currentObject.primitive.getGeometryInstanceAttributes(currentObject.id).color = lastColor;
currentObject = undefined;
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
});

Sandcastle.addToolbarButton('Z-Order', function() {
createOverlappingPolygons(false);
viewOverlappingPolygons();


handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
handler.setInputAction(function(movement) {
var pickedObject = scene.pick(movement.endPosition);
if (Cesium.defined(pickedObject)) {
scene.groundPrimitives.raiseToTop(pickedObject.primitive);
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
});

Sandcastle.addToolbarButton('Create large polygons', function() {
// Circle geometry
scene.groundPrimitives.add(new Cesium.GroundPrimitive({
geometryInstance: new Cesium.GeometryInstance({
geometry : new Cesium.CircleGeometry({
center : Cesium.Cartesian3.fromDegrees(-95.0, 45.0),
radius : 250000.0
}),
attributes : {
color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 0.0, 0.5))
},
id : 'circle'
})
}));

// Ellipse Geometry
scene.groundPrimitives.add(new Cesium.GroundPrimitive({
geometryInstance: new Cesium.GeometryInstance({
geometry : new Cesium.EllipseGeometry({
center : Cesium.Cartesian3.fromDegrees(-105.0, 40.0),
semiMinorAxis : 300000.0,
semiMajorAxis : 400000.0
}),
attributes : {
color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(0.0, 1.0, 1.0, 0.5))
},
id : 'ellipse'
})
}));

// Corridor Geometry
scene.groundPrimitives.add(new Cesium.GroundPrimitive({
geometryInstance : new Cesium.GeometryInstance({
geometry: new Cesium.CorridorGeometry({
positions : Cesium.Cartesian3.fromDegreesArray([
-112.0, 40.0,
-117.0, 40.0,
-117.0, 35.0
]),
width : 200000.0
}),
attributes : {
color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(0.0, 0.0, 1.0, 0.5))
},
id : 'corridor'
})
}));

// Rectangle geometry
scene.groundPrimitives.add(new Cesium.GroundPrimitive({
geometryInstance : new Cesium.GeometryInstance({
geometry : new Cesium.RectangleGeometry({
rectangle : Cesium.Rectangle.fromDegrees(-100.0, 30.0, -90.0, 40.0),
rotation : Cesium.Math.toRadians(45)
}),
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(0.0, 1.0, 0.0, 0.5))
},
id : 'rectangle'
})
}));
});

Sandcastle.reset = function() {
scene.groundPrimitives.removeAll();
handler = handler && handler.destroy();

//Set the camera to a US centered tilted view and switch back to moving in world coordinates.
viewer.camera.lookAt(Cesium.Cartesian3.fromDegrees(-98.0, 40.0), new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0));
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
};

//Sandcastle_End
Sandcastle.finishedLoading();
Expand Down
9 changes: 9 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ Change Log
* Removed [es5-shim](https://github.com/kriskowal/es5-shim), which is no longer required by the unit tests. [#2933](https://github.com/AnalyticalGraphicsInc/cesium/pull/2945)
* Fix issue where `JulianDate` would not parse certain dates properly. [#405](https://github.com/AnalyticalGraphicsInc/cesium/issues/405)
* Added support for `GroundPrimitive` which works much like `Primitive` but it drapes the geometry over terrain. Valid geometries that can be draped on terrain are `CircleGeometry`, `CorridorGeometry`, `EllipseGeometry`, `PolygonGeometry`, and `RectangleGeometry`.
* Added `Scene.groundPrimitives`, which is a primitive collection like `Scene.primitives`, but for `GroundPrimitive`s. Use for correct z-ordering. For example:

// draws the ellipse on top of the rectangle
var ellipse = scene.groundPrimitives.add(new Cesium.GroundPrimitive({...}));
var rectangle = scene.groundPrimitives.add(new Cesium.GroundPrimitive({...}));

// move the rectangle to draw on top of the ellipse
scene.groundPrimitives.raise(rectangle);

* Added `BoundingSphere.isOccluded` and `OrientedBoundingBox.isOccluded` to determine if the volumes are occluded by an `Occluder`.
* Added `distanceSquaredTo` and `computePlaneDistances` functions to `OrientedBoundingBox`.
* Added `reverseZ` tag to `UrlTemplateImageryProvider`.
Expand Down
16 changes: 16 additions & 0 deletions Source/Scene/Scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ define([
this._context = context;
this._globe = undefined;
this._primitives = new PrimitiveCollection();
this._groundPrimitives = new PrimitiveCollection();

this._tweens = new TweenCollection();

Expand Down Expand Up @@ -637,6 +638,19 @@ define([
}
},

/**
* Gets the collection of ground primitives.
* @memberof Scene.prototype
*
* @type {PrimitiveCollection}
* @readonly
*/
groundPrimitives : {
get : function() {
return this._groundPrimitives;
}
},

/**
* Gets the camera.
* @memberof Scene.prototype
Expand Down Expand Up @@ -1605,6 +1619,7 @@ define([
scene._globe.update(context, frameState, commandList);
}

scene._groundPrimitives.update(context, frameState, commandList);
scene._primitives.update(context, frameState, commandList);
}

Expand Down Expand Up @@ -2117,6 +2132,7 @@ define([
this._screenSpaceCameraController = this._screenSpaceCameraController && this._screenSpaceCameraController.destroy();
this._pickFramebuffer = this._pickFramebuffer && this._pickFramebuffer.destroy();
this._primitives = this._primitives && this._primitives.destroy();
this._groundPrimitives = this._groundPrimitives && this._groundPrimitives.destroy();
this._globe = this._globe && this._globe.destroy();
this.skyBox = this.skyBox && this.skyBox.destroy();
this.skyAtmosphere = this.skyAtmosphere && this.skyAtmosphere.destroy();
Expand Down
Loading

0 comments on commit 18e133c

Please sign in to comment.