import { BoundingSphere } from "../../Source/Cesium.js"; import { Cartesian3 } from "../../Source/Cesium.js"; import { Cartesian4 } from "../../Source/Cesium.js"; import { Ellipsoid } from "../../Source/Cesium.js"; import { Intersect } from "../../Source/Cesium.js"; import { Math as CesiumMath } from "../../Source/Cesium.js"; import { Matrix3 } from "../../Source/Cesium.js"; import { Occluder } from "../../Source/Cesium.js"; import { OrientedBoundingBox } from "../../Source/Cesium.js"; import { Plane } from "../../Source/Cesium.js"; import { Quaternion } from "../../Source/Cesium.js"; import { Rectangle } from "../../Source/Cesium.js"; import createPackableSpecs from "../createPackableSpecs.js"; describe("Core/OrientedBoundingBox", function () { var positions = [ new Cartesian3(2.0, 0.0, 0.0), new Cartesian3(0.0, 3.0, 0.0), new Cartesian3(0.0, 0.0, 4.0), new Cartesian3(-2.0, 0.0, 0.0), new Cartesian3(0.0, -3.0, 0.0), new Cartesian3(0.0, 0.0, -4.0), ]; function rotatePositions(positions, axis, angle) { var points = []; var quaternion = Quaternion.fromAxisAngle(axis, angle); var rotation = Matrix3.fromQuaternion(quaternion); for (var i = 0; i < positions.length; ++i) { points.push( Matrix3.multiplyByVector(rotation, positions[i], new Cartesian3()) ); } return { points: points, rotation: rotation, }; } function translatePositions(positions, translation) { var points = []; for (var i = 0; i < positions.length; ++i) { points.push(Cartesian3.add(translation, positions[i], new Cartesian3())); } return points; } it("constructor sets expected default values", function () { var box = new OrientedBoundingBox(); expect(box.center).toEqual(Cartesian3.ZERO); expect(box.halfAxes).toEqual(Matrix3.ZERO); }); it("fromPoints constructs empty box with undefined positions", function () { var box = OrientedBoundingBox.fromPoints(undefined); expect(box.halfAxes).toEqual(Matrix3.ZERO); expect(box.center).toEqual(Cartesian3.ZERO); }); it("fromPoints constructs empty box with empty positions", function () { var box = OrientedBoundingBox.fromPoints([]); expect(box.halfAxes).toEqual(Matrix3.ZERO); expect(box.center).toEqual(Cartesian3.ZERO); }); it("fromPoints correct scale", function () { var box = OrientedBoundingBox.fromPoints(positions); expect(box.halfAxes).toEqual( Matrix3.fromScale(new Cartesian3(2.0, 3.0, 4.0)) ); expect(box.center).toEqual(Cartesian3.ZERO); }); it("fromPoints correct translation", function () { var translation = new Cartesian3(10.0, -20.0, 30.0); var points = translatePositions(positions, translation); var box = OrientedBoundingBox.fromPoints(points); expect(box.halfAxes).toEqual( Matrix3.fromScale(new Cartesian3(2.0, 3.0, 4.0)) ); expect(box.center).toEqual(translation); }); it("fromPoints rotation about z", function () { var result = rotatePositions( positions, Cartesian3.UNIT_Z, CesiumMath.PI_OVER_FOUR ); var points = result.points; var rotation = result.rotation; rotation[1] = -rotation[1]; rotation[3] = -rotation[3]; var box = OrientedBoundingBox.fromPoints(points); expect(box.halfAxes).toEqualEpsilon( Matrix3.multiplyByScale( rotation, new Cartesian3(3.0, 2.0, 4.0), new Matrix3() ), CesiumMath.EPSILON15 ); expect(box.center).toEqualEpsilon(Cartesian3.ZERO, CesiumMath.EPSILON15); }); it("fromPoints rotation about y", function () { var result = rotatePositions( positions, Cartesian3.UNIT_Y, CesiumMath.PI_OVER_FOUR ); var points = result.points; var rotation = result.rotation; rotation[2] = -rotation[2]; rotation[6] = -rotation[6]; var box = OrientedBoundingBox.fromPoints(points); expect(box.halfAxes).toEqualEpsilon( Matrix3.multiplyByScale( rotation, new Cartesian3(4.0, 3.0, 2.0), new Matrix3() ), CesiumMath.EPSILON15 ); expect(box.center).toEqualEpsilon(Cartesian3.ZERO, CesiumMath.EPSILON15); }); it("fromPoints rotation about x", function () { var result = rotatePositions( positions, Cartesian3.UNIT_X, CesiumMath.PI_OVER_FOUR ); var points = result.points; var rotation = result.rotation; rotation[5] = -rotation[5]; rotation[7] = -rotation[7]; var box = OrientedBoundingBox.fromPoints(points); expect(box.halfAxes).toEqualEpsilon( Matrix3.multiplyByScale( rotation, new Cartesian3(2.0, 4.0, 3.0), new Matrix3() ), CesiumMath.EPSILON15 ); expect(box.center).toEqualEpsilon(Cartesian3.ZERO, CesiumMath.EPSILON15); }); it("fromPoints rotation and translation", function () { var result = rotatePositions( positions, Cartesian3.UNIT_Z, CesiumMath.PI_OVER_FOUR ); var points = result.points; var rotation = result.rotation; rotation[1] = -rotation[1]; rotation[3] = -rotation[3]; var translation = new Cartesian3(-40.0, 20.0, -30.0); points = translatePositions(points, translation); var box = OrientedBoundingBox.fromPoints(points); expect(box.halfAxes).toEqualEpsilon( Matrix3.multiplyByScale( rotation, new Cartesian3(3.0, 2.0, 4.0), new Matrix3() ), CesiumMath.EPSILON14 ); expect(box.center).toEqualEpsilon(translation, CesiumMath.EPSILON15); }); it("fromRectangle sets correct default ellipsoid", function () { var rectangle = new Rectangle(-0.9, -1.2, 0.5, 0.7); var box1 = OrientedBoundingBox.fromRectangle(rectangle, 0.0, 0.0); var box2 = OrientedBoundingBox.fromRectangle( rectangle, 0.0, 0.0, Ellipsoid.WGS84 ); expect(box1.center).toEqualEpsilon(box2.center, CesiumMath.EPSILON15); expect(box1.halfAxes).toEqualEpsilon(box2.halfAxes, CesiumMath.EPSILON15); }); it("fromRectangle sets correct default heights", function () { var rectangle = new Rectangle(0.0, 0.0, 0.0, 0.0); var box = OrientedBoundingBox.fromRectangle( rectangle, undefined, undefined, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(1.0, 0.0, 0.0), CesiumMath.EPSILON15 ); var rotScale = Matrix3.ZERO; expect(box.halfAxes).toEqualEpsilon(rotScale, CesiumMath.EPSILON15); }); it("fromRectangle throws without rectangle", function () { var ellipsoid = Ellipsoid.UNIT_SPHERE; expect(function () { OrientedBoundingBox.fromRectangle(undefined, 0.0, 0.0, ellipsoid); }).toThrowDeveloperError(); }); it("fromRectangle throws with invalid rectangles", function () { var ellipsoid = Ellipsoid.UNIT_SPHERE; expect(function () { return OrientedBoundingBox.fromRectangle( new Rectangle(-1.0, 1.0, 1.0, -1.0), 0.0, 0.0, ellipsoid ); }).toThrowDeveloperError(); expect(function () { return OrientedBoundingBox.fromRectangle( new Rectangle(-2.0, 2.0, -1.0, 1.0), 0.0, 0.0, ellipsoid ); }).toThrowDeveloperError(); expect(function () { return OrientedBoundingBox.fromRectangle( new Rectangle(-4.0, -2.0, 4.0, 1.0), 0.0, 0.0, ellipsoid ); }).toThrowDeveloperError(); expect(function () { return OrientedBoundingBox.fromRectangle( new Rectangle(-2.0, -2.0, 1.0, 2.0), 0.0, 0.0, ellipsoid ); }).toThrowDeveloperError(); expect(function () { return OrientedBoundingBox.fromRectangle( new Rectangle(-1.0, -2.0, 2.0, 2.0), 0.0, 0.0, ellipsoid ); }).toThrowDeveloperError(); expect(function () { return OrientedBoundingBox.fromRectangle( new Rectangle(-4.0, -1.0, 4.0, 2.0), 0.0, 0.0, ellipsoid ); }).toThrowDeveloperError(); }); it("fromRectangle throws with non-revolution ellipsoids", function () { var rectangle = new Rectangle(0.0, 0.0, 0.0, 0.0); expect(function () { return OrientedBoundingBox.fromRectangle( rectangle, 0.0, 0.0, new Ellipsoid(1.01, 1.0, 1.01) ); }).toThrowDeveloperError(); expect(function () { return OrientedBoundingBox.fromRectangle( rectangle, 0.0, 0.0, new Ellipsoid(1.0, 1.01, 1.01) ); }).toThrowDeveloperError(); }); it("fromRectangle creates an OrientedBoundingBox without a result parameter", function () { var ellipsoid = Ellipsoid.UNIT_SPHERE; var rectangle = new Rectangle(0.0, 0.0, 0.0, 0.0); var box = OrientedBoundingBox.fromRectangle(rectangle, 0.0, 0.0, ellipsoid); expect(box.center).toEqualEpsilon( new Cartesian3(1.0, 0.0, 0.0), CesiumMath.EPSILON15 ); var rotScale = Matrix3.ZERO; expect(box.halfAxes).toEqualEpsilon(rotScale, CesiumMath.EPSILON15); }); it("fromRectangle creates an OrientedBoundingBox with a result parameter", function () { var ellipsoid = Ellipsoid.UNIT_SPHERE; var rectangle = new Rectangle(0.0, 0.0, 0.0, 0.0); var result = new OrientedBoundingBox(); var box = OrientedBoundingBox.fromRectangle( rectangle, 0.0, 0.0, ellipsoid, result ); expect(box).toBe(result); expect(box.center).toEqualEpsilon( new Cartesian3(1.0, 0.0, 0.0), CesiumMath.EPSILON15 ); var rotScale = Matrix3.ZERO; expect(box.halfAxes).toEqualEpsilon(rotScale, CesiumMath.EPSILON15); }); it("fromRectangle for rectangles with heights", function () { var d90 = CesiumMath.PI_OVER_TWO; var box; box = OrientedBoundingBox.fromRectangle( new Rectangle(0.0, 0.0, 0.0, 0.0), 1.0, 1.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(2.0, 0.0, 0.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon(Matrix3.ZERO, CesiumMath.EPSILON15); box = OrientedBoundingBox.fromRectangle( new Rectangle(0.0, 0.0, 0.0, 0.0), -1.0, -1.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0.0, 0.0, 0.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon(Matrix3.ZERO, CesiumMath.EPSILON15); box = OrientedBoundingBox.fromRectangle( new Rectangle(0.0, 0.0, 0.0, 0.0), -1.0, 1.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(1.0, 0.0, 0.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(0, 0, 1, 0, 0, 0, 0, 0, 0), CesiumMath.EPSILON15 ); box = OrientedBoundingBox.fromRectangle( new Rectangle(-d90, -d90, d90, d90), 0.0, 1.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(1.0, 0.0, 0.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(0, 0, 1, 2, 0, 0, 0, 2, 0), CesiumMath.EPSILON15 ); box = OrientedBoundingBox.fromRectangle( new Rectangle(-d90, -d90, d90, d90), -1.0, -1.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0.0, 0.0, 0.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon(Matrix3.ZERO, CesiumMath.EPSILON15); box = OrientedBoundingBox.fromRectangle( new Rectangle(-d90, -d90, d90, d90), -1.0, 0.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0.5, 0.0, 0.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(0, 0, 0.5, 1, 0, 0, 0, 1, 0), CesiumMath.EPSILON15 ); }); it("fromRectangle for rectangles that span over half the ellipsoid", function () { var d90 = CesiumMath.PI_OVER_TWO; var d180 = CesiumMath.PI; var d135 = (3.0 / 4.0) * CesiumMath.PI; var d45 = CesiumMath.PI_OVER_FOUR; var onePlusSqrtHalfDivTwo = (1.0 + Math.SQRT1_2) / 2.0; var oneMinusOnePlusSqrtHalfDivTwo = 1.0 - onePlusSqrtHalfDivTwo; var sqrtTwoMinusOneDivFour = (Math.SQRT2 - 1.0) / 4.0; var sqrtTwoPlusOneDivFour = (Math.SQRT2 + 1.0) / 4.0; var box; // Entire ellipsoid box = OrientedBoundingBox.fromRectangle( new Rectangle(-d180, -d90, d180, d90), 0, 0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0, 0, 0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(0, 0, 1, 1, 0, 0, 0, 1, 0), CesiumMath.EPSILON15 ); // 3/4s of longitude, full latitude box = OrientedBoundingBox.fromRectangle( new Rectangle(-d135, -d90, d135, d90), 0, 0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(oneMinusOnePlusSqrtHalfDivTwo, 0, 0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(0, 0, onePlusSqrtHalfDivTwo, 1, 0, 0, 0, 1, 0), CesiumMath.EPSILON15 ); // 3/4s of longitude, 1/2 of latitude centered at equator box = OrientedBoundingBox.fromRectangle( new Rectangle(-d135, -d45, d135, d45), 0, 0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(oneMinusOnePlusSqrtHalfDivTwo, 0, 0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(0, 0, onePlusSqrtHalfDivTwo, 1, 0, 0, 0, Math.SQRT1_2, 0), CesiumMath.EPSILON15 ); // 3/4s of longitude centered at IDL, 1/2 of latitude centered at equator box = OrientedBoundingBox.fromRectangle( new Rectangle(d180, -d45, d90, d45), 0, 0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(sqrtTwoMinusOneDivFour, -sqrtTwoMinusOneDivFour, 0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3( Math.SQRT1_2, 0, sqrtTwoPlusOneDivFour, Math.SQRT1_2, 0, -sqrtTwoPlusOneDivFour, 0, Math.SQRT1_2, 0.0 ), CesiumMath.EPSILON15 ); // Full longitude, 1/2 of latitude centered at equator box = OrientedBoundingBox.fromRectangle( new Rectangle(-d180, -d45, d180, d45), 0, 0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0, 0, 0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(0, 0, 1, 1, 0, 0, 0, Math.SQRT1_2, 0), CesiumMath.EPSILON15 ); // Full longitude, 1/4 of latitude starting from north pole box = OrientedBoundingBox.fromRectangle( new Rectangle(-d180, d45, d180, d90), 0, 0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0, 0, onePlusSqrtHalfDivTwo), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3( 0, 0, Math.SQRT1_2, Math.SQRT1_2, 0, 0, 0, oneMinusOnePlusSqrtHalfDivTwo, 0 ), CesiumMath.EPSILON15 ); // Full longitude, 1/4 of latitude starting from south pole box = OrientedBoundingBox.fromRectangle( new Rectangle(-d180, -d90, d180, -d45), 0, 0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0, 0, -onePlusSqrtHalfDivTwo), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3( 0, 0, Math.SQRT1_2, Math.SQRT1_2, 0, 0, 0, oneMinusOnePlusSqrtHalfDivTwo, 0 ), CesiumMath.EPSILON15 ); // Cmpletely on north pole box = OrientedBoundingBox.fromRectangle( new Rectangle(-d180, d90, d180, d90), 0, 0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0, 0, 1), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(0, 0, 0, 0, 0, 0, 0, 0, 0), CesiumMath.EPSILON15 ); // Completely on north pole 2 box = OrientedBoundingBox.fromRectangle( new Rectangle(-d135, d90, d135, d90), 0, 0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0, 0, 1), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(0, 0, 0, 0, 0, 0, 0, 0, 0), CesiumMath.EPSILON15 ); // Completely on south pole box = OrientedBoundingBox.fromRectangle( new Rectangle(-d180, -d90, d180, -d90), 0, 0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0, 0, -1), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(0, 0, 0, 0, 0, 0, 0, 0, 0), CesiumMath.EPSILON15 ); // Completely on south pole 2 box = OrientedBoundingBox.fromRectangle( new Rectangle(-d135, -d90, d135, -d90), 0, 0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0, 0, -1), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(0, 0, 0, 0, 0, 0, 0, 0, 0), CesiumMath.EPSILON15 ); }); it("fromRectangle for interesting, degenerate, and edge-case rectangles", function () { var d45 = CesiumMath.PI_OVER_FOUR; var d30 = CesiumMath.PI_OVER_SIX; var d90 = CesiumMath.PI_OVER_TWO; var d135 = 3 * CesiumMath.PI_OVER_FOUR; var d180 = CesiumMath.PI; var sqrt3 = Math.sqrt(3.0); var box; box = OrientedBoundingBox.fromRectangle( new Rectangle(0.0, 0.0, 0.0, 0.0), 0.0, 0.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(1.0, 0.0, 0.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon(Matrix3.ZERO, CesiumMath.EPSILON15); box = OrientedBoundingBox.fromRectangle( new Rectangle(d180, 0.0, -d180, 0.0), 0.0, 0.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(-1.0, 0.0, 0.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon(Matrix3.ZERO, CesiumMath.EPSILON15); box = OrientedBoundingBox.fromRectangle( new Rectangle(d180, 0.0, d180, 0.0), 0.0, 0.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(-1.0, 0.0, 0.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon(Matrix3.ZERO, CesiumMath.EPSILON15); box = OrientedBoundingBox.fromRectangle( new Rectangle(0.0, d90, 0.0, d90), 0.0, 0.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0.0, 0.0, 1.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon(Matrix3.ZERO, CesiumMath.EPSILON15); box = OrientedBoundingBox.fromRectangle( new Rectangle(0.0, 0.0, d180, 0.0), 0.0, 0.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0.0, 0.5, 0.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(-1.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0), CesiumMath.EPSILON15 ); box = OrientedBoundingBox.fromRectangle( new Rectangle(-d90, -d90, d90, d90), 0.0, 0.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0.5, 0.0, 0.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(0.0, 0.0, 0.5, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0), CesiumMath.EPSILON15 ); box = OrientedBoundingBox.fromRectangle( new Rectangle(-d90, -d30, d90, d90), 0.0, 0.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0.1875 * sqrt3, 0.0, 0.1875), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(0, -sqrt3 / 4, (5 * sqrt3) / 16, 1, 0, 0, 0, 3 / 4, 5 / 16), CesiumMath.EPSILON15 ); box = OrientedBoundingBox.fromRectangle( new Rectangle(-d90, -d90, d90, d30), 0.0, 0.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0.1875 * sqrt3, 0.0, -0.1875), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(0, sqrt3 / 4, (5 * sqrt3) / 16, 1, 0, 0, 0, 3 / 4, -5 / 16), CesiumMath.EPSILON15 ); box = OrientedBoundingBox.fromRectangle( new Rectangle(0.0, -d30, d180, d90), 0.0, 0.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0.0, 0.1875 * sqrt3, 0.1875), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(-1, 0, 0, 0, -sqrt3 / 4, (5 * sqrt3) / 16, 0, 3 / 4, 5 / 16), CesiumMath.EPSILON15 ); box = OrientedBoundingBox.fromRectangle( new Rectangle(0.0, -d90, d180, d30), 0.0, 0.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0.0, 0.1875 * sqrt3, -0.1875), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(-1, 0, 0, 0, sqrt3 / 4, (5 * sqrt3) / 16, 0, 3 / 4, -5 / 16), CesiumMath.EPSILON15 ); box = OrientedBoundingBox.fromRectangle( new Rectangle(-d45, 0.0, d45, 0.0), 0.0, 0.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3((1.0 + Math.SQRT1_2) / 2.0, 0.0, 0.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3( 0.0, 0.0, 0.5 * (1.0 - Math.SQRT1_2), Math.SQRT1_2, 0.0, 0.0, 0.0, 0.0, 0.0 ), CesiumMath.EPSILON15 ); box = OrientedBoundingBox.fromRectangle( new Rectangle(d135, 0.0, -d135, 0.0), 0.0, 0.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(-(1.0 + Math.SQRT1_2) / 2.0, 0.0, 0.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3( 0.0, 0.0, -0.5 * (1.0 - Math.SQRT1_2), -Math.SQRT1_2, 0.0, 0.0, 0.0, 0.0, 0.0 ), CesiumMath.EPSILON15 ); box = OrientedBoundingBox.fromRectangle( new Rectangle(0.0, -d45, 0.0, d45), 0.0, 0.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3((1.0 + Math.SQRT1_2) / 2.0, 0.0, 0.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3( 0.0, 0.0, 0.5 * (1.0 - Math.SQRT1_2), 0.0, 0.0, 0.0, 0.0, Math.SQRT1_2, 0.0 ), CesiumMath.EPSILON15 ); box = OrientedBoundingBox.fromRectangle( new Rectangle(-d90, 0.0, d90, 0.0), 0.0, 0.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0.5, 0.0, 0.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(0.0, 0.0, 0.5, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0), CesiumMath.EPSILON15 ); box = OrientedBoundingBox.fromRectangle( new Rectangle(0.0, -d90, 0.0, d90), 0.0, 0.0, Ellipsoid.UNIT_SPHERE ); expect(box.center).toEqualEpsilon( new Cartesian3(0.5, 0.0, 0.0), CesiumMath.EPSILON15 ); expect(box.halfAxes).toEqualEpsilon( new Matrix3(0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0), CesiumMath.EPSILON15 ); }); var intersectPlaneTestCornersEdgesFaces = function (center, axes) { var SQRT1_2 = Math.pow(1.0 / 2.0, 1 / 2.0); var SQRT3_4 = Math.pow(3.0 / 4.0, 1 / 2.0); var box = new OrientedBoundingBox( center, Matrix3.multiplyByScalar(axes, 0.5, new Matrix3()) ); var planeNormXform = function (nx, ny, nz, dist) { var n = new Cartesian3(nx, ny, nz); var arb = new Cartesian3(357, 924, 258); var p0 = Cartesian3.normalize(n, new Cartesian3()); Cartesian3.multiplyByScalar(p0, -dist, p0); var tang = Cartesian3.cross(n, arb, new Cartesian3()); Cartesian3.normalize(tang, tang); var binorm = Cartesian3.cross(n, tang, new Cartesian3()); Cartesian3.normalize(binorm, binorm); Matrix3.multiplyByVector(axes, p0, p0); Matrix3.multiplyByVector(axes, tang, tang); Matrix3.multiplyByVector(axes, binorm, binorm); Cartesian3.cross(tang, binorm, n); if (Cartesian3.magnitude(n) === 0) { return undefined; } Cartesian3.normalize(n, n); Cartesian3.add(p0, center, p0); var d = -Cartesian3.dot(p0, n); if (Math.abs(d) > 0.0001 && Cartesian3.magnitudeSquared(n) > 0.0001) { return new Plane(n, d); } return undefined; }; var pl; // Tests against faces pl = planeNormXform(+1.0, +0.0, +0.0, 0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(-1.0, +0.0, +0.0, 0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+0.0, +1.0, +0.0, 0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+0.0, -1.0, +0.0, 0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+0.0, +0.0, +1.0, 0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+0.0, +0.0, -1.0, 0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+1.0, +0.0, +0.0, 0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, +0.0, +0.0, 0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+0.0, +1.0, +0.0, 0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+0.0, -1.0, +0.0, 0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+0.0, +0.0, +1.0, 0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+0.0, +0.0, -1.0, 0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, +0.0, +0.0, -0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, +0.0, +0.0, -0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+0.0, +1.0, +0.0, -0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+0.0, -1.0, +0.0, -0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+0.0, +0.0, +1.0, -0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+0.0, +0.0, -1.0, -0.49999); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, +0.0, +0.0, -0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(-1.0, +0.0, +0.0, -0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(+0.0, +1.0, +0.0, -0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(+0.0, -1.0, +0.0, -0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(+0.0, +0.0, +1.0, -0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(+0.0, +0.0, -1.0, -0.50001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } // Tests against edges pl = planeNormXform(+1.0, +1.0, +0.0, SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+1.0, -1.0, +0.0, SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(-1.0, +1.0, +0.0, SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(-1.0, -1.0, +0.0, SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+1.0, +0.0, +1.0, SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+1.0, +0.0, -1.0, SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(-1.0, +0.0, +1.0, SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(-1.0, +0.0, -1.0, SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+0.0, +1.0, +1.0, SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+0.0, +1.0, -1.0, SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+0.0, -1.0, +1.0, SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+0.0, -1.0, -1.0, SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+1.0, +1.0, +0.0, SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, -1.0, +0.0, SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, +1.0, +0.0, SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, -1.0, +0.0, SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, +0.0, +1.0, SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, +0.0, -1.0, SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, +0.0, +1.0, SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, +0.0, -1.0, SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+0.0, +1.0, +1.0, SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+0.0, +1.0, -1.0, SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+0.0, -1.0, +1.0, SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+0.0, -1.0, -1.0, SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, +1.0, +0.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, -1.0, +0.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, +1.0, +0.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, -1.0, +0.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, +0.0, +1.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, +0.0, -1.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, +0.0, +1.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, +0.0, -1.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+0.0, +1.0, +1.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+0.0, +1.0, -1.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+0.0, -1.0, +1.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+0.0, -1.0, -1.0, -SQRT1_2 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, +1.0, +0.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(+1.0, -1.0, +0.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(-1.0, +1.0, +0.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(-1.0, -1.0, +0.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(+1.0, +0.0, +1.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(+1.0, +0.0, -1.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(-1.0, +0.0, +1.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(-1.0, +0.0, -1.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(+0.0, +1.0, +1.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(+0.0, +1.0, -1.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(+0.0, -1.0, +1.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(+0.0, -1.0, -1.0, -SQRT1_2 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } // Tests against corners pl = planeNormXform(+1.0, +1.0, +1.0, SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+1.0, +1.0, -1.0, SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+1.0, -1.0, +1.0, SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+1.0, -1.0, -1.0, SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(-1.0, +1.0, +1.0, SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(-1.0, +1.0, -1.0, SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(-1.0, -1.0, +1.0, SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(-1.0, -1.0, -1.0, SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INSIDE); } pl = planeNormXform(+1.0, +1.0, +1.0, SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, +1.0, -1.0, SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, -1.0, +1.0, SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, -1.0, -1.0, SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, +1.0, +1.0, SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, +1.0, -1.0, SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, -1.0, +1.0, SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, -1.0, -1.0, SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, +1.0, +1.0, -SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, +1.0, -1.0, -SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, -1.0, +1.0, -SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, -1.0, -1.0, -SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, +1.0, +1.0, -SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, +1.0, -1.0, -SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, -1.0, +1.0, -SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(-1.0, -1.0, -1.0, -SQRT3_4 + 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.INTERSECTING); } pl = planeNormXform(+1.0, +1.0, +1.0, -SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(+1.0, +1.0, -1.0, -SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(+1.0, -1.0, +1.0, -SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(+1.0, -1.0, -1.0, -SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(-1.0, +1.0, +1.0, -SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(-1.0, +1.0, -1.0, -SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(-1.0, -1.0, +1.0, -SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } pl = planeNormXform(-1.0, -1.0, -1.0, -SQRT3_4 - 0.00001); if (pl) { expect(box.intersectPlane(pl)).toEqual(Intersect.OUTSIDE); } }; it("intersectPlane works with untransformed box", function () { intersectPlaneTestCornersEdgesFaces(Cartesian3.ZERO, Matrix3.IDENTITY); }); it("intersectPlane works with off-center box", function () { intersectPlaneTestCornersEdgesFaces( new Cartesian3(1.0, 0.0, 0.0), Matrix3.IDENTITY ); intersectPlaneTestCornersEdgesFaces( new Cartesian3(0.7, -1.8, 12.0), Matrix3.IDENTITY ); }); it("intersectPlane works with rotated box", function () { intersectPlaneTestCornersEdgesFaces( Cartesian3.ZERO, Matrix3.fromQuaternion( Quaternion.fromAxisAngle(new Cartesian3(0.5, 1.5, -1.2), 1.2), new Matrix3() ) ); }); it("intersectPlane works with scaled box", function () { var m = new Matrix3(); intersectPlaneTestCornersEdgesFaces( Cartesian3.ZERO, Matrix3.fromScale(new Cartesian3(1.5, 0.4, 20.6), m) ); intersectPlaneTestCornersEdgesFaces( Cartesian3.ZERO, Matrix3.fromScale(new Cartesian3(0.0, 0.4, 20.6), m) ); intersectPlaneTestCornersEdgesFaces( Cartesian3.ZERO, Matrix3.fromScale(new Cartesian3(1.5, 0.0, 20.6), m) ); intersectPlaneTestCornersEdgesFaces( Cartesian3.ZERO, Matrix3.fromScale(new Cartesian3(1.5, 0.4, 0.0), m) ); intersectPlaneTestCornersEdgesFaces( Cartesian3.ZERO, Matrix3.fromScale(new Cartesian3(0.0, 0.0, 0.0), m) ); }); it("intersectPlane works with this arbitrary box", function () { var m = Matrix3.fromScale(new Cartesian3(1.5, 80.4, 2.6), new Matrix3()); var n = Matrix3.fromQuaternion( Quaternion.fromAxisAngle(new Cartesian3(0.5, 1.5, -1.2), 1.2), new Matrix3() ); Matrix3.multiply(m, n, n); intersectPlaneTestCornersEdgesFaces(new Cartesian3(-5.1, 0.0, 0.1), n); }); it("intersectPlane fails without box parameter", function () { var plane = new Cartesian4(1.0, 0.0, 0.0, 0.0); expect(function () { OrientedBoundingBox.intersectPlane(undefined, plane); }).toThrowDeveloperError(); }); it("intersectPlane fails without plane parameter", function () { var box = new OrientedBoundingBox(Cartesian3.IDENTITY, Matrix3.ZERO); expect(function () { OrientedBoundingBox.intersectPlane(box, undefined); }).toThrowDeveloperError(); }); it("distanceSquaredTo", function () { var r0 = Matrix3.fromRotationZ(CesiumMath.toRadians(-45.0)); var r1 = Matrix3.fromRotationY(CesiumMath.toRadians(45.0)); var rotation = Matrix3.multiply(r1, r0, r0); var scale = new Cartesian3(2.0, 3.0, 4.0); var rotationScale = Matrix3.multiplyByScale(rotation, scale, rotation); var center = new Cartesian3(4.0, 3.0, 2.0); var obb = new OrientedBoundingBox(center, rotationScale); var halfAxes = obb.halfAxes; var xAxis = Matrix3.getColumn(halfAxes, 0, new Cartesian3()); var yAxis = Matrix3.getColumn(halfAxes, 1, new Cartesian3()); var zAxis = Matrix3.getColumn(halfAxes, 2, new Cartesian3()); // from positive x direction var cartesian = Cartesian3.multiplyByScalar(xAxis, 2.0, new Cartesian3()); Cartesian3.add(cartesian, center, cartesian); var d = Cartesian3.distance(cartesian, center) - scale.x; var expected = d * d; expect(obb.distanceSquaredTo(cartesian)).toEqualEpsilon( expected, CesiumMath.EPSILON10 ); // from negative x direction Cartesian3.multiplyByScalar(xAxis, -2.0, cartesian); Cartesian3.add(cartesian, center, cartesian); d = Cartesian3.distance(cartesian, center) - scale.x; expected = d * d; expect(obb.distanceSquaredTo(cartesian)).toEqualEpsilon( expected, CesiumMath.EPSILON10 ); // from positive y direction Cartesian3.multiplyByScalar(yAxis, 2.0, cartesian); Cartesian3.add(cartesian, center, cartesian); d = Cartesian3.distance(cartesian, center) - scale.y; expected = d * d; expect(obb.distanceSquaredTo(cartesian)).toEqualEpsilon( expected, CesiumMath.EPSILON10 ); // from negative y direction Cartesian3.multiplyByScalar(yAxis, -2.0, cartesian); Cartesian3.add(cartesian, center, cartesian); d = Cartesian3.distance(cartesian, center) - scale.y; expected = d * d; expect(obb.distanceSquaredTo(cartesian)).toEqualEpsilon( expected, CesiumMath.EPSILON10 ); // from positive z direction Cartesian3.multiplyByScalar(zAxis, 2.0, cartesian); Cartesian3.add(cartesian, center, cartesian); d = Cartesian3.distance(cartesian, center) - scale.z; expected = d * d; expect(obb.distanceSquaredTo(cartesian)).toEqualEpsilon( expected, CesiumMath.EPSILON10 ); // from negative z direction Cartesian3.multiplyByScalar(zAxis, -2.0, cartesian); Cartesian3.add(cartesian, center, cartesian); d = Cartesian3.distance(cartesian, center) - scale.z; expected = d * d; expect(obb.distanceSquaredTo(cartesian)).toEqualEpsilon( expected, CesiumMath.EPSILON10 ); // from corner point Cartesian3.add(xAxis, yAxis, cartesian); Cartesian3.add(zAxis, cartesian, cartesian); var cornerDistance = Cartesian3.magnitude(cartesian); Cartesian3.add(cartesian, center, cartesian); d = Cartesian3.distance(cartesian, center) - cornerDistance; expected = d * d; expect(obb.distanceSquaredTo(cartesian)).toEqualEpsilon( expected, CesiumMath.EPSILON10 ); }); it("distanceSquaredTo throws without box", function () { expect(function () { OrientedBoundingBox.distanceSquaredTo(undefined, new Cartesian3()); }).toThrowDeveloperError(); }); it("distanceSquaredTo throws without cartesian", function () { expect(function () { OrientedBoundingBox.distanceSquaredTo( new OrientedBoundingBox(), undefined ); }).toThrowDeveloperError(); }); it("computePlaneDistances", function () { var r0 = Matrix3.fromRotationZ(CesiumMath.toRadians(-45.0)); var r1 = Matrix3.fromRotationY(CesiumMath.toRadians(45.0)); var rotation = Matrix3.multiply(r1, r0, r0); var scale = new Cartesian3(2.0, 3.0, 4.0); var rotationScale = Matrix3.multiplyByScale(rotation, scale, rotation); var center = new Cartesian3(4.0, 3.0, 2.0); var obb = new OrientedBoundingBox(center, rotationScale); var halfAxes = obb.halfAxes; var xAxis = Matrix3.getColumn(halfAxes, 0, new Cartesian3()); var yAxis = Matrix3.getColumn(halfAxes, 1, new Cartesian3()); var zAxis = Matrix3.getColumn(halfAxes, 2, new Cartesian3()); // from x direction var position = Cartesian3.multiplyByScalar(xAxis, 2.0, new Cartesian3()); Cartesian3.add(position, center, position); var direction = Cartesian3.negate(xAxis, new Cartesian3()); Cartesian3.normalize(direction, direction); var d = Cartesian3.distance(position, center); var expectedNear = d - scale.x; var expectedFar = d + scale.x; var distances = obb.computePlaneDistances(position, direction); expect(distances.start).toEqualEpsilon(expectedNear, CesiumMath.EPSILON14); expect(distances.stop).toEqualEpsilon(expectedFar, CesiumMath.EPSILON14); // from y direction Cartesian3.multiplyByScalar(yAxis, 2.0, position); Cartesian3.add(position, center, position); Cartesian3.negate(yAxis, direction); Cartesian3.normalize(direction, direction); d = Cartesian3.distance(position, center); expectedNear = d - scale.y; expectedFar = d + scale.y; obb.computePlaneDistances(position, direction, distances); expect(distances.start).toEqualEpsilon(expectedNear, CesiumMath.EPSILON14); expect(distances.stop).toEqualEpsilon(expectedFar, CesiumMath.EPSILON14); // from z direction Cartesian3.multiplyByScalar(zAxis, 2.0, position); Cartesian3.add(position, center, position); Cartesian3.negate(zAxis, direction); Cartesian3.normalize(direction, direction); d = Cartesian3.distance(position, center); expectedNear = d - scale.z; expectedFar = d + scale.z; obb.computePlaneDistances(position, direction, distances); expect(distances.start).toEqualEpsilon(expectedNear, CesiumMath.EPSILON14); expect(distances.stop).toEqualEpsilon(expectedFar, CesiumMath.EPSILON14); // from corner point Cartesian3.add(xAxis, yAxis, position); Cartesian3.add(zAxis, position, position); Cartesian3.negate(position, direction); Cartesian3.normalize(direction, direction); var cornerDistance = Cartesian3.magnitude(position); Cartesian3.add(position, center, position); d = Cartesian3.distance(position, center); expectedNear = d - cornerDistance; expectedFar = d + cornerDistance; obb.computePlaneDistances(position, direction, distances); expect(distances.start).toEqualEpsilon(expectedNear, CesiumMath.EPSILON14); expect(distances.stop).toEqualEpsilon(expectedFar, CesiumMath.EPSILON14); }); it("computePlaneDistances throws without a box", function () { expect(function () { OrientedBoundingBox.computePlaneDistances( undefined, new Cartesian3(), new Cartesian3() ); }).toThrowDeveloperError(); }); it("computePlaneDistances throws without a position", function () { expect(function () { OrientedBoundingBox.computePlaneDistances( new OrientedBoundingBox(), undefined, new Cartesian3() ); }).toThrowDeveloperError(); }); it("computePlaneDistances throws without a direction", function () { expect(function () { OrientedBoundingBox.computePlaneDistances( new OrientedBoundingBox(), new Cartesian3(), undefined ); }).toThrowDeveloperError(); }); it("isOccluded", function () { var occluderSphere = new BoundingSphere(new Cartesian3(0, 0, -1.5), 0.5); var occluder = new Occluder(occluderSphere, Cartesian3.ZERO); var radius = 0.25 / Math.sqrt(2.0); var halfAxes = Matrix3.multiplyByScale( Matrix3.IDENTITY, new Cartesian3(radius, radius, radius), new Matrix3() ); var obb = new OrientedBoundingBox(new Cartesian3(0, 0, -2.75), halfAxes); expect(obb.isOccluded(occluder)).toEqual(true); occluderSphere = new BoundingSphere(new Cartesian3(0, 0, -2.75), 0.25); occluder = new Occluder(occluderSphere, Cartesian3.ZERO); radius = 0.5 / Math.sqrt(2.0); halfAxes = Matrix3.multiplyByScale( Matrix3.IDENTITY, new Cartesian3(radius, radius, radius), new Matrix3() ); obb = new OrientedBoundingBox(new Cartesian3(0, 0, -1.5), halfAxes); expect(obb.isOccluded(occluder)).toEqual(false); }); it("isOccluded throws without a box", function () { expect(function () { OrientedBoundingBox.isOccluded( undefined, new Occluder(new BoundingSphere(), new Cartesian3()) ); }).toThrowDeveloperError(); }); it("isOccluded throws without a occluder", function () { expect(function () { OrientedBoundingBox.isOccluded(new OrientedBoundingBox(), undefined); }).toThrowDeveloperError(); }); it("clone without a result parameter", function () { var box = new OrientedBoundingBox(); var result = OrientedBoundingBox.clone(box); expect(box).not.toBe(result); expect(box).toEqual(result); expect(box.clone()).toEqual(box); }); it("clone with a result parameter", function () { var box = new OrientedBoundingBox(); var box2 = new OrientedBoundingBox(); var result = new OrientedBoundingBox(); var returnedResult = OrientedBoundingBox.clone(box, result); expect(result).toBe(returnedResult); expect(box).not.toBe(result); expect(box).toEqual(result); expect(box.clone(box2)).toBe(box2); expect(box.clone(box2)).toEqual(box2); }); it("clone undefined OBB with a result parameter", function () { var box = new OrientedBoundingBox(); expect(OrientedBoundingBox.clone(undefined, box)).toBe(undefined); }); it("clone undefined OBB without a result parameter", function () { expect(OrientedBoundingBox.clone(undefined)).toBe(undefined); }); it("equals works in all cases", function () { var box = new OrientedBoundingBox(); expect(box.equals(new OrientedBoundingBox())).toEqual(true); expect(box.equals(undefined)).toEqual(false); }); createPackableSpecs( OrientedBoundingBox, new OrientedBoundingBox(new Cartesian3(1.0, 2.0, 3.0), Matrix3.IDENTITY), [1.0, 2.0, 3.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] ); });