Skip to content

Commit

Permalink
Add WebGL tests to verify global clipping works as expected
Browse files Browse the repository at this point in the history
  • Loading branch information
Samuel Vargas committed Jun 9, 2020
1 parent 92bf7a3 commit 61363cd
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 32 deletions.
64 changes: 64 additions & 0 deletions Source/Scene/ClippingPolygon.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Cartographic from "../Core/Cartographic.js";
import Transforms from "../Core/Transforms.js";
import simplify3d from "../ThirdParty/simplify3d.js";
import Check from "../Core/Check.js";
import destroyObject from "../Core/destroyObject.js";

/**
* ClippingPolygon constructor. Should not be instantiated directly;
Expand Down Expand Up @@ -51,6 +52,9 @@ function ClippingPolygon(options) {
this._union = options.union;
this._enabled = options.enabled;

// If owned, only its owner should update or destroy it.
this._owner = undefined;

var positions = options.positions;
var indices = options.indices;
var splits = options.splits;
Expand Down Expand Up @@ -167,7 +171,37 @@ ClippingPolygon.fromPolygonHierarchies = function (options) {
return new ClippingPolygon(options);
};

/**
* Sets the owner for the provided ClippingPolygon if it doesn't
* already have an owner. Destroys the owner's previous ClippingPolygon
* if setting is unsuccessful
*/
ClippingPolygon.setOwner = function (clippingPolygon, owner, key) {
// Avoid destroying ClippingPolygon if already owned by newOwner
if (clippingPolygon === owner[key]) {
return;
}

owner[key] = owner[key] && owner[key].destroy();
if (defined(clippingPolygon)) {
if (defined(clippingPolygon._owner)) {
throw new DeveloperError(
"ClippingPolygon should only be assigned to one object."
);
}
}

clippingPolygon._owner = owner;
owner[key] = clippingPolygon;
};

Object.defineProperties(ClippingPolygon.prototype, {
owner: {
get: function () {
return this._owner;
},
},

grid: {
get: function () {
return this._grid;
Expand Down Expand Up @@ -351,6 +385,36 @@ ClippingPolygon.prototype.update = function (frameState) {
});
};

/**
* Returns true if this object was destroyed; otherwise, false.
* <br /><br />
* If this object was destroyed, it should not be used; calling any function other than
* <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
*
* @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>.
*
* @see ClippingPolygon#destroy
*/
ClippingPolygon.prototype.isDestroyed = function () {
return false;
};

ClippingPolygon.prototype.destroy = function () {
if (defined(this.meshPositionsTexture)) {
this.meshPositionsTexture.destroy();
}

if (defined(this.overlappingTriangleIndicesTexture)) {
this.overlappingTriangleIndicesTexture.destroy();
}

if (defined(this.gridTexture)) {
this.gridTexture.destroy();
}

return destroyObject(this);
};

/**
* @param {Array.<PolygonHierarchy>} hierarchies Polygon hierarchies to collapse into
* a single mesh.
Expand Down
4 changes: 2 additions & 2 deletions Source/Scene/GlobeSurfaceTileProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import RenderState from "../Renderer/RenderState.js";
import VertexArray from "../Renderer/VertexArray.js";
import BlendingState from "./BlendingState.js";
import ClippingPlaneCollection from "./ClippingPlaneCollection.js";
import ClippingPolygon from "./ClippingPolygon.js";
import DepthFunction from "./DepthFunction.js";
import GlobeSurfaceTile from "./GlobeSurfaceTile.js";
import ImageryLayer from "./ImageryLayer.js";
Expand Down Expand Up @@ -337,8 +338,7 @@ Object.defineProperties(GlobeSurfaceTileProvider.prototype, {
return this._clippingPolygon;
},
set: function (value) {
this._clippingPolygon = value;
//ClippingPolygon.setOwner(value, this, "_clippingPolygon");
ClippingPolygon.setOwner(value, this, "_clippingPolygon");
},
},
});
Expand Down
15 changes: 12 additions & 3 deletions Source/Scene/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import when from "../ThirdParty/when.js";
import Axis from "./Axis.js";
import BlendingState from "./BlendingState.js";
import ClippingPlaneCollection from "./ClippingPlaneCollection.js";
import ClippingPolygon from "./ClippingPolygon.js";
import ColorBlendMode from "./ColorBlendMode.js";
import DepthFunction from "./DepthFunction.js";
import DracoLoader from "./DracoLoader.js";
Expand Down Expand Up @@ -1097,9 +1098,7 @@ Object.defineProperties(Model.prototype, {
if (value === this._clippingPolygon) {
return;
}
this._clippingPolygon = value;
// Handle destroying, checking of unknown, checking for existing ownership
//ClippingPlaneCollection.setOwner(value, this, "_clippingPlanes");
ClippingPolygon.setOwner(value, this, "_clippingPolygon");
},
},

Expand Down Expand Up @@ -5901,6 +5900,16 @@ Model.prototype.destroy = function () {
releaseCachedGltf(this);
this._quantizedVertexShaders = undefined;

// Only destroy the ClippingPolygon collection if this is the owner.
var clippingPolygon = this._clippingPolygon;
if (
defined(clippingPolygon) &&
!clippingPolygon.isDestroyed() &&
clippingPolygon.owner === this
) {
clippingPolygon.destroy();
}

// Only destroy the ClippingPlaneCollection if this is the owner - if this model is part of a Cesium3DTileset,
// _clippingPlanes references a ClippingPlaneCollection that this model does not own.
var clippingPlaneCollection = this._clippingPlanes;
Expand Down
104 changes: 77 additions & 27 deletions Specs/Scene/ClippingPolygonSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,33 @@ import pollToPromise from "../pollToPromise.js";
describe("Scene/ClippingPolygon", function () {
// prettier-ignore
var coloradoBoundaryECEF =
[
new Cartesian3(-1483132.6118617766, -4586466.1397278225, 4162750.5664251903),
new Cartesian3(-1306830.1054550062, -4640193.5668967, 4162291.5282076155),
new Cartesian3(-1170464.5181384478, -4676041.788416427, 4162750.5664251903),
new Cartesian3(-1006635.362080386, -4714025.799998029, 4162750.5664251903),
new Cartesian3(-1021730.8265712946, -4784717.146391854, 4078123.8740084106),
new Cartesian3(-1064162.144338376, -4988089.875097037, 3816931.0243110945),
new Cartesian3(-1147369.5949660358, -4969234.714178492, 3817416.470178762),
new Cartesian3(-1263040.64619151, -4941478.523433706, 3816931.0243110945),
new Cartesian3(-1479968.0924533417, -4880899.1094683, 3816931.024311095),
new Cartesian3(-1526912.2714726557, -4866034.273129951, 3817416.4701787615),
new Cartesian3(-1663966.3042978912, -4820888.587201569, 3817416.4701787615),
new Cartesian3(-1638200.935371567, -4746240.457199701, 3920021.4124960876),
new Cartesian3(-1637105.4814648873, -4738660.06955747, 3929573.7306454126),
new Cartesian3(-1617417.1160520257, -4683121.79641693, 4003119.2230556826),
new Cartesian3(-1573284.5993211386, -4556750.687971856, 4162291.5282076155),
new Cartesian3(-1483132.6118617766, -4586466.1397278225, 4162750.5664251903)
];

var colorado = new PolygonHierarchy(coloradoBoundaryECEF);
[
new Cartesian3(-1483132.6118617766, -4586466.1397278225, 4162750.5664251903),
new Cartesian3(-1306830.1054550062, -4640193.5668967, 4162291.5282076155),
new Cartesian3(-1170464.5181384478, -4676041.788416427, 4162750.5664251903),
new Cartesian3(-1006635.362080386, -4714025.799998029, 4162750.5664251903),
new Cartesian3(-1021730.8265712946, -4784717.146391854, 4078123.8740084106),
new Cartesian3(-1064162.144338376, -4988089.875097037, 3816931.0243110945),
new Cartesian3(-1147369.5949660358, -4969234.714178492, 3817416.470178762),
new Cartesian3(-1263040.64619151, -4941478.523433706, 3816931.0243110945),
new Cartesian3(-1479968.0924533417, -4880899.1094683, 3816931.024311095),
new Cartesian3(-1526912.2714726557, -4866034.273129951, 3817416.4701787615),
new Cartesian3(-1663966.3042978912, -4820888.587201569, 3817416.4701787615),
new Cartesian3(-1638200.935371567, -4746240.457199701, 3920021.4124960876),
new Cartesian3(-1637105.4814648873, -4738660.06955747, 3929573.7306454126),
new Cartesian3(-1617417.1160520257, -4683121.79641693, 4003119.2230556826),
new Cartesian3(-1573284.5993211386, -4556750.687971856, 4162291.5282076155),
new Cartesian3(-1483132.6118617766, -4586466.1397278225, 4162750.5664251903)
];

var coloradoPolygonHierarchy = new PolygonHierarchy(coloradoBoundaryECEF);
var boundingSphere = BoundingSphere.fromPoints(coloradoBoundaryECEF);
var cartographic = Cartographic.fromCartesian(boundingSphere.center);
var coloradoCenter = Cartographic.toCartesian(cartographic);

it("constructs with expected default values", function () {
var clippingPolygon = ClippingPolygon.fromPolygonHierarchies({
polygonHierarchies: [colorado],
polygonHierarchies: [coloradoPolygonHierarchy],
});

expect(clippingPolygon.union).toEqual(false);
Expand All @@ -52,7 +52,7 @@ describe("Scene/ClippingPolygon", function () {

it("worldToENU matrix translates from world space to east north up space", function () {
var clippingPolygon = ClippingPolygon.fromPolygonHierarchies({
polygonHierarchies: [colorado],
polygonHierarchies: [coloradoPolygonHierarchy],
});

var worldToENU = clippingPolygon.worldToENU;
Expand All @@ -67,9 +67,9 @@ describe("Scene/ClippingPolygon", function () {
expect(result.z).toBeCloseTo(0);
});

it("setters update as expeected", function () {
it("setters update as expected", function () {
var clippingPolygon = ClippingPolygon.fromPolygonHierarchies({
polygonHierarchies: [colorado],
polygonHierarchies: [coloradoPolygonHierarchy],
});

clippingPolygon.enabled = false;
Expand All @@ -89,7 +89,7 @@ describe("Scene/ClippingPolygon", function () {
var union = true;

var clippingPolygon = ClippingPolygon.fromPolygonHierarchies({
polygonHierarchies: [colorado],
polygonHierarchies: [coloradoPolygonHierarchy],
union: union,
simplify: 3,
enabled: enabled,
Expand Down Expand Up @@ -171,6 +171,51 @@ describe("Scene/ClippingPolygon", function () {
scene.destroyForSpecs();
});

it("object is destroyed as expected", function () {
var clippingPolygon = ClippingPolygon.fromPolygonHierarchies({
polygonHierarchies: [coloradoPolygonHierarchy],
union: false,
simplify: 3,
enabled: true,
splits: 0,
});

var texturesGenerated = false;
var scene = createScene();
scene.mode = SceneMode.SCENE3D;
scene.camera = new Camera(scene);

if (!scene.context.floatingPointTexture) {
scene.destroyForSpecs();
} else {
texturesGenerated = true;
}

expect(clippingPolygon.gridTexture).toBeUndefined();
expect(clippingPolygon.overlappingTriangleIndicesTexture).toBeUndefined();
expect(clippingPolygon.meshPositionsTexture).toBeUndefined();

if (!texturesGenerated) {
return;
}

clippingPolygon.update(scene.frameState);
expect(clippingPolygon.gridTexture).toBeDefined();
expect(clippingPolygon.overlappingTriangleIndicesTexture).toBeDefined();
expect(clippingPolygon.meshPositionsTexture).toBeDefined();
clippingPolygon.destroy();

expect(clippingPolygon.isDestroyed()).toBe(true);

expect(function () {
clippingPolygon.update(scene.frameState);
}).toThrowDeveloperError();

expect(function () {
clippingPolygon.update(scene.frameState);
}).toThrowDeveloperError();
});

function clipColoradoAndRenderSceneIfFloatTextureAvailable(useUnion, flyTo) {
var scene = createScene();
scene.mode = SceneMode.SCENE3D;
Expand All @@ -182,14 +227,19 @@ describe("Scene/ClippingPolygon", function () {
}

var coloradoClipped = ClippingPolygon.fromPolygonHierarchies({
polygonHierarchies: [colorado],
polygonHierarchies: [coloradoPolygonHierarchy],
union: useUnion,
});

coloradoClipped.update(scene.frameState);

scene.globe = new Globe();
scene.globe.clippingPolygon = coloradoClipped;
var sameClippingPolygon = scene.globe.clippingPolygon === coloradoClipped;
var correctOwner =
coloradoClipped.owner === scene.globe._surface.tileProvider;
expect(sameClippingPolygon).toBe(true);
expect(correctOwner).toBe(true);

flyTo(scene.camera);
return scene;
Expand Down Expand Up @@ -225,7 +275,7 @@ describe("Scene/ClippingPolygon", function () {
});
}

it("colorado is NOT rendered if camera is looking at colorado and union is false", function () {
it("colorado IS NOT rendered if camera is looking at colorado and union is false", function () {
var scene = clipColoradoAndRenderSceneIfFloatTextureAvailable(
false,
flyToColorado
Expand Down

0 comments on commit 61363cd

Please sign in to comment.