import { AxisAlignedBoundingBox } from "../../Source/Cesium.js"; import { BoundingSphere } from "../../Source/Cesium.js"; import { Cartesian3 } from "../../Source/Cesium.js"; import { CullingVolume } from "../../Source/Cesium.js"; import { Intersect } from "../../Source/Cesium.js"; import { PerspectiveFrustum } from "../../Source/Cesium.js"; describe("Core/CullingVolume", function () { var cullingVolume; beforeEach(function () { var frustum = new PerspectiveFrustum(); frustum.near = 1.0; frustum.far = 2.0; frustum.fov = Math.PI / 3; frustum.aspectRatio = 1.0; cullingVolume = frustum.computeCullingVolume( new Cartesian3(), Cartesian3.negate(Cartesian3.UNIT_Z, new Cartesian3()), Cartesian3.UNIT_Y ); }); it("computeVisibility throws without a bounding volume", function () { expect(function () { return new CullingVolume().computeVisibility(); }).toThrowDeveloperError(); }); it("computeVisibilityWithPlaneMask throws without a bounding volume", function () { expect(function () { return new CullingVolume().computeVisibilityWithPlaneMask( undefined, CullingVolume.MASK_INDETERMINATE ); }).toThrowDeveloperError(); }); it("computeVisibilityWithPlaneMask throws without a parent plane mask", function () { expect(function () { return new CullingVolume().computeVisibilityWithPlaneMask( new BoundingSphere(), undefined ); }).toThrowDeveloperError(); }); function testWithAndWithoutPlaneMask(culling, bound, intersect) { expect(culling.computeVisibility(bound)).toEqual(intersect); var mask = culling.computeVisibilityWithPlaneMask( bound, CullingVolume.MASK_INDETERMINATE ); if (intersect === Intersect.INSIDE) { expect(mask).toEqual(CullingVolume.MASK_INSIDE); } else if (intersect === Intersect.OUTSIDE) { expect(mask).toEqual(CullingVolume.MASK_OUTSIDE); } else { expect(mask).not.toEqual(CullingVolume.MASK_INSIDE); expect(mask).not.toEqual(CullingVolume.MASK_OUTSIDE); } expect(culling.computeVisibilityWithPlaneMask(bound, mask)).toEqual(mask); } describe("box intersections", function () { it("can contain an axis aligned bounding box", function () { var box1 = AxisAlignedBoundingBox.fromPoints([ new Cartesian3(-0.5, 0, -1.25), new Cartesian3(0.5, 0, -1.25), new Cartesian3(-0.5, 0, -1.75), new Cartesian3(0.5, 0, -1.75), ]); testWithAndWithoutPlaneMask(cullingVolume, box1, Intersect.INSIDE); }); describe("can partially contain an axis aligned bounding box", function () { it("on the far plane", function () { var box2 = AxisAlignedBoundingBox.fromPoints([ new Cartesian3(-0.5, 0, -1.5), new Cartesian3(0.5, 0, -1.5), new Cartesian3(-0.5, 0, -2.5), new Cartesian3(0.5, 0, -2.5), ]); testWithAndWithoutPlaneMask( cullingVolume, box2, Intersect.INTERSECTING ); }); it("on the near plane", function () { var box3 = AxisAlignedBoundingBox.fromPoints([ new Cartesian3(-0.5, 0, -0.5), new Cartesian3(0.5, 0, -0.5), new Cartesian3(-0.5, 0, -1.5), new Cartesian3(0.5, 0, -1.5), ]); testWithAndWithoutPlaneMask( cullingVolume, box3, Intersect.INTERSECTING ); }); it("on the left plane", function () { var box4 = AxisAlignedBoundingBox.fromPoints([ new Cartesian3(-1.5, 0, -1.25), new Cartesian3(0, 0, -1.25), new Cartesian3(-1.5, 0, -1.5), new Cartesian3(0, 0, -1.5), ]); testWithAndWithoutPlaneMask( cullingVolume, box4, Intersect.INTERSECTING ); }); it("on the right plane", function () { var box5 = AxisAlignedBoundingBox.fromPoints([ new Cartesian3(0, 0, -1.25), new Cartesian3(1.5, 0, -1.25), new Cartesian3(0, 0, -1.5), new Cartesian3(1.5, 0, -1.5), ]); testWithAndWithoutPlaneMask( cullingVolume, box5, Intersect.INTERSECTING ); }); it("on the top plane", function () { var box6 = AxisAlignedBoundingBox.fromPoints([ new Cartesian3(-0.5, 0, -1.25), new Cartesian3(0.5, 0, -1.25), new Cartesian3(-0.5, 2.0, -1.75), new Cartesian3(0.5, 2.0, -1.75), ]); testWithAndWithoutPlaneMask( cullingVolume, box6, Intersect.INTERSECTING ); }); it("on the bottom plane", function () { var box7 = AxisAlignedBoundingBox.fromPoints([ new Cartesian3(-0.5, -2.0, -1.25), new Cartesian3(0.5, 0, -1.25), new Cartesian3(-0.5, -2.0, -1.5), new Cartesian3(0.5, 0, -1.5), ]); testWithAndWithoutPlaneMask( cullingVolume, box7, Intersect.INTERSECTING ); }); }); describe("can not contain an axis aligned bounding box", function () { it("past the far plane", function () { var box8 = AxisAlignedBoundingBox.fromPoints([ new Cartesian3(-0.5, 0, -2.25), new Cartesian3(0.5, 0, -2.25), new Cartesian3(-0.5, 0, -2.75), new Cartesian3(0.5, 0, -2.75), ]); testWithAndWithoutPlaneMask(cullingVolume, box8, Intersect.OUTSIDE); }); it("before the near plane", function () { var box9 = AxisAlignedBoundingBox.fromPoints([ new Cartesian3(-0.5, 0, -0.25), new Cartesian3(0.5, 0, -0.25), new Cartesian3(-0.5, 0, -0.75), new Cartesian3(0.5, 0, -0.75), ]); testWithAndWithoutPlaneMask(cullingVolume, box9, Intersect.OUTSIDE); }); it("past the left plane", function () { var box10 = AxisAlignedBoundingBox.fromPoints([ new Cartesian3(-5, 0, -1.25), new Cartesian3(-3, 0, -1.25), new Cartesian3(-5, 0, -1.75), new Cartesian3(-3, 0, -1.75), ]); testWithAndWithoutPlaneMask(cullingVolume, box10, Intersect.OUTSIDE); }); it("past the right plane", function () { var box11 = AxisAlignedBoundingBox.fromPoints([ new Cartesian3(3, 0, -1.25), new Cartesian3(5, 0, -1.25), new Cartesian3(3, 0, -1.75), new Cartesian3(5, 0, -1.75), ]); testWithAndWithoutPlaneMask(cullingVolume, box11, Intersect.OUTSIDE); }); it("past the top plane", function () { var box12 = AxisAlignedBoundingBox.fromPoints([ new Cartesian3(-0.5, 3, -1.25), new Cartesian3(0.5, 3, -1.25), new Cartesian3(-0.5, 5, -1.75), new Cartesian3(0.5, 5, -1.75), ]); testWithAndWithoutPlaneMask(cullingVolume, box12, Intersect.OUTSIDE); }); it("past the bottom plane", function () { var box13 = AxisAlignedBoundingBox.fromPoints([ new Cartesian3(-0.5, -3, -1.25), new Cartesian3(0.5, -3, -1.25), new Cartesian3(-0.5, -5, -1.75), new Cartesian3(0.5, -5, -1.75), ]); testWithAndWithoutPlaneMask(cullingVolume, box13, Intersect.OUTSIDE); }); }); }); describe("sphere intersection", function () { it("can contain a sphere", function () { var sphere1 = BoundingSphere.fromPoints([ new Cartesian3(0, 0, -1.25), new Cartesian3(0, 0, -1.75), ]); testWithAndWithoutPlaneMask(cullingVolume, sphere1, Intersect.INSIDE); }); describe("can partially contain a sphere", function () { it("on the far plane", function () { var sphere2 = BoundingSphere.fromPoints([ new Cartesian3(0, 0, -1.5), new Cartesian3(0, 0, -2.5), ]); testWithAndWithoutPlaneMask( cullingVolume, sphere2, Intersect.INTERSECTING ); }); it("on the near plane", function () { var sphere3 = BoundingSphere.fromPoints([ new Cartesian3(0, 0, -0.5), new Cartesian3(0, 0, -1.5), ]); testWithAndWithoutPlaneMask( cullingVolume, sphere3, Intersect.INTERSECTING ); }); it("on the left plane", function () { var sphere4 = BoundingSphere.fromPoints([ new Cartesian3(-1.0, 0, -1.5), new Cartesian3(0, 0, -1.5), ]); testWithAndWithoutPlaneMask( cullingVolume, sphere4, Intersect.INTERSECTING ); }); it("on the right plane", function () { var sphere5 = BoundingSphere.fromPoints([ new Cartesian3(0, 0, -1.5), new Cartesian3(1.0, 0, -1.5), ]); testWithAndWithoutPlaneMask( cullingVolume, sphere5, Intersect.INTERSECTING ); }); it("on the top plane", function () { var sphere6 = BoundingSphere.fromPoints([ new Cartesian3(0, 0, -1.5), new Cartesian3(0, 2.0, -1.5), ]); testWithAndWithoutPlaneMask( cullingVolume, sphere6, Intersect.INTERSECTING ); }); it("on the bottom plane", function () { var sphere7 = BoundingSphere.fromPoints([ new Cartesian3(0, -2.0, -1.5), new Cartesian3(0, 0, -1.5), ]); testWithAndWithoutPlaneMask( cullingVolume, sphere7, Intersect.INTERSECTING ); }); }); describe("can not contain a sphere", function () { it("past the far plane", function () { var sphere8 = BoundingSphere.fromPoints([ new Cartesian3(0, 0, -2.25), new Cartesian3(0, 0, -2.75), ]); testWithAndWithoutPlaneMask(cullingVolume, sphere8, Intersect.OUTSIDE); }); it("before the near plane", function () { var sphere9 = BoundingSphere.fromPoints([ new Cartesian3(0, 0, -0.25), new Cartesian3(0, 0, -0.5), ]); testWithAndWithoutPlaneMask(cullingVolume, sphere9, Intersect.OUTSIDE); }); it("past the left plane", function () { var sphere10 = BoundingSphere.fromPoints([ new Cartesian3(-5, 0, -1.25), new Cartesian3(-4.5, 0, -1.75), ]); testWithAndWithoutPlaneMask(cullingVolume, sphere10, Intersect.OUTSIDE); }); it("past the right plane", function () { var sphere11 = BoundingSphere.fromPoints([ new Cartesian3(4.5, 0, -1.25), new Cartesian3(5, 0, -1.75), ]); testWithAndWithoutPlaneMask(cullingVolume, sphere11, Intersect.OUTSIDE); }); it("past the top plane", function () { var sphere12 = BoundingSphere.fromPoints([ new Cartesian3(-0.5, 4.5, -1.25), new Cartesian3(-0.5, 5, -1.25), ]); testWithAndWithoutPlaneMask(cullingVolume, sphere12, Intersect.OUTSIDE); }); it("past the bottom plane", function () { var sphere13 = BoundingSphere.fromPoints([ new Cartesian3(-0.5, -4.5, -1.25), new Cartesian3(-0.5, -5, -1.25), ]); testWithAndWithoutPlaneMask(cullingVolume, sphere13, Intersect.OUTSIDE); }); }); }); describe("construct from bounding sphere", function () { var boundingSphereCullingVolume = new BoundingSphere( new Cartesian3(1000.0, 2000.0, 3000.0), 100.0 ); var cullingVolume = CullingVolume.fromBoundingSphere( boundingSphereCullingVolume ); it("throws without a boundingSphere", function () { expect(function () { CullingVolume.fromBoundingSphere(undefined); }).toThrowDeveloperError(); }); it("can contain a volume", function () { var sphere1 = BoundingSphere.clone(boundingSphereCullingVolume); sphere1.radius *= 0.5; testWithAndWithoutPlaneMask(cullingVolume, sphere1, Intersect.INSIDE); }); describe("can partially contain a volume", function () { it("on the far plane", function () { var offset = new Cartesian3( 0.0, 0.0, boundingSphereCullingVolume.radius * 1.5 ); var center = Cartesian3.add( boundingSphereCullingVolume.center, offset, new Cartesian3() ); var radius = boundingSphereCullingVolume.radius * 0.5; var sphere2 = new BoundingSphere(center, radius); testWithAndWithoutPlaneMask( cullingVolume, sphere2, Intersect.INTERSECTING ); }); it("on the near plane", function () { var offset = new Cartesian3( 0.0, 0.0, -boundingSphereCullingVolume.radius * 1.5 ); var center = Cartesian3.add( boundingSphereCullingVolume.center, offset, new Cartesian3() ); var radius = boundingSphereCullingVolume.radius * 0.5; var sphere3 = new BoundingSphere(center, radius); testWithAndWithoutPlaneMask( cullingVolume, sphere3, Intersect.INTERSECTING ); }); it("on the left plane", function () { var offset = new Cartesian3( -boundingSphereCullingVolume.radius * 1.5, 0.0, 0.0 ); var center = Cartesian3.add( boundingSphereCullingVolume.center, offset, new Cartesian3() ); var radius = boundingSphereCullingVolume.radius * 0.5; var sphere4 = new BoundingSphere(center, radius); testWithAndWithoutPlaneMask( cullingVolume, sphere4, Intersect.INTERSECTING ); }); it("on the right plane", function () { var offset = new Cartesian3( boundingSphereCullingVolume.radius * 1.5, 0.0, 0.0 ); var center = Cartesian3.add( boundingSphereCullingVolume.center, offset, new Cartesian3() ); var radius = boundingSphereCullingVolume.radius * 0.5; var sphere5 = new BoundingSphere(center, radius); testWithAndWithoutPlaneMask( cullingVolume, sphere5, Intersect.INTERSECTING ); }); it("on the top plane", function () { var offset = new Cartesian3( 0.0, boundingSphereCullingVolume.radius * 1.5, 0.0 ); var center = Cartesian3.add( boundingSphereCullingVolume.center, offset, new Cartesian3() ); var radius = boundingSphereCullingVolume.radius * 0.5; var sphere6 = new BoundingSphere(center, radius); testWithAndWithoutPlaneMask( cullingVolume, sphere6, Intersect.INTERSECTING ); }); it("on the bottom plane", function () { var offset = new Cartesian3( 0.0, -boundingSphereCullingVolume.radius * 1.5, 0.0 ); var center = Cartesian3.add( boundingSphereCullingVolume.center, offset, new Cartesian3() ); var radius = boundingSphereCullingVolume.radius * 0.5; var sphere7 = new BoundingSphere(center, radius); testWithAndWithoutPlaneMask( cullingVolume, sphere7, Intersect.INTERSECTING ); }); }); describe("can not contain a volume", function () { it("past the far plane", function () { var offset = new Cartesian3( 0.0, 0.0, boundingSphereCullingVolume.radius * 2.0 ); var center = Cartesian3.add( boundingSphereCullingVolume.center, offset, new Cartesian3() ); var radius = boundingSphereCullingVolume.radius * 0.5; var sphere8 = new BoundingSphere(center, radius); testWithAndWithoutPlaneMask(cullingVolume, sphere8, Intersect.OUTSIDE); }); it("before the near plane", function () { var offset = new Cartesian3( 0.0, 0.0, -boundingSphereCullingVolume.radius * 2.0 ); var center = Cartesian3.add( boundingSphereCullingVolume.center, offset, new Cartesian3() ); var radius = boundingSphereCullingVolume.radius * 0.5; var sphere9 = new BoundingSphere(center, radius); testWithAndWithoutPlaneMask(cullingVolume, sphere9, Intersect.OUTSIDE); }); it("past the left plane", function () { var offset = new Cartesian3( -boundingSphereCullingVolume.radius * 2.0, 0.0, 0.0 ); var center = Cartesian3.add( boundingSphereCullingVolume.center, offset, new Cartesian3() ); var radius = boundingSphereCullingVolume.radius * 0.5; var sphere10 = new BoundingSphere(center, radius); testWithAndWithoutPlaneMask(cullingVolume, sphere10, Intersect.OUTSIDE); }); it("past the right plane", function () { var offset = new Cartesian3( boundingSphereCullingVolume.radius * 2.0, 0.0, 0.0 ); var center = Cartesian3.add( boundingSphereCullingVolume.center, offset, new Cartesian3() ); var radius = boundingSphereCullingVolume.radius * 0.5; var sphere11 = new BoundingSphere(center, radius); testWithAndWithoutPlaneMask(cullingVolume, sphere11, Intersect.OUTSIDE); }); it("past the top plane", function () { var offset = new Cartesian3( 0.0, boundingSphereCullingVolume.radius * 2.0, 0.0 ); var center = Cartesian3.add( boundingSphereCullingVolume.center, offset, new Cartesian3() ); var radius = boundingSphereCullingVolume.radius * 0.5; var sphere12 = new BoundingSphere(center, radius); testWithAndWithoutPlaneMask(cullingVolume, sphere12, Intersect.OUTSIDE); }); it("past the bottom plane", function () { var offset = new Cartesian3( 0.0, -boundingSphereCullingVolume.radius * 2.0, 0.0 ); var center = Cartesian3.add( boundingSphereCullingVolume.center, offset, new Cartesian3() ); var radius = boundingSphereCullingVolume.radius * 0.5; var sphere13 = new BoundingSphere(center, radius); testWithAndWithoutPlaneMask(cullingVolume, sphere13, Intersect.OUTSIDE); }); }); }); });