import { BoundingSphere } from "../../Source/Cesium.js"; import { Cartesian3 } from "../../Source/Cesium.js"; import { Ellipsoid } from "../../Source/Cesium.js"; import { Math as CesiumMath } from "../../Source/Cesium.js"; import { Occluder } from "../../Source/Cesium.js"; import { Rectangle } from "../../Source/Cesium.js"; import { Visibility } from "../../Source/Cesium.js"; describe("Core/Occluder", function () { it("throws an exception during construction (1 of 3)", function () { expect(function () { return new Occluder(); }).toThrowDeveloperError(); }); it("throws an exception during construction (2 of 3)", function () { expect(function () { return new Occluder(new BoundingSphere(new Cartesian3(0, 0, 0))); }).toThrowDeveloperError(); }); it("throws an exception during construction (3 of 3)", function () { expect(function () { return new Occluder(new Cartesian3(0, 0, 0)); }).toThrowDeveloperError(); }); it("can entirely eclipse a smaller occludee", function () { var giantSphere = new BoundingSphere(new Cartesian3(0, 0, -1.5), 0.5); var littleSphere = new BoundingSphere(new Cartesian3(0, 0, -2.75), 0.25); var cameraPosition = Cartesian3.ZERO; var occluder = new Occluder(giantSphere, cameraPosition); expect(occluder.isBoundingSphereVisible(littleSphere)).toEqual(false); expect(occluder.computeVisibility(littleSphere)).toEqual(Visibility.NONE); }); it("can have a fully visible occludee", function () { var bigSphere = new BoundingSphere(new Cartesian3(0, 0, -1.5), 0.5); var littleSphere = new BoundingSphere(new Cartesian3(0, 0, -2.75), 0.25); var cameraPosition = Cartesian3.ZERO; var occluder = new Occluder(littleSphere, cameraPosition); expect(occluder.radius).toBeLessThan(bigSphere.radius); expect(occluder.isBoundingSphereVisible(bigSphere)).toEqual(true); expect(occluder.computeVisibility(bigSphere)).toEqual(Visibility.FULL); }); it("blocks the occludee when both are aligned and the same size", function () { var sphere1 = new BoundingSphere(new Cartesian3(0, 0, -1.5), 0.5); var sphere2 = new BoundingSphere(new Cartesian3(0, 0, -2.5), 0.5); var cameraPosition = Cartesian3.ZERO; var occluder = new Occluder(sphere1, cameraPosition); expect(occluder.isBoundingSphereVisible(sphere2)).toEqual(false); expect(occluder.computeVisibility(sphere2)).toEqual(Visibility.NONE); }); it("can have a fully visible occludee", function () { var sphere1 = new BoundingSphere(new Cartesian3(-1.25, 0, -1.5), 0.5); var sphere2 = new BoundingSphere(new Cartesian3(1.25, 0, -1.5), 0.5); var cameraPosition = Cartesian3.ZERO; var occluder = new Occluder(sphere1, cameraPosition); expect(occluder.computeVisibility(sphere2)).toEqual(Visibility.FULL); }); it("can partially block an occludee without intersecting", function () { var cameraPosition = Cartesian3.ZERO; var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -2), 1); var occluder = new Occluder(occluderBS, cameraPosition); var occludeeBS = new BoundingSphere(new Cartesian3(0.5, 0.5, -3), 1); expect(occluder.computeVisibility(occludeeBS)).toEqual(Visibility.PARTIAL); }); it("can partially block an occludee when it intersects laterally", function () { var cameraPosition = Cartesian3.ZERO; var occluderBS = new BoundingSphere(new Cartesian3(-0.5, 0, -1), 1); var occluder = new Occluder(occluderBS, cameraPosition); var occludeeBS = new BoundingSphere(new Cartesian3(0.5, 0, -1), 1); expect(occluder.computeVisibility(occludeeBS)).toEqual(Visibility.PARTIAL); }); it("can partially block an occludee when it intersects vertically", function () { var cameraPosition = Cartesian3.ZERO; var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -2), 1); var occluder = new Occluder(occluderBS, cameraPosition); var occludeeBS = new BoundingSphere(new Cartesian3(0, 0.5, -2.5), 1); expect(occluder.computeVisibility(occludeeBS)).toEqual(Visibility.PARTIAL); }); it("reports full visibility when occludee is larger than occluder", function () { var littleSphere = new BoundingSphere(new Cartesian3(0, 0, -1.5), 0.5); var bigSphere = new BoundingSphere(new Cartesian3(0, 0, -3), 1); var cameraPosition = Cartesian3.ZERO; var occluder = new Occluder(littleSphere, cameraPosition); expect(occluder.computeVisibility(bigSphere)).toEqual(Visibility.FULL); }); it("computeVisibility throws without a bounding sphere", function () { var sphere = new BoundingSphere(new Cartesian3(0, 0, -1.5), 0.5); var cameraPosition = Cartesian3.ZERO; var occluder = new Occluder(sphere, cameraPosition); expect(function () { occluder.computeVisibility(); }).toThrowDeveloperError(); }); it("can throw errors during computeOccludeePoint (1 of 5)", function () { expect(function () { Occluder.computeOccludeePoint(); }).toThrowDeveloperError(); }); it("can throw errors during computeOccludeePoint (2 of 5)", function () { var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -5), 1); var occludeePosition = new Cartesian3(0, 0, -5); var positions = []; expect(function () { Occluder.computeOccludeePoint(occluderBS, occludeePosition, positions); }).toThrowDeveloperError(); }); it("can throw errors during computeOccludeePoint (3 of 5)", function () { var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -5), 1); var positions = []; expect(function () { Occluder.computeOccludeePoint( occluderBS, new Cartesian3(0, 0, -3), positions ); }).toThrowDeveloperError(); }); it("can throw errors during computeOccludeePoint (4 of 5)", function () { var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -5), 1); expect(function () { Occluder.computeOccludeePoint(occluderBS, new Cartesian3(0, 0, -3)); }).toThrowDeveloperError(); }); it("can throw errors during computeOccludeePoint (5 of 5)", function () { var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -5), 1); expect(function () { Occluder.computeOccludeePoint( occluderBS, new Cartesian3(0, 0, -5), new Cartesian3(0, 0, -3) ); }).toThrowDeveloperError(); }); it("can compute an occludee point", function () { var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -8), 2); var positions = [ new Cartesian3(-1.085, 0, -6.221), new Cartesian3(1.085, 0, -6.221), ]; var tileOccluderSphere = BoundingSphere.fromPoints(positions); var occludeePosition = tileOccluderSphere.center; var result = Occluder.computeOccludeePoint( occluderBS, occludeePosition, positions ); expect(result).toEqualEpsilon( new Cartesian3(0, 0, -5), CesiumMath.EPSILON1 ); }); it("can compute a rotation vector (major axis = 0)", function () { var cameraPosition = Cartesian3.ZERO; var occluderBS = new BoundingSphere(new Cartesian3(5, 0, 0), 2); var occluder = new Occluder(occluderBS, cameraPosition); var occludeeBS = new BoundingSphere(new Cartesian3(8, 0, 0), 1); var occludee = new Occluder(occludeeBS, cameraPosition); var occluderPosition = occluder.position; var occludeePosition = occludee.position; var occluderPlaneNormal = Cartesian3.normalize( Cartesian3.subtract(occludeePosition, occluderPosition, new Cartesian3()), new Cartesian3() ); var occluderPlaneD = -Cartesian3.dot(occluderPlaneNormal, occluderPosition); var tempVec0 = Cartesian3.abs( Cartesian3.clone(occluderPlaneNormal), new Cartesian3() ); var majorAxis = tempVec0.x > tempVec0.y ? 0 : 1; if ( (majorAxis === 0 && tempVec0.z > tempVec0.x) || (majorAxis === 1 && tempVec0.z > tempVec0.y) ) { majorAxis = 2; } expect(majorAxis).toEqual(0); var aRotationVector = Occluder._anyRotationVector( occluderPosition, occluderPlaneNormal, occluderPlaneD ); expect(aRotationVector).toBeTruthy(); }); it("can compute a rotation vector (major axis = 1)", function () { var cameraPosition = Cartesian3.ZERO; var occluderBS = new BoundingSphere(new Cartesian3(5, 0, 0), 2); var occluder = new Occluder(occluderBS, cameraPosition); var occludeeBS = new BoundingSphere(new Cartesian3(7, 2, 0), 1); var occludee = new Occluder(occludeeBS, cameraPosition); var occluderPosition = occluder.position; var occludeePosition = occludee.position; var occluderPlaneNormal = Cartesian3.normalize( Cartesian3.subtract(occludeePosition, occluderPosition, new Cartesian3()), new Cartesian3() ); var occluderPlaneD = -Cartesian3.dot(occluderPlaneNormal, occluderPosition); var tempVec0 = Cartesian3.abs( Cartesian3.clone(occluderPlaneNormal), new Cartesian3() ); var majorAxis = tempVec0.x > tempVec0.y ? 0 : 1; if ( (majorAxis === 0 && tempVec0.z > tempVec0.x) || (majorAxis === 1 && tempVec0.z > tempVec0.y) ) { majorAxis = 2; } expect(majorAxis).toEqual(1); var aRotationVector = Occluder._anyRotationVector( occluderPosition, occluderPlaneNormal, occluderPlaneD ); expect(aRotationVector).toBeTruthy(); }); it("can compute a rotation vector (major axis = 2)", function () { var cameraPosition = Cartesian3.ZERO; var occluderBS = new BoundingSphere(new Cartesian3(5, 0, 0), 2); var occluder = new Occluder(occluderBS, cameraPosition); var occludeeBS = new BoundingSphere(new Cartesian3(6, 0, 2), 1); var occludee = new Occluder(occludeeBS, cameraPosition); var occluderPosition = occluder.position; var occludeePosition = occludee.position; var occluderPlaneNormal = Cartesian3.normalize( Cartesian3.subtract(occludeePosition, occluderPosition, new Cartesian3()), new Cartesian3() ); var occluderPlaneD = -Cartesian3.dot(occluderPlaneNormal, occluderPosition); var tempVec0 = Cartesian3.abs( Cartesian3.clone(occluderPlaneNormal), new Cartesian3() ); var majorAxis = tempVec0.x > tempVec0.y ? 0 : 1; if ( (majorAxis === 0 && tempVec0.z > tempVec0.x) || (majorAxis === 1 && tempVec0.z > tempVec0.y) ) { majorAxis = 2; } expect(majorAxis).toEqual(2); var aRotationVector = Occluder._anyRotationVector( occluderPosition, occluderPlaneNormal, occluderPlaneD ); expect(aRotationVector).toBeTruthy(); }); it("can have an invisible occludee point", function () { var cameraPosition = new Cartesian3(0, 0, -8); var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -8), 2); var occluder = new Occluder(occluderBS, cameraPosition); var positions = [ new Cartesian3(-0.25, 0, -5.3), new Cartesian3(0.25, 0, -5.3), ]; var tileOccluderSphere = BoundingSphere.fromPoints(positions); var occludeePosition = tileOccluderSphere.center; var result = Occluder.computeOccludeePoint( occluderBS, occludeePosition, positions ); var bs = new BoundingSphere(result, 0.0); expect(occluder.isBoundingSphereVisible(bs)).toEqual(false); expect(occluder.computeVisibility(bs)).toEqual(Visibility.NONE); }); it("can have a visible occludee point", function () { var cameraPosition = new Cartesian3(3, 0, -8); var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -8), 2); var occluder = new Occluder(occluderBS, cameraPosition); var positions = [ new Cartesian3(-0.25, 0, -5.3), new Cartesian3(0.25, 0, -5.3), ]; var tileOccluderSphere = BoundingSphere.fromPoints(positions); var occludeePosition = tileOccluderSphere.center; var result = Occluder.computeOccludeePoint( occluderBS, occludeePosition, positions ); expect( occluder.isBoundingSphereVisible(new BoundingSphere(result, 0.0)) ).toEqual(true); }); it("compute occludee point from rectangle throws without a rectangle", function () { expect(function () { return Occluder.computeOccludeePointFromRectangle(); }).toThrowDeveloperError(); }); it("compute invalid occludee point from rectangle", function () { var rectangle = Rectangle.MAX_VALUE; expect(Occluder.computeOccludeePointFromRectangle(rectangle)).toEqual( undefined ); }); it("compute valid occludee point from rectangle", function () { var edge = Math.PI / 32.0; var rectangle = new Rectangle(-edge, -edge, edge, edge); var ellipsoid = Ellipsoid.WGS84; var positions = Rectangle.subsample(rectangle, ellipsoid); var bs = BoundingSphere.fromPoints(positions); var point = Occluder.computeOccludeePoint( new BoundingSphere(Cartesian3.ZERO, ellipsoid.minimumRadius), bs.center, positions ); var actual = Occluder.computeOccludeePointFromRectangle(rectangle); expect(actual).toEqual(point); }); it("fromBoundingSphere throws without a bounding sphere", function () { expect(function () { Occluder.fromBoundingSphere(); }).toThrowDeveloperError(); }); it("fromBoundingSphere throws without camera position", function () { expect(function () { Occluder.fromBoundingSphere(new BoundingSphere()); }).toThrowDeveloperError(); }); it("fromBoundingSphere without result parameter", function () { var cameraPosition = new Cartesian3(3, 0, -8); var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -8), 2); var occluder0 = new Occluder(occluderBS, cameraPosition); var occluder1 = Occluder.fromBoundingSphere(occluderBS, cameraPosition); expect(occluder1.position).toEqual(occluder0.position); expect(occluder1.radius).toEqual(occluder0.radius); }); it("fromBoundingSphere with result parameter", function () { var cameraPosition = new Cartesian3(3, 0, -8); var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -8), 2); var occluder0 = new Occluder(occluderBS, cameraPosition); var result = new Occluder(occluderBS, Cartesian3.ZERO); var occluder1 = Occluder.fromBoundingSphere( occluderBS, cameraPosition, result ); expect(occluder1).toBe(result); expect(occluder1.position).toEqual(occluder0.position); expect(occluder1.radius).toEqual(occluder0.radius); }); });