import { arrayFill } from "../../Source/Cesium.js"; import { Cartesian2 } from "../../Source/Cesium.js"; import { Cartesian3 } from "../../Source/Cesium.js"; import { Ellipsoid } from "../../Source/Cesium.js"; import { GeographicProjection } from "../../Source/Cesium.js"; import { GeometryOffsetAttribute } from "../../Source/Cesium.js"; import { Math as CesiumMath } from "../../Source/Cesium.js"; import { Matrix2 } from "../../Source/Cesium.js"; import { Rectangle } from "../../Source/Cesium.js"; import { RectangleOutlineGeometry } from "../../Source/Cesium.js"; import createPackableSpecs from "../createPackableSpecs.js"; describe("Core/RectangleOutlineGeometry", function () { it("computes positions", function () { var rectangle = new Rectangle(-2.0, -1.0, 0.0, 1.0); var m = RectangleOutlineGeometry.createGeometry( new RectangleOutlineGeometry({ rectangle: rectangle, granularity: 1.0, }) ); var positions = m.attributes.position.values; expect(positions.length).toEqual(8 * 3); expect(m.indices.length).toEqual(8 * 2); var expectedNWCorner = Ellipsoid.WGS84.cartographicToCartesian( Rectangle.northwest(rectangle) ); expect( new Cartesian3(positions[0], positions[1], positions[2]) ).toEqualEpsilon(expectedNWCorner, CesiumMath.EPSILON9); }); it("computes positions across IDL", function () { var rectangle = Rectangle.fromDegrees(179.0, -1.0, -179.0, 1.0); var m = RectangleOutlineGeometry.createGeometry( new RectangleOutlineGeometry({ rectangle: rectangle, }) ); var positions = m.attributes.position.values; expect(positions.length).toEqual(8 * 3); expect(m.indices.length).toEqual(8 * 2); var expectedNWCorner = Ellipsoid.WGS84.cartographicToCartesian( Rectangle.northwest(rectangle) ); expect( new Cartesian3(positions[0], positions[1], positions[2]) ).toEqualEpsilon(expectedNWCorner, CesiumMath.EPSILON9); }); it("computes positions at north pole", function () { var rectangle = Rectangle.fromDegrees(-180.0, 89.0, -179.0, 90.0); var m = RectangleOutlineGeometry.createGeometry( new RectangleOutlineGeometry({ rectangle: rectangle, }) ); var positions = m.attributes.position.values; expect(positions.length).toEqual(5 * 3); expect(m.indices.length).toEqual(5 * 2); }); it("computes positions at south pole", function () { var rectangle = Rectangle.fromDegrees(-180.0, -90.0, -179.0, -89.0); var m = RectangleOutlineGeometry.createGeometry( new RectangleOutlineGeometry({ rectangle: rectangle, }) ); var positions = m.attributes.position.values; expect(positions.length).toEqual(5 * 3); expect(m.indices.length).toEqual(5 * 2); }); it("compute positions with rotation", function () { var rectangle = new Rectangle(-1, -1, 1, 1); var angle = CesiumMath.PI_OVER_TWO; var m = RectangleOutlineGeometry.createGeometry( new RectangleOutlineGeometry({ rectangle: rectangle, rotation: angle, granularity: 1.0, }) ); var positions = m.attributes.position.values; expect(positions.length).toEqual(8 * 3); expect(m.indices.length).toEqual(8 * 2); var unrotatedNWCorner = Rectangle.northwest(rectangle); var projection = new GeographicProjection(); var projectedNWCorner = projection.project(unrotatedNWCorner); var rotation = Matrix2.fromRotation(angle); var rotatedNWCornerCartographic = projection.unproject( Matrix2.multiplyByVector(rotation, projectedNWCorner, new Cartesian2()) ); var rotatedNWCorner = Ellipsoid.WGS84.cartographicToCartesian( rotatedNWCornerCartographic ); var actual = new Cartesian3(positions[0], positions[1], positions[2]); expect(actual).toEqualEpsilon(rotatedNWCorner, CesiumMath.EPSILON6); }); it("throws without rectangle", function () { expect(function () { return new RectangleOutlineGeometry({}); }).toThrowDeveloperError(); }); it("throws if rotated rectangle is invalid", function () { expect(function () { return RectangleOutlineGeometry.createGeometry( new RectangleOutlineGeometry({ rectangle: new Rectangle( -CesiumMath.PI_OVER_TWO, 1, CesiumMath.PI_OVER_TWO, CesiumMath.PI_OVER_TWO ), rotation: CesiumMath.PI_OVER_TWO, }) ); }).toThrowDeveloperError(); }); it("throws if north is less than south", function () { expect(function () { return new RectangleOutlineGeometry({ rectangle: new Rectangle( -CesiumMath.PI_OVER_TWO, CesiumMath.PI_OVER_TWO, CesiumMath.PI_OVER_TWO, -CesiumMath.PI_OVER_TWO ), }); }).toThrowDeveloperError(); }); it("computes positions extruded", function () { var rectangle = new Rectangle(-2.0, -1.0, 0.0, 1.0); var m = RectangleOutlineGeometry.createGeometry( new RectangleOutlineGeometry({ rectangle: rectangle, granularity: 1.0, extrudedHeight: 2, }) ); var positions = m.attributes.position.values; expect(positions.length).toEqual(16 * 3); // 8 top + 8 bottom expect(m.indices.length).toEqual(20 * 2); // 8 top + 8 bottom + 4 edges }); it("computes positions extruded at north pole", function () { var rectangle = Rectangle.fromDegrees(-180.0, 89.0, -179.0, 90.0); var m = RectangleOutlineGeometry.createGeometry( new RectangleOutlineGeometry({ rectangle: rectangle, extrudedHeight: 2, }) ); var positions = m.attributes.position.values; expect(positions.length).toEqual(10 * 3); // 5 top + 5 bottom expect(m.indices.length).toEqual(13 * 2); // 5 top + 5 bottom + 3 edges }); it("computes positions extruded at south pole", function () { var rectangle = Rectangle.fromDegrees(-180.0, -90.0, -179.0, -89.0); var m = RectangleOutlineGeometry.createGeometry( new RectangleOutlineGeometry({ rectangle: rectangle, extrudedHeight: 2, }) ); var positions = m.attributes.position.values; expect(positions.length).toEqual(10 * 3); // 5 top + 5 bottom expect(m.indices.length).toEqual(13 * 2); // 5 top + 5 bottom + 3 edges }); it("compute positions with rotation extruded", function () { var rectangle = new Rectangle(-1, -1, 1, 1); var angle = CesiumMath.PI_OVER_TWO; var m = RectangleOutlineGeometry.createGeometry( new RectangleOutlineGeometry({ rectangle: rectangle, rotation: angle, granularity: 1.0, extrudedHeight: 2, }) ); var positions = m.attributes.position.values; expect(positions.length).toEqual(16 * 3); expect(m.indices.length).toEqual(20 * 2); var unrotatedNWCorner = Rectangle.northwest(rectangle); var projection = new GeographicProjection(); var projectedNWCorner = projection.project(unrotatedNWCorner); var rotation = Matrix2.fromRotation(angle); var rotatedNWCornerCartographic = projection.unproject( Matrix2.multiplyByVector(rotation, projectedNWCorner, new Cartesian2()) ); rotatedNWCornerCartographic.height = 2; var rotatedNWCorner = Ellipsoid.WGS84.cartographicToCartesian( rotatedNWCornerCartographic ); var actual = new Cartesian3(positions[0], positions[1], positions[2]); expect(actual).toEqualEpsilon(rotatedNWCorner, CesiumMath.EPSILON6); }); it("computes non-extruded rectangle if height is small", function () { var rectangle = new Rectangle(-2.0, -1.0, 0.0, 1.0); var m = RectangleOutlineGeometry.createGeometry( new RectangleOutlineGeometry({ rectangle: rectangle, granularity: 1.0, extrudedHeight: CesiumMath.EPSILON14, }) ); var positions = m.attributes.position.values; expect(positions.length).toEqual(8 * 3); expect(m.indices.length).toEqual(8 * 2); }); it("undefined is returned if any side are of length zero", function () { var rectangleOutline0 = new RectangleOutlineGeometry({ rectangle: Rectangle.fromDegrees(-80.0, 39.0, -80.0, 42.0), }); var rectangleOutline1 = new RectangleOutlineGeometry({ rectangle: Rectangle.fromDegrees(-81.0, 42.0, -80.0, 42.0), }); var rectangleOutline2 = new RectangleOutlineGeometry({ rectangle: Rectangle.fromDegrees(-80.0, 39.0, -80.0, 39.0), }); var geometry0 = RectangleOutlineGeometry.createGeometry(rectangleOutline0); var geometry1 = RectangleOutlineGeometry.createGeometry(rectangleOutline1); var geometry2 = RectangleOutlineGeometry.createGeometry(rectangleOutline2); expect(geometry0).toBeUndefined(); expect(geometry1).toBeUndefined(); expect(geometry2).toBeUndefined(); }); it("computes offset attribute", function () { var rectangle = new Rectangle(-2.0, -1.0, 0.0, 1.0); var m = RectangleOutlineGeometry.createGeometry( new RectangleOutlineGeometry({ rectangle: rectangle, granularity: 1.0, offsetAttribute: GeometryOffsetAttribute.TOP, }) ); var positions = m.attributes.position.values; var numVertices = 8; expect(positions.length).toEqual(numVertices * 3); var offset = m.attributes.applyOffset.values; expect(offset.length).toEqual(numVertices); var expected = new Array(offset.length); expected = arrayFill(expected, 1); expect(offset).toEqual(expected); }); it("computes offset attribute extruded for top vertices", function () { var rectangle = new Rectangle(-2.0, -1.0, 0.0, 1.0); var m = RectangleOutlineGeometry.createGeometry( new RectangleOutlineGeometry({ rectangle: rectangle, granularity: 1.0, extrudedHeight: 2, offsetAttribute: GeometryOffsetAttribute.TOP, }) ); var positions = m.attributes.position.values; var numVertices = 16; expect(positions.length).toEqual(numVertices * 3); var offset = m.attributes.applyOffset.values; expect(offset.length).toEqual(numVertices); var expected = new Array(offset.length); expected = arrayFill(expected, 0); expected = arrayFill(expected, 1, 0, 8); expect(offset).toEqual(expected); }); it("computes offset attribute extruded for all vertices", function () { var rectangle = new Rectangle(-2.0, -1.0, 0.0, 1.0); var m = RectangleOutlineGeometry.createGeometry( new RectangleOutlineGeometry({ rectangle: rectangle, granularity: 1.0, extrudedHeight: 2, offsetAttribute: GeometryOffsetAttribute.ALL, }) ); var positions = m.attributes.position.values; var numVertices = 16; expect(positions.length).toEqual(numVertices * 3); var offset = m.attributes.applyOffset.values; expect(offset.length).toEqual(numVertices); var expected = new Array(offset.length); expected = arrayFill(expected, 1); expect(offset).toEqual(expected); }); var rectangle = new RectangleOutlineGeometry({ rectangle: new Rectangle(0.1, 0.2, 0.3, 0.4), ellipsoid: new Ellipsoid(5, 6, 7), granularity: 8, height: 9, rotation: 10, extrudedHeight: 11, }); var packedInstance = [0.1, 0.2, 0.3, 0.4, 5, 6, 7, 8, 11, 10, 9, -1]; createPackableSpecs( RectangleOutlineGeometry, rectangle, packedInstance, "extruded" ); rectangle = new RectangleOutlineGeometry({ rectangle: new Rectangle(0.1, 0.2, 0.3, 0.4), ellipsoid: new Ellipsoid(5, 6, 7), granularity: 8, height: 9, rotation: 10, }); packedInstance = [0.1, 0.2, 0.3, 0.4, 5, 6, 7, 8, 9, 10, 9, -1]; createPackableSpecs( RectangleOutlineGeometry, rectangle, packedInstance, "at height" ); });