EllipseOutlineGeometry-12b6fef5.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. define(['exports', './Transforms-bc45e707', './Matrix3-41c58dde', './ComponentDatatype-cf1fa08e', './defaultValue-fe22d8c0', './Check-6ede7e26', './EllipseGeometryLibrary-92ab6b1e', './GeometryAttribute-a466e9c7', './GeometryAttributes-ad136444', './GeometryOffsetAttribute-9ad0019c', './IndexDatatype-2643aa47', './Math-0a2ac845'], (function (exports, Transforms, Matrix3, ComponentDatatype, defaultValue, Check, EllipseGeometryLibrary, GeometryAttribute, GeometryAttributes, GeometryOffsetAttribute, IndexDatatype, Math$1) { 'use strict';
  2. const scratchCartesian1 = new Matrix3.Cartesian3();
  3. let boundingSphereCenter = new Matrix3.Cartesian3();
  4. function computeEllipse(options) {
  5. const center = options.center;
  6. boundingSphereCenter = Matrix3.Cartesian3.multiplyByScalar(
  7. options.ellipsoid.geodeticSurfaceNormal(center, boundingSphereCenter),
  8. options.height,
  9. boundingSphereCenter
  10. );
  11. boundingSphereCenter = Matrix3.Cartesian3.add(
  12. center,
  13. boundingSphereCenter,
  14. boundingSphereCenter
  15. );
  16. const boundingSphere = new Transforms.BoundingSphere(
  17. boundingSphereCenter,
  18. options.semiMajorAxis
  19. );
  20. const positions = EllipseGeometryLibrary.EllipseGeometryLibrary.computeEllipsePositions(
  21. options,
  22. false,
  23. true
  24. ).outerPositions;
  25. const attributes = new GeometryAttributes.GeometryAttributes({
  26. position: new GeometryAttribute.GeometryAttribute({
  27. componentDatatype: ComponentDatatype.ComponentDatatype.DOUBLE,
  28. componentsPerAttribute: 3,
  29. values: EllipseGeometryLibrary.EllipseGeometryLibrary.raisePositionsToHeight(
  30. positions,
  31. options,
  32. false
  33. ),
  34. }),
  35. });
  36. const length = positions.length / 3;
  37. const indices = IndexDatatype.IndexDatatype.createTypedArray(length, length * 2);
  38. let index = 0;
  39. for (let i = 0; i < length; ++i) {
  40. indices[index++] = i;
  41. indices[index++] = (i + 1) % length;
  42. }
  43. return {
  44. boundingSphere: boundingSphere,
  45. attributes: attributes,
  46. indices: indices,
  47. };
  48. }
  49. const topBoundingSphere = new Transforms.BoundingSphere();
  50. const bottomBoundingSphere = new Transforms.BoundingSphere();
  51. function computeExtrudedEllipse(options) {
  52. const center = options.center;
  53. const ellipsoid = options.ellipsoid;
  54. const semiMajorAxis = options.semiMajorAxis;
  55. let scaledNormal = Matrix3.Cartesian3.multiplyByScalar(
  56. ellipsoid.geodeticSurfaceNormal(center, scratchCartesian1),
  57. options.height,
  58. scratchCartesian1
  59. );
  60. topBoundingSphere.center = Matrix3.Cartesian3.add(
  61. center,
  62. scaledNormal,
  63. topBoundingSphere.center
  64. );
  65. topBoundingSphere.radius = semiMajorAxis;
  66. scaledNormal = Matrix3.Cartesian3.multiplyByScalar(
  67. ellipsoid.geodeticSurfaceNormal(center, scaledNormal),
  68. options.extrudedHeight,
  69. scaledNormal
  70. );
  71. bottomBoundingSphere.center = Matrix3.Cartesian3.add(
  72. center,
  73. scaledNormal,
  74. bottomBoundingSphere.center
  75. );
  76. bottomBoundingSphere.radius = semiMajorAxis;
  77. let positions = EllipseGeometryLibrary.EllipseGeometryLibrary.computeEllipsePositions(
  78. options,
  79. false,
  80. true
  81. ).outerPositions;
  82. const attributes = new GeometryAttributes.GeometryAttributes({
  83. position: new GeometryAttribute.GeometryAttribute({
  84. componentDatatype: ComponentDatatype.ComponentDatatype.DOUBLE,
  85. componentsPerAttribute: 3,
  86. values: EllipseGeometryLibrary.EllipseGeometryLibrary.raisePositionsToHeight(
  87. positions,
  88. options,
  89. true
  90. ),
  91. }),
  92. });
  93. positions = attributes.position.values;
  94. const boundingSphere = Transforms.BoundingSphere.union(
  95. topBoundingSphere,
  96. bottomBoundingSphere
  97. );
  98. let length = positions.length / 3;
  99. if (defaultValue.defined(options.offsetAttribute)) {
  100. let applyOffset = new Uint8Array(length);
  101. if (options.offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.TOP) {
  102. applyOffset = applyOffset.fill(1, 0, length / 2);
  103. } else {
  104. const offsetValue =
  105. options.offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.NONE ? 0 : 1;
  106. applyOffset = applyOffset.fill(offsetValue);
  107. }
  108. attributes.applyOffset = new GeometryAttribute.GeometryAttribute({
  109. componentDatatype: ComponentDatatype.ComponentDatatype.UNSIGNED_BYTE,
  110. componentsPerAttribute: 1,
  111. values: applyOffset,
  112. });
  113. }
  114. let numberOfVerticalLines = defaultValue.defaultValue(options.numberOfVerticalLines, 16);
  115. numberOfVerticalLines = Math$1.CesiumMath.clamp(
  116. numberOfVerticalLines,
  117. 0,
  118. length / 2
  119. );
  120. const indices = IndexDatatype.IndexDatatype.createTypedArray(
  121. length,
  122. length * 2 + numberOfVerticalLines * 2
  123. );
  124. length /= 2;
  125. let index = 0;
  126. let i;
  127. for (i = 0; i < length; ++i) {
  128. indices[index++] = i;
  129. indices[index++] = (i + 1) % length;
  130. indices[index++] = i + length;
  131. indices[index++] = ((i + 1) % length) + length;
  132. }
  133. let numSide;
  134. if (numberOfVerticalLines > 0) {
  135. const numSideLines = Math.min(numberOfVerticalLines, length);
  136. numSide = Math.round(length / numSideLines);
  137. const maxI = Math.min(numSide * numberOfVerticalLines, length);
  138. for (i = 0; i < maxI; i += numSide) {
  139. indices[index++] = i;
  140. indices[index++] = i + length;
  141. }
  142. }
  143. return {
  144. boundingSphere: boundingSphere,
  145. attributes: attributes,
  146. indices: indices,
  147. };
  148. }
  149. /**
  150. * A description of the outline of an ellipse on an ellipsoid.
  151. *
  152. * @alias EllipseOutlineGeometry
  153. * @constructor
  154. *
  155. * @param {object} options Object with the following properties:
  156. * @param {Cartesian3} options.center The ellipse's center point in the fixed frame.
  157. * @param {number} options.semiMajorAxis The length of the ellipse's semi-major axis in meters.
  158. * @param {number} options.semiMinorAxis The length of the ellipse's semi-minor axis in meters.
  159. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the ellipse will be on.
  160. * @param {number} [options.height=0.0] The distance in meters between the ellipse and the ellipsoid surface.
  161. * @param {number} [options.extrudedHeight] The distance in meters between the ellipse's extruded face and the ellipsoid surface.
  162. * @param {number} [options.rotation=0.0] The angle from north (counter-clockwise) in radians.
  163. * @param {number} [options.granularity=0.02] The angular distance between points on the ellipse in radians.
  164. * @param {number} [options.numberOfVerticalLines=16] Number of lines to draw between the top and bottom surface of an extruded ellipse.
  165. *
  166. * @exception {DeveloperError} semiMajorAxis and semiMinorAxis must be greater than zero.
  167. * @exception {DeveloperError} semiMajorAxis must be greater than or equal to the semiMinorAxis.
  168. * @exception {DeveloperError} granularity must be greater than zero.
  169. *
  170. * @see EllipseOutlineGeometry.createGeometry
  171. *
  172. * @example
  173. * const ellipse = new Cesium.EllipseOutlineGeometry({
  174. * center : Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883),
  175. * semiMajorAxis : 500000.0,
  176. * semiMinorAxis : 300000.0,
  177. * rotation : Cesium.Math.toRadians(60.0)
  178. * });
  179. * const geometry = Cesium.EllipseOutlineGeometry.createGeometry(ellipse);
  180. */
  181. function EllipseOutlineGeometry(options) {
  182. options = defaultValue.defaultValue(options, defaultValue.defaultValue.EMPTY_OBJECT);
  183. const center = options.center;
  184. const ellipsoid = defaultValue.defaultValue(options.ellipsoid, Matrix3.Ellipsoid.WGS84);
  185. const semiMajorAxis = options.semiMajorAxis;
  186. const semiMinorAxis = options.semiMinorAxis;
  187. const granularity = defaultValue.defaultValue(
  188. options.granularity,
  189. Math$1.CesiumMath.RADIANS_PER_DEGREE
  190. );
  191. //>>includeStart('debug', pragmas.debug);
  192. if (!defaultValue.defined(center)) {
  193. throw new Check.DeveloperError("center is required.");
  194. }
  195. if (!defaultValue.defined(semiMajorAxis)) {
  196. throw new Check.DeveloperError("semiMajorAxis is required.");
  197. }
  198. if (!defaultValue.defined(semiMinorAxis)) {
  199. throw new Check.DeveloperError("semiMinorAxis is required.");
  200. }
  201. if (semiMajorAxis < semiMinorAxis) {
  202. throw new Check.DeveloperError(
  203. "semiMajorAxis must be greater than or equal to the semiMinorAxis."
  204. );
  205. }
  206. if (granularity <= 0.0) {
  207. throw new Check.DeveloperError("granularity must be greater than zero.");
  208. }
  209. //>>includeEnd('debug');
  210. const height = defaultValue.defaultValue(options.height, 0.0);
  211. const extrudedHeight = defaultValue.defaultValue(options.extrudedHeight, height);
  212. this._center = Matrix3.Cartesian3.clone(center);
  213. this._semiMajorAxis = semiMajorAxis;
  214. this._semiMinorAxis = semiMinorAxis;
  215. this._ellipsoid = Matrix3.Ellipsoid.clone(ellipsoid);
  216. this._rotation = defaultValue.defaultValue(options.rotation, 0.0);
  217. this._height = Math.max(extrudedHeight, height);
  218. this._granularity = granularity;
  219. this._extrudedHeight = Math.min(extrudedHeight, height);
  220. this._numberOfVerticalLines = Math.max(
  221. defaultValue.defaultValue(options.numberOfVerticalLines, 16),
  222. 0
  223. );
  224. this._offsetAttribute = options.offsetAttribute;
  225. this._workerName = "createEllipseOutlineGeometry";
  226. }
  227. /**
  228. * The number of elements used to pack the object into an array.
  229. * @type {number}
  230. */
  231. EllipseOutlineGeometry.packedLength =
  232. Matrix3.Cartesian3.packedLength + Matrix3.Ellipsoid.packedLength + 8;
  233. /**
  234. * Stores the provided instance into the provided array.
  235. *
  236. * @param {EllipseOutlineGeometry} value The value to pack.
  237. * @param {number[]} array The array to pack into.
  238. * @param {number} [startingIndex=0] The index into the array at which to start packing the elements.
  239. *
  240. * @returns {number[]} The array that was packed into
  241. */
  242. EllipseOutlineGeometry.pack = function (value, array, startingIndex) {
  243. //>>includeStart('debug', pragmas.debug);
  244. if (!defaultValue.defined(value)) {
  245. throw new Check.DeveloperError("value is required");
  246. }
  247. if (!defaultValue.defined(array)) {
  248. throw new Check.DeveloperError("array is required");
  249. }
  250. //>>includeEnd('debug');
  251. startingIndex = defaultValue.defaultValue(startingIndex, 0);
  252. Matrix3.Cartesian3.pack(value._center, array, startingIndex);
  253. startingIndex += Matrix3.Cartesian3.packedLength;
  254. Matrix3.Ellipsoid.pack(value._ellipsoid, array, startingIndex);
  255. startingIndex += Matrix3.Ellipsoid.packedLength;
  256. array[startingIndex++] = value._semiMajorAxis;
  257. array[startingIndex++] = value._semiMinorAxis;
  258. array[startingIndex++] = value._rotation;
  259. array[startingIndex++] = value._height;
  260. array[startingIndex++] = value._granularity;
  261. array[startingIndex++] = value._extrudedHeight;
  262. array[startingIndex++] = value._numberOfVerticalLines;
  263. array[startingIndex] = defaultValue.defaultValue(value._offsetAttribute, -1);
  264. return array;
  265. };
  266. const scratchCenter = new Matrix3.Cartesian3();
  267. const scratchEllipsoid = new Matrix3.Ellipsoid();
  268. const scratchOptions = {
  269. center: scratchCenter,
  270. ellipsoid: scratchEllipsoid,
  271. semiMajorAxis: undefined,
  272. semiMinorAxis: undefined,
  273. rotation: undefined,
  274. height: undefined,
  275. granularity: undefined,
  276. extrudedHeight: undefined,
  277. numberOfVerticalLines: undefined,
  278. offsetAttribute: undefined,
  279. };
  280. /**
  281. * Retrieves an instance from a packed array.
  282. *
  283. * @param {number[]} array The packed array.
  284. * @param {number} [startingIndex=0] The starting index of the element to be unpacked.
  285. * @param {EllipseOutlineGeometry} [result] The object into which to store the result.
  286. * @returns {EllipseOutlineGeometry} The modified result parameter or a new EllipseOutlineGeometry instance if one was not provided.
  287. */
  288. EllipseOutlineGeometry.unpack = function (array, startingIndex, result) {
  289. //>>includeStart('debug', pragmas.debug);
  290. if (!defaultValue.defined(array)) {
  291. throw new Check.DeveloperError("array is required");
  292. }
  293. //>>includeEnd('debug');
  294. startingIndex = defaultValue.defaultValue(startingIndex, 0);
  295. const center = Matrix3.Cartesian3.unpack(array, startingIndex, scratchCenter);
  296. startingIndex += Matrix3.Cartesian3.packedLength;
  297. const ellipsoid = Matrix3.Ellipsoid.unpack(array, startingIndex, scratchEllipsoid);
  298. startingIndex += Matrix3.Ellipsoid.packedLength;
  299. const semiMajorAxis = array[startingIndex++];
  300. const semiMinorAxis = array[startingIndex++];
  301. const rotation = array[startingIndex++];
  302. const height = array[startingIndex++];
  303. const granularity = array[startingIndex++];
  304. const extrudedHeight = array[startingIndex++];
  305. const numberOfVerticalLines = array[startingIndex++];
  306. const offsetAttribute = array[startingIndex];
  307. if (!defaultValue.defined(result)) {
  308. scratchOptions.height = height;
  309. scratchOptions.extrudedHeight = extrudedHeight;
  310. scratchOptions.granularity = granularity;
  311. scratchOptions.rotation = rotation;
  312. scratchOptions.semiMajorAxis = semiMajorAxis;
  313. scratchOptions.semiMinorAxis = semiMinorAxis;
  314. scratchOptions.numberOfVerticalLines = numberOfVerticalLines;
  315. scratchOptions.offsetAttribute =
  316. offsetAttribute === -1 ? undefined : offsetAttribute;
  317. return new EllipseOutlineGeometry(scratchOptions);
  318. }
  319. result._center = Matrix3.Cartesian3.clone(center, result._center);
  320. result._ellipsoid = Matrix3.Ellipsoid.clone(ellipsoid, result._ellipsoid);
  321. result._semiMajorAxis = semiMajorAxis;
  322. result._semiMinorAxis = semiMinorAxis;
  323. result._rotation = rotation;
  324. result._height = height;
  325. result._granularity = granularity;
  326. result._extrudedHeight = extrudedHeight;
  327. result._numberOfVerticalLines = numberOfVerticalLines;
  328. result._offsetAttribute =
  329. offsetAttribute === -1 ? undefined : offsetAttribute;
  330. return result;
  331. };
  332. /**
  333. * Computes the geometric representation of an outline of an ellipse on an ellipsoid, including its vertices, indices, and a bounding sphere.
  334. *
  335. * @param {EllipseOutlineGeometry} ellipseGeometry A description of the ellipse.
  336. * @returns {Geometry|undefined} The computed vertices and indices.
  337. */
  338. EllipseOutlineGeometry.createGeometry = function (ellipseGeometry) {
  339. if (
  340. ellipseGeometry._semiMajorAxis <= 0.0 ||
  341. ellipseGeometry._semiMinorAxis <= 0.0
  342. ) {
  343. return;
  344. }
  345. const height = ellipseGeometry._height;
  346. const extrudedHeight = ellipseGeometry._extrudedHeight;
  347. const extrude = !Math$1.CesiumMath.equalsEpsilon(
  348. height,
  349. extrudedHeight,
  350. 0,
  351. Math$1.CesiumMath.EPSILON2
  352. );
  353. ellipseGeometry._center = ellipseGeometry._ellipsoid.scaleToGeodeticSurface(
  354. ellipseGeometry._center,
  355. ellipseGeometry._center
  356. );
  357. const options = {
  358. center: ellipseGeometry._center,
  359. semiMajorAxis: ellipseGeometry._semiMajorAxis,
  360. semiMinorAxis: ellipseGeometry._semiMinorAxis,
  361. ellipsoid: ellipseGeometry._ellipsoid,
  362. rotation: ellipseGeometry._rotation,
  363. height: height,
  364. granularity: ellipseGeometry._granularity,
  365. numberOfVerticalLines: ellipseGeometry._numberOfVerticalLines,
  366. };
  367. let geometry;
  368. if (extrude) {
  369. options.extrudedHeight = extrudedHeight;
  370. options.offsetAttribute = ellipseGeometry._offsetAttribute;
  371. geometry = computeExtrudedEllipse(options);
  372. } else {
  373. geometry = computeEllipse(options);
  374. if (defaultValue.defined(ellipseGeometry._offsetAttribute)) {
  375. const length = geometry.attributes.position.values.length;
  376. const offsetValue =
  377. ellipseGeometry._offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.NONE
  378. ? 0
  379. : 1;
  380. const applyOffset = new Uint8Array(length / 3).fill(offsetValue);
  381. geometry.attributes.applyOffset = new GeometryAttribute.GeometryAttribute({
  382. componentDatatype: ComponentDatatype.ComponentDatatype.UNSIGNED_BYTE,
  383. componentsPerAttribute: 1,
  384. values: applyOffset,
  385. });
  386. }
  387. }
  388. return new GeometryAttribute.Geometry({
  389. attributes: geometry.attributes,
  390. indices: geometry.indices,
  391. primitiveType: GeometryAttribute.PrimitiveType.LINES,
  392. boundingSphere: geometry.boundingSphere,
  393. offsetAttribute: ellipseGeometry._offsetAttribute,
  394. });
  395. };
  396. exports.EllipseOutlineGeometry = EllipseOutlineGeometry;
  397. }));