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

Add multifrustum near/far planes to DebugCameraPrimitive #4932

Merged
merged 13 commits into from
Feb 2, 2017
Merged
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ Change Log
* Added 2D and Columbus View support for models using the RTC extension or whose vertices are in WGS84 coordinates. [#4922](https://github.com/AnalyticalGraphicsInc/cesium/pull/4922)
* Transparent parts of billboards, labels, and points no longer overwrite parts of the scene behind them. [#4886](https://github.com/AnalyticalGraphicsInc/cesium/pull/4886)
* Added `blendOption` property to `BillboardCollection`, `LabelCollection`, and `PointPrimitiveCollection`. The default is `BlendOption.OPAQUE_AND_TRANSLUCENT`; however, if all billboards, labels, or points are either completely opaque or completely translucent, `blendOption` can be changed to `BlendOption.OPAQUE` or `BlendOption.TRANSLUCENT`, respectively, to increase performance by up to 2x.
<<<<<<< HEAD
* Added support to `DebugCameraPrimitive` to draw multifrustum planes. `CesiumInspector` also displays this toggle.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explicitly mention the new properties and arguments.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also move this to a new section for 1.31 since this is unlikely to make the 1.30 release, which is going out tomorrow morning.

=======
* Added the ability to run the unit tests with a [WebGL Stub](https://github.com/AnalyticalGraphicsInc/cesium/tree/master/Documentation/Contributors/TestingGuide#run-with-webgl-stub), which makes all WebGL calls a noop and ignores test expectations that rely on reading back from WebGL. Use the web link from the main index.html or run with `npm run test-webgl-stub`.
>>>>>>> agi/master

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The merge conflict in here needs to be resolved.

### 1.29 - 2017-01-02

Expand Down
113 changes: 94 additions & 19 deletions Source/Scene/DebugCameraPrimitive.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,17 +93,13 @@ define([
}

var frustumCornersNDC = new Array(8);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only 4 now.

frustumCornersNDC[0] = new Cartesian4(-1.0, -1.0, -1.0, 1.0);
frustumCornersNDC[1] = new Cartesian4(1.0, -1.0, -1.0, 1.0);
frustumCornersNDC[2] = new Cartesian4(1.0, 1.0, -1.0, 1.0);
frustumCornersNDC[3] = new Cartesian4(-1.0, 1.0, -1.0, 1.0);
frustumCornersNDC[4] = new Cartesian4(-1.0, -1.0, 1.0, 1.0);
frustumCornersNDC[5] = new Cartesian4(1.0, -1.0, 1.0, 1.0);
frustumCornersNDC[6] = new Cartesian4(1.0, 1.0, 1.0, 1.0);
frustumCornersNDC[7] = new Cartesian4(-1.0, 1.0, 1.0, 1.0);
frustumCornersNDC[0] = new Cartesian4(-1.0, -1.0, 1.0, 1.0);
frustumCornersNDC[1] = new Cartesian4(1.0, -1.0, 1.0, 1.0);
frustumCornersNDC[2] = new Cartesian4(1.0, 1.0, 1.0, 1.0);
frustumCornersNDC[3] = new Cartesian4(-1.0, 1.0, 1.0, 1.0);

var scratchMatrix = new Matrix4();
var scratchFrustumCorners = new Array(8);
var scratchFrustumCorners = new Array(4);
for (var i = 0; i < 8; ++i) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be 4

scratchFrustumCorners[i] = new Cartesian4();
}
Expand All @@ -130,14 +126,28 @@ define([
var viewProjection = Matrix4.multiply(projection, view, scratchMatrix);
var inverseViewProjection = Matrix4.inverse(viewProjection, scratchMatrix);

var positions = new Float64Array(8 * 3);
for (var i = 0; i < 8; ++i) {
var corner = Cartesian4.clone(frustumCornersNDC[i], scratchFrustumCorners[i]);
Matrix4.multiplyByVector(inverseViewProjection, corner, corner);
Cartesian3.divideByScalar(corner, corner.w, corner); // Handle the perspective divide
positions[i * 3] = corner.x;
positions[i * 3 + 1] = corner.y;
positions[i * 3 + 2] = corner.z;
var numFrustums = Math.max(1, Math.ceil(Math.log(frameState.far / frameState.near) / Math.log(frameState.farToNearRatio)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think FrameState should store the exact splits rather than recalculating here.


var positions = new Float64Array(3 * 4 * (numFrustums + 1));
var f;
for (f = 0; f < numFrustums + 1; ++f) {
for (var i = 0; i < 4; ++i) {
var corner = Cartesian4.clone(frustumCornersNDC[i], scratchFrustumCorners[i]);

Matrix4.multiplyByVector(inverseViewProjection, corner, corner);
Cartesian3.divideByScalar(corner, corner.w, corner); // Handle the perspective divide
Cartesian3.subtract(corner, this._camera.positionWC, corner);
Cartesian3.normalize(corner, corner);

var d = frameState.near * Math.pow(frameState.farToNearRatio, f);
var fac = Cartesian3.dot(this._camera.directionWC, corner);
Cartesian3.multiplyByScalar(corner, d / fac, corner);
Cartesian3.add(corner, this._camera.positionWC, corner);

positions[12 * f + i * 3] = corner.x;
positions[12 * f + i * 3 + 1] = corner.y;
positions[12 * f + i * 3 + 2] = corner.z;
}
}

var boundingSphere = new BoundingSphere.fromVertices(positions);
Expand All @@ -149,8 +159,33 @@ define([
values : positions
});

var offset;

// Create the outline primitive
var outlineIndices = new Uint16Array([0,1,1,2,2,3,3,0,0,4,4,7,7,3,7,6,6,2,2,1,1,5,5,4,5,6]);
var outlineIndices = new Uint16Array(8 * (2 * numFrustums + 1));
// build the far planes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capitalize the first word in comments.

for (f = 0; f < numFrustums + 1; ++f) {
outlineIndices[f * 8] = f * 4;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and in the loop below, assign f * 8 and f * 4 to locals. I do not know if the JS engine would optimize. This primitive is just for debugging, but in general primitive.update functions are carefully coded for performance.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment throughout.

outlineIndices[f * 8 + 1] = f * 4 + 1;
outlineIndices[f * 8 + 2] = f * 4 + 1;
outlineIndices[f * 8 + 3] = f * 4 + 2;
outlineIndices[f * 8 + 4] = f * 4 + 2;
outlineIndices[f * 8 + 5] = f * 4 + 3;
outlineIndices[f * 8 + 6] = f * 4 + 3;
outlineIndices[f * 8 + 7] = f * 4;
}
// build the sides of the frustums
for (f = 0; f < numFrustums; ++f) {
offset = (numFrustums + 1 + f) * 8;
outlineIndices[offset] = f * 4;
outlineIndices[offset + 1] = f * 4 + 4;
outlineIndices[offset + 2] = f * 4 + 1;
outlineIndices[offset + 3] = f * 4 + 5;
outlineIndices[offset + 4] = f * 4 + 2;
outlineIndices[offset + 5] = f * 4 + 6;
outlineIndices[offset + 6] = f * 4 + 3;
outlineIndices[offset + 7] = f * 4 + 7;
}

this._outlinePrimitive = new Primitive({
geometryInstances : new GeometryInstance({
Expand All @@ -174,7 +209,47 @@ define([
});

// Create the planes primitive
var planesIndices = new Uint16Array([4,5,6,4,6,7,5,1,2,5,2,6,7,6,2,7,2,3,0,1,5,0,5,4,0,4,7,0,7,3,1,0,3,1,3,2]);
var planesIndices = new Uint16Array(6 * (5 * numFrustums + 1));
// build the far planes
for (f = 0; f < numFrustums + 1; ++f) {
planesIndices[f * 6] = f * 4;
planesIndices[f * 6 + 1] = f * 4 + 1;
planesIndices[f * 6 + 2] = f * 4 + 2;
planesIndices[f * 6 + 3] = f * 4;
planesIndices[f * 6 + 4] = f * 4 + 2;
planesIndices[f * 6 + 5] = f * 4 + 3;
}
// build the sides of the frustums
for (f = 0; f < numFrustums; ++f) {
offset = (numFrustums + 1 + 4 * f) * 6;
planesIndices[offset] = 4 * f + 4;
planesIndices[offset + 1] = 4 * f;
planesIndices[offset + 2] = 4 * f + 3;
planesIndices[offset + 3] = 4 * f + 4;
planesIndices[offset + 4] = 4 * f + 3;
planesIndices[offset + 5] = 4 * f + 7;

planesIndices[offset + 6] = 4 * f + 4;
planesIndices[offset + 7] = 4 * f;
planesIndices[offset + 8] = 4 * f + 1;
planesIndices[offset + 9] = 4 * f + 4;
planesIndices[offset + 10] = 4 * f + 1;
planesIndices[offset + 11] = 4 * f + 5;

planesIndices[offset + 12] = 4 * f + 7;
planesIndices[offset + 13] = 4 * f + 3;
planesIndices[offset + 14] = 4 * f + 2;
planesIndices[offset + 15] = 4 * f + 7;
planesIndices[offset + 16] = 4 * f + 2;
planesIndices[offset + 17] = 4 * f + 6;

planesIndices[offset + 18] = 4 * f + 6;
planesIndices[offset + 19] = 4 * f + 2;
planesIndices[offset + 20] = 4 * f + 1;
planesIndices[offset + 21] = 4 * f + 6;
planesIndices[offset + 22] = 4 * f + 1;
planesIndices[offset + 23] = 4 * f + 5;
}

this._planesPrimitive = new Primitive({
geometryInstances : new GeometryInstance({
Expand Down
4 changes: 4 additions & 0 deletions Source/Scene/FrameState.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ define([
* @default 0.0
*/
this.imagerySplitPosition = 0.0;

this.near = 1.0;
this.far = 1000.0;
this.farToNearRatio = 1000.0;
}

/**
Expand Down
42 changes: 42 additions & 0 deletions Source/Scene/Scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ define([
'./Camera',
'./CreditDisplay',
'./CullingVolume',
'./DebugCameraPrimitive',
'./DepthPlane',
'./DeviceOrientationCameraController',
'./Fog',
Expand Down Expand Up @@ -109,6 +110,7 @@ define([
Camera,
CreditDisplay,
CullingVolume,
DebugCameraPrimitive,
DepthPlane,
DeviceOrientationCameraController,
Fog,
Expand Down Expand Up @@ -515,6 +517,9 @@ define([
*/
this.debugShowDepthFrustum = 1;

this._debugShowFrustumPlanes = false;
this._debugFrustumPlanes = undefined;

/**
* When <code>true</code>, enables Fast Approximate Anti-aliasing even when order independent translucency
* is unsupported.
Expand Down Expand Up @@ -944,6 +949,40 @@ define([
}
},

/**
* This property is for debugging only; it is not for production use.
* <p>
* When <code>true</code>, draws primitives to show the boundaries of the camera frustum
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tweak wording a bit - draws outlines to show the boundaries of the camera frustums

* </p>
*
* @type Boolean
*
* @default false
*/
debugShowFrustumPlanes : {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When this is merged into the 3d-tiles branch, please remove the code that explicitly creates the debug frustum in the Cesium3DTileset and just have the inspector set this property.

get : function() {
return this._debugShowFrustumPlanes;
},

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove empty line.

set : function(val) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

val -> value

if (!val) {
if (defined(this._debugFrustumPlanes)) {
this.primitives.remove(this._debugFrustumPlanes);
this._debugFrustumPlanes = this._debugFrustumPlanes && !this._debugFrustumPlanes.isDestroyed() && this._debugFrustumPlanes.destroy();
}
} else if (val !== this._debugShowFrustumPlanes) {
this._debugFrustumPlanes = this._debugFrustumPlanes && !this._debugFrustumPlanes.isDestroyed() && this._debugFrustumPlanes.destroy();
this._debugFrustumPlanes = new DebugCameraPrimitive({
camera: this.camera,
updateOnChange: false
});
this._debugFrustumPlanes.update(this.frameState);
this.primitives.add(this._debugFrustumPlanes);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not add directly to primitives. Instead Scene should be responsible for pushing this._debugFrustumPlanes's commands.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While doing that make sure to destroy it when scene is destroyed.

}
this._debugShowFrustumPlanes = val;
}
},

/**
* Gets whether or not the scene is optimized for 3D only viewing.
* @memberof Scene.prototype
Expand Down Expand Up @@ -1428,6 +1467,9 @@ define([
if (near !== Number.MAX_VALUE && (numFrustums !== numberOfFrustums || (frustumCommandsList.length !== 0 &&
(near < frustumCommandsList[0].near || far > frustumCommandsList[numberOfFrustums - 1].far)))) {
updateFrustums(near, far, farToNearRatio, numFrustums, frustumCommandsList, is2D, scene.nearToFarDistance2D);
frameState.near = near;
frameState.far = far;
frameState.farToNearRatio = farToNearRatio;
createPotentiallyVisibleSet(scene);
}
}
Expand Down
9 changes: 9 additions & 0 deletions Source/Widgets/CesiumInspector/CesiumInspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ define([
generalSection.className = 'cesium-cesiumInspector-section';
generalSection.setAttribute('data-bind', 'css: {"cesium-cesiumInspector-show" : generalVisible, "cesium-cesiumInspector-hide" : !generalVisible}');
panel.appendChild(generalSection);

var debugShowFrustums = document.createElement('div');
generalSection.appendChild(debugShowFrustums);
var frustumStats = document.createElement('div');
Expand All @@ -92,6 +93,14 @@ define([
debugShowFrustums.appendChild(document.createTextNode('Show Frustums'));
debugShowFrustums.appendChild(frustumStats);

var debugShowFrustumPlanes = document.createElement('div');
generalSection.appendChild(debugShowFrustumPlanes);
var frustumPlanesCheckbox = document.createElement('input');
frustumPlanesCheckbox.type = 'checkbox';
frustumPlanesCheckbox.setAttribute('data-bind', 'checked: frustumPlanes');
debugShowFrustumPlanes.appendChild(frustumPlanesCheckbox);
debugShowFrustumPlanes.appendChild(document.createTextNode('Show Frustum Planes'));

var performanceDisplay = document.createElement('div');
generalSection.appendChild(performanceDisplay);
var pdCheckbox = document.createElement('input');
Expand Down
13 changes: 13 additions & 0 deletions Source/Widgets/CesiumInspector/CesiumInspectorViewModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ define([
*/
this.frustums = false;

/**
* Gets or sets the show frustum planes state. This property is observable.
* @type {Boolean}
* @default false
*/
this.frustumPlanes = false;

/**
* Gets or sets the show performance display state. This property is observable.
* @type {Boolean}
Expand Down Expand Up @@ -305,6 +312,7 @@ define([

knockout.track(this, [
'frustums',
'frustumPlanes',
'performance',
'shaderCacheText',
'primitiveBoundingSphere',
Expand Down Expand Up @@ -351,6 +359,10 @@ define([
that._scene.debugShowFrustums = val;
});

this._frustumPlanesSubscription = knockout.getObservable(this, 'frustumPlanes').subscribe(function(val) {
that._scene.debugShowFrustumPlanes = val;
});

this._performanceSubscription = knockout.getObservable(this, 'performance').subscribe(function(val) {
if (val) {
that._performanceDisplay = new PerformanceDisplay({
Expand Down Expand Up @@ -940,6 +952,7 @@ define([
CesiumInspectorViewModel.prototype.destroy = function() {
this._eventHandler.destroy();
this._frustumsSubscription.dispose();
this._frustumPlanesSubscription.dispose();
this._performanceSubscription.dispose();
this._primitiveBoundingSphereSubscription.dispose();
this._primitiveReferenceFrameSubscription.dispose();
Expand Down