Skip to content

Commit

Permalink
Merge pull request #5966 from ggetz/clipping-planes-tileset-traversal
Browse files Browse the repository at this point in the history
Tileset traversal with clipping planes
  • Loading branch information
lilleyse authored Nov 21, 2017
2 parents 7567c0c + 32b01c1 commit 261d0fc
Show file tree
Hide file tree
Showing 10 changed files with 229 additions and 95 deletions.
77 changes: 49 additions & 28 deletions Apps/Sandcastle/gallery/Clipping Planes.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,27 @@
<tr>
<td>x</td>
<td>
<input type="range" min="-100" max="100" step="1" data-bind="value: xOffset, valueUpdate: 'input'">
<input type="range" min="-150" max="150" step="1" data-bind="value: xOffset, valueUpdate: 'input'">
<input type="text" size="2" data-bind="value: xOffset">
</td>
</tr>
<tr>
<td>y</td>
<td>
<input type="range" min="-100" max="100" step="1" data-bind="value: yOffset, valueUpdate: 'input'">
<input type="range" min="-150" max="150" step="1" data-bind="value: yOffset, valueUpdate: 'input'">
<input type="text" size="2" data-bind="value: yOffset">
</td>
</tr>
<tr>
<td>z</td>
<td>
<input type="range" min="-100" max="100" step="1" data-bind="value: zOffset, valueUpdate: 'input'">
<input type="range" min="-150" max="150" step="1" data-bind="value: zOffset, valueUpdate: 'input'">
<input type="text" size="2" data-bind="value: zOffset">
</td>
</tr>
</tbody></table>
<input type="checkbox" value="false" data-bind="checked: clippingPlanesEnabled, valueUpdate: 'input'"> Enable clipping planes
<input type="checkbox" value="false" data-bind="checked: debugBoundingVolumesEnabled, valueUpdate: 'input'"> Show debug <code>boundingVolume</code>
</div>

<script id="cesium_sandcastle_script">
Expand All @@ -71,16 +73,28 @@
//Sandcastle_Begin
var viewer = new Cesium.Viewer('cesiumContainer');

var clippingPlanes;
var defaultClippingPlanes = [
new Cesium.Plane(new Cesium.Cartesian3(-1, 0, 0), 0.0),
new Cesium.Plane(new Cesium.Cartesian3(0, -1, 0), 100.0),
new Cesium.Plane(new Cesium.Cartesian3(0, 0, 1), 100.0)
new Cesium.Plane(new Cesium.Cartesian3(1.0, 0.0, 0.0), 0.0),
new Cesium.Plane(new Cesium.Cartesian3(0.0, 1.0, 0.0), -100.0),
new Cesium.Plane(new Cesium.Cartesian3(0.0, 0.0,-1.0), -100.0)
];

function loadTileset (url) {
var viewModel = {
exampleType : 'BIM',
exampleTypes : ['BIM', 'Model', 'Point Cloud'],
clippingPlanesEnabled: true,
xOffset : 0.0,
yOffset: -100.0,
zOffset: -100.0,
debugBoundingVolumesEnabled: false
};

var tileset;
function loadTileset(url) {
reset();

var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
url : url
}));

Expand All @@ -92,11 +106,13 @@
throw(error);
});

tileset.clippingPlanes = defaultClippingPlanes;
return tileset.clippingPlanes;
tileset.debugShowBoundingVolume = viewModel.debugBoundingVolumesEnabled;
tileset.clippingPlanesEnabled = viewModel.clippingPlanesEnabled;
clippingPlanes = tileset.clippingPlanes = defaultClippingPlanes.slice();
}

function loadModel (url) {
var model;
function loadModel(url) {
reset();

var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, 100.0);
Expand All @@ -118,27 +134,19 @@
});

viewer.trackedEntity = entity;

entity.model.clippingPlanes = defaultClippingPlanes;
return entity.model.clippingPlanes.getValue();
model = entity.model;
model.clippingPlanesEnabled = viewModel.clippingPlanesEnabled;
clippingPlanes = model.clippingPlanes = defaultClippingPlanes.slice();
}

// Power Plant design model provided by Bentley Systems
var bimUrl = 'https://beta.cesium.com/api/assets/1459?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIzNjUyM2I5Yy01YmRhLTQ0MjktOGI0Zi02MDdmYzBjMmY0MjYiLCJpZCI6NDQsImFzc2V0cyI6WzE0NTldLCJpYXQiOjE0OTkyNjQ3ODF9.SW_rwY-ic0TwQBeiweXNqFyywoxnnUBtcVjeCmDGef4';
var pointCloudUrl = 'https://beta.cesium.com/api/assets/1460?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIyMzk2YzJiOS1jZGFmLTRlZmYtYmQ4MS00NTA3NjEwMzViZTkiLCJpZCI6NDQsImFzc2V0cyI6WzE0NjBdLCJpYXQiOjE0OTkyNjQ3NTV9.oWjvN52CRQ-dk3xtvD4e8ZnOHZhoWSpJLlw115mbQJM';
var modelUrl = '../../SampleData/models/CesiumAir/Cesium_Air.glb';

var clippingPlanes = loadTileset(bimUrl);
loadTileset(bimUrl);

// Track and create the bindings for the view model

var viewModel = {
exampleType : 'BIM',
exampleTypes : ['BIM', 'Model', 'Point Cloud'],
xOffset : 0.0,
yOffset: 100.0,
zOffset: 100.0
};
var toolbar = document.getElementById('toolbar');
Cesium.knockout.track(viewModel);
Cesium.knockout.applyBindings(viewModel, toolbar);
Expand All @@ -155,14 +163,26 @@
clippingPlanes[2].distance = parseFloat(newValue);
});

Cesium.knockout.getObservable(viewModel, 'debugBoundingVolumesEnabled').subscribe(function(newValue) {
if (Cesium.defined(tileset)) {
tileset.debugShowBoundingVolume = newValue;
}
});

Cesium.knockout.getObservable(viewModel, 'clippingPlanesEnabled').subscribe(function(newValue) {
if (Cesium.defined(tileset)) {
tileset.clippingPlanesEnabled = newValue;
}
});

Cesium.knockout.getObservable(viewModel, 'exampleType').subscribe(
function(newValue) {
if (newValue === 'BIM') {
clippingPlanes = loadTileset(bimUrl);
loadTileset(bimUrl);
} else if (newValue === 'Point Cloud') {
clippingPlanes = loadTileset(pointCloudUrl);
loadTileset(pointCloudUrl);
} else {
clippingPlanes = loadModel(modelUrl);
loadModel(modelUrl);
}
}
);
Expand All @@ -172,9 +192,10 @@
viewer.scene.primitives.removeAll();

if (Cesium.defined(viewModel)) {
viewModel.clippingPlanesEnabled = true;
viewModel.xOffset = 0.0;
viewModel.yOffset = 100.0;
viewModel.zOffset = 100.0;
viewModel.yOffset = -100.0;
viewModel.zOffset = -100.0;
}
}

Expand Down
7 changes: 6 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
Change Log
==========

## TODO release

* Added `clippingPlanes` property to `ModelGraphics` and `Cesium3DTileset`, which specifies an array of planes to clip the object. [TODO]()
* Added `Plane.transformPlane` function to apply a transformation to a plane. [TODO]()

### 1.38 - 2017-10-02

* Breaking changes
Expand All @@ -18,7 +24,6 @@ Change Log
* Fixed a 3D Tiles point cloud bug causing a stray point to appear at the center of the screen on certain hardware. [#5599](https://github.com/AnalyticalGraphicsInc/cesium/issues/5599)
* Fixed removing multiple event listeners within event callbacks. [#5827](https://github.com/AnalyticalGraphicsInc/cesium/issues/5827)
* Running `buildApps` now creates a built version of Sandcastle which uses the built version of Cesium for better performance.
* Added `clippingPlanes` property to models and 3D Tilesets, which specify an array of planes to clip the object. [TODO]()
* Fixed a tileset traversal bug when the `skipLevelOfDetail` optimization is off. [#5869](https://github.com/AnalyticalGraphicsInc/cesium/issues/5869)

### 1.37 - 2017-09-01
Expand Down
61 changes: 38 additions & 23 deletions Source/Core/Plane.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
define([
'./Cartesian3',
'./Check',
'./defined',
'./DeveloperError',
'./freezeObject',
'./Math'
'./Math',
'./Matrix4'
], function(
Cartesian3,
Check,
defined,
DeveloperError,
freezeObject,
CesiumMath) {
CesiumMath,
Matrix4
) {
'use strict';

/**
Expand Down Expand Up @@ -39,15 +44,11 @@ define([
*/
function Plane(normal, distance) {
//>>includeStart('debug', pragmas.debug);
if (!defined(normal)) {
throw new DeveloperError('normal is required.');
}
Check.typeOf.object('normal', normal);
if (!CesiumMath.equalsEpsilon(Cartesian3.magnitude(normal), 1.0, CesiumMath.EPSILON6)) {
throw new DeveloperError('normal must be normalized.');
}
if (!defined(distance)) {
throw new DeveloperError('distance is required.');
}
Check.typeOf.number('distance', distance);
//>>includeEnd('debug');

/**
Expand Down Expand Up @@ -86,12 +87,8 @@ define([
*/
Plane.fromPointNormal = function(point, normal, result) {
//>>includeStart('debug', pragmas.debug);
if (!defined(point)) {
throw new DeveloperError('point is required.');
}
if (!defined(normal)) {
throw new DeveloperError('normal is required.');
}
Check.typeOf.object('point', point);
Check.typeOf.object('normal', normal);
if (!CesiumMath.equalsEpsilon(Cartesian3.magnitude(normal), 1.0, CesiumMath.EPSILON6)) {
throw new DeveloperError('normal must be normalized.');
}
Expand Down Expand Up @@ -120,9 +117,7 @@ define([
*/
Plane.fromCartesian4 = function(coefficients, result) {
//>>includeStart('debug', pragmas.debug);
if (!defined(coefficients)) {
throw new DeveloperError('coefficients is required.');
}
Check.typeOf.object('coefficients', coefficients);
//>>includeEnd('debug');

var normal = Cartesian3.fromCartesian4(coefficients, scratchNormal);
Expand Down Expand Up @@ -155,17 +150,37 @@ define([
*/
Plane.getPointDistance = function(plane, point) {
//>>includeStart('debug', pragmas.debug);
if (!defined(plane)) {
throw new DeveloperError('plane is required.');
}
if (!defined(point)) {
throw new DeveloperError('point is required.');
}
Check.typeOf.object('plane', plane);
Check.typeOf.object('point', point);
//>>includeEnd('debug');

return Cartesian3.dot(plane.normal, point) + plane.distance;
};

var scratchPosition = new Cartesian3();
/**
* Transforms the plane by the given transformation matrix.
*
* @param {Plane} plane The plane.
* @param {Matrix4} transform The transformation matrix.
* @param {Plane} [result] The object into which to store the result.
* @returns {Plane} The plane transformed by the given transformation matrix.
*/
Plane.transform = function(plane, transform, result) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object('plane', plane);
Check.typeOf.object('transform', transform);
//>>includeEnd('debug');

Matrix4.multiplyByPointAsVector(transform, plane.normal, scratchNormal);
Cartesian3.normalize(scratchNormal, scratchNormal);

Cartesian3.multiplyByScalar(plane.normal, plane.distance, scratchPosition);
Matrix4.multiplyByPoint(transform, scratchPosition, scratchPosition);

return Plane.fromPointNormal(scratchPosition, scratchNormal, result);
};

/**
* A constant initialized to the XY plane passing through the origin, with normal in positive Z.
*
Expand Down
4 changes: 2 additions & 2 deletions Source/DataSources/ModelGraphics.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ define([
* @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} that blends with the model's rendered color.
* @param {Property} [options.colorBlendMode=ColorBlendMode.HIGHLIGHT] An enum Property specifying how the color blends with the model.
* @param {Property} [options.colorBlendAmount=0.5] A numeric Property specifying the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two.
* @param {Property} [options.clippingPlanes=[]] A property specifying an array of {@link Plane} used to clip the model.
* @param {Property} [options.clippingPlanes=[]] A property specifying an array of up to 6 {@link Plane} used to selectively disable rendering on the outside of each plane.
*
* @see {@link http://cesiumjs.org/2014/03/03/Cesium-3D-Models-Tutorial/|3D Models Tutorial}
* @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=3D%20Models.html|Cesium Sandcastle 3D Models Demo}
Expand Down Expand Up @@ -248,7 +248,7 @@ define([
colorBlendAmount : createPropertyDescriptor('colorBlendAmount'),

/**
* A property specifying an array of {@link Plane} used to clip the model.
* A property specifying an array of up to 6 {@link Plane} used to selectively disable rendering on the outside of each plane.
* @memberof ModelGraphics.prototype
* @type {Property}
* @default []
Expand Down
4 changes: 3 additions & 1 deletion Source/Scene/Batched3DModel3DTileContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,8 @@ define([
pickUniformMapLoaded : batchTable.getPickUniformMapCallback(),
addBatchIdToGeneratedShaders : (batchLength > 0), // If the batch table has values in it, generated shaders will need a batchId attribute
pickObject : pickObject,
clippingPlanes : tileset.clippingPlanes
clippingPlanes : tileset.clippingPlanes,
clippingPlanesEnabled : tileset.clippingPlanesEnabled && tile._isClipped
});
}

Expand Down Expand Up @@ -449,6 +450,7 @@ define([
this._model.shadows = this._tileset.shadows;
this._model.debugWireframe = this._tileset.debugWireframe;
this._model.clippingPlanes = this._tileset.clippingPlanes;
this._model.clippingPlanesEnabled = this._tileset.clippingPlanesEnabled && this._tile._isClipped;
this._model.update(frameState);

// If any commands were pushed, add derived commands
Expand Down
Loading

0 comments on commit 261d0fc

Please sign in to comment.