defineSuite([ 'Core/OrientedBoundingBox', 'Core/BoundingSphere', 'Core/Cartesian3', 'Core/Cartesian4', 'Core/Ellipsoid', 'Core/Intersect', 'Core/Math', 'Core/Matrix3', 'Core/Occluder', 'Core/Plane', 'Core/Quaternion', 'Core/Rectangle', 'Specs/createPackableSpecs' ], function( OrientedBoundingBox, BoundingSphere, Cartesian3, Cartesian4, Ellipsoid, Intersect, CesiumMath, Matrix3, Occluder, Plane, Quaternion, Rectangle, createPackableSpecs) { 'use strict'; 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.00, 1.01)); }).toThrowDeveloperError(); expect(function() { return OrientedBoundingBox.fromRectangle(rectangle, 0.0, 0.0, new Ellipsoid(1.00, 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 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]); });