Skip to content

Commit

Permalink
Merge pull request #7168 from OmarShehata/clipping-crash
Browse files Browse the repository at this point in the history
Fix clipping planes crash when adding plane to empty collection
  • Loading branch information
likangning93 authored Oct 26, 2018
2 parents cceb56c + 27c2efa commit ff3db12
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Change Log
* Fixed a crash when using `BingMapsGeocoderService` [#7143](https://github.com/AnalyticalGraphicsInc/cesium/issues/7143)
* Fixed entity visibility issue related to setting an entity show property and altering or adding entity geometry [#7156](https://github.com/AnalyticalGraphicsInc/cesium/pull/7156)
* Fixed accuracy of rotation matrix generated by `VelocityOrientationProperty` [#6641](https://github.com/AnalyticalGraphicsInc/cesium/pull/6641)
* Fixed clipping plane crash when adding a plane to an empty collection. [#7168](https://github.com/AnalyticalGraphicsInc/cesium/pull/7168)

### 1.50 - 2018-10-01

Expand Down
15 changes: 9 additions & 6 deletions Source/Scene/ClippingPlaneCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -470,10 +470,8 @@ define([

function computeTextureResolution(pixelsNeeded, result) {
var maxSize = ContextLimits.maximumTextureSize;
var width = Math.min(pixelsNeeded, maxSize);
var height = Math.ceil(pixelsNeeded / width);
result.x = Math.max(width, 1);
result.y = Math.max(height, 1);
result.x = Math.min(pixelsNeeded, maxSize);
result.y = Math.ceil(pixelsNeeded / result.x);
return result;
}

Expand All @@ -495,7 +493,6 @@ define([
// In RGBA UNSIGNED_BYTE, A plane is a float in [0, 1) packed to RGBA and an Oct32 quantized normal,
// so 8 bits or 2 pixels in RGBA.
var pixelsNeeded = useFloatTexture ? this.length : this.length * 2;
var requiredResolution = computeTextureResolution(pixelsNeeded, textureResolutionScratch);

if (defined(clippingPlanesTexture)) {
var currentPixelCount = clippingPlanesTexture.width * clippingPlanesTexture.height;
Expand All @@ -508,10 +505,17 @@ define([
pixelsNeeded < 0.25 * currentPixelCount) {
clippingPlanesTexture.destroy();
clippingPlanesTexture = undefined;
this._clippingPlanesTexture = undefined;
}
}

// If there are no clipping planes, there's nothing to update.
if (this.length === 0) {
return;
}

if (!defined(clippingPlanesTexture)) {
var requiredResolution = computeTextureResolution(pixelsNeeded, textureResolutionScratch);
// Allocate twice as much space as needed to avoid frequent texture reallocation.
// Allocate in the Y direction, since texture may be as wide as context texture support.
requiredResolution.y *= 2;
Expand Down Expand Up @@ -572,7 +576,6 @@ define([
} else {
offsetY = Math.floor((dirtyIndex * 2) / clippingPlanesTexture.width);
offsetX = Math.floor((dirtyIndex * 2) - offsetY * clippingPlanesTexture.width);

packPlanesAsUint8(this, dirtyIndex, dirtyIndex + 1);
clippingPlanesTexture.copyFrom({
width : 2,
Expand Down
2 changes: 1 addition & 1 deletion Source/Scene/GlobeSurfaceShaderSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ define([
(colorCorrect << 22);

var currentClippingShaderState = 0;
if (defined(clippingPlanes)) {
if (defined(clippingPlanes) && clippingPlanes.length > 0) {
currentClippingShaderState = enableClippingPlanes ? clippingPlanes.clippingPlanesState : 0;
}
var surfaceShader = surfaceTile.surfaceShader;
Expand Down
4 changes: 2 additions & 2 deletions Source/Scene/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ define([

function isClippingEnabled(model) {
var clippingPlanes = model._clippingPlanes;
return defined(clippingPlanes) && clippingPlanes.enabled;
return defined(clippingPlanes) && clippingPlanes.enabled && clippingPlanes.length !== 0;
}

/**
Expand Down Expand Up @@ -4344,7 +4344,7 @@ define([
// Regenerate shaders if ClippingPlaneCollection state changed or it was removed
var clippingPlanes = this._clippingPlanes;
var currentClippingPlanesState = 0;
if (defined(clippingPlanes) && clippingPlanes.enabled) {
if (defined(clippingPlanes) && clippingPlanes.enabled && clippingPlanes.length > 0) {
var clippingPlaneOffsetMatrix = defaultValue(this.clippingPlaneOffsetMatrix, modelMatrix);
Matrix4.multiply(context.uniformState.view3D, clippingPlaneOffsetMatrix, this._clippingPlaneModelViewMatrix);
currentClippingPlanesState = clippingPlanes.clippingPlanesState;
Expand Down
39 changes: 39 additions & 0 deletions Specs/Scene/ClippingPlaneCollectionSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,21 @@ defineSuite([
scene.destroyForSpecs();
});

it('only creates texture when planes are added', function() {
var scene = createScene();

clippingPlanes = new ClippingPlaneCollection();
clippingPlanes.update(scene.frameState);
expect(clippingPlanes.texture).toBeUndefined();

clippingPlanes.add(planes[0]);
clippingPlanes.update(scene.frameState);

expect(clippingPlanes.texture).toBeDefined();
expect(isNaN(clippingPlanes.texture.width)).toBe(false);
expect(isNaN(clippingPlanes.texture.height)).toBe(false);
});

it('update fills the clipping plane texture with packed planes', function() {
var scene = createScene();

Expand Down Expand Up @@ -399,6 +414,30 @@ defineSuite([
scene.destroyForSpecs();
});

it('only creates texture when planes are added', function() {
var scene = createScene();

if (!ClippingPlaneCollection.useFloatTexture(scene.context)) {
// Don't fail just because float textures aren't supported
scene.destroyForSpecs();
return;
}

clippingPlanes = new ClippingPlaneCollection();
clippingPlanes.update(scene.frameState);
expect(clippingPlanes.texture).toBeUndefined();

clippingPlanes.add(planes[0]);
clippingPlanes.update(scene.frameState);

expect(clippingPlanes.texture).toBeDefined();
expect(isNaN(clippingPlanes.texture.width)).toBe(false);
expect(isNaN(clippingPlanes.texture.height)).toBe(false);

clippingPlanes.destroy();
scene.destroyForSpecs();
});

it('update fills the clipping plane texture with packed planes', function() {
var scene = createScene();

Expand Down

0 comments on commit ff3db12

Please sign in to comment.