PolygonGeometryLibrary.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. import ArcType from "./ArcType.js";
  2. import arrayRemoveDuplicates from "./arrayRemoveDuplicates.js";
  3. import Cartesian2 from "./Cartesian2.js";
  4. import Cartesian3 from "./Cartesian3.js";
  5. import Cartographic from "./Cartographic.js";
  6. import ComponentDatatype from "./ComponentDatatype.js";
  7. import defaultValue from "./defaultValue.js";
  8. import defined from "./defined.js";
  9. import Ellipsoid from "./Ellipsoid.js";
  10. import EllipsoidRhumbLine from "./EllipsoidRhumbLine.js";
  11. import Geometry from "./Geometry.js";
  12. import GeometryAttribute from "./GeometryAttribute.js";
  13. import GeometryAttributes from "./GeometryAttributes.js";
  14. import GeometryPipeline from "./GeometryPipeline.js";
  15. import IndexDatatype from "./IndexDatatype.js";
  16. import CesiumMath from "./Math.js";
  17. import Matrix3 from "./Matrix3.js";
  18. import PolygonPipeline from "./PolygonPipeline.js";
  19. import PrimitiveType from "./PrimitiveType.js";
  20. import Quaternion from "./Quaternion.js";
  21. import Queue from "./Queue.js";
  22. import WindingOrder from "./WindingOrder.js";
  23. /**
  24. * @private
  25. */
  26. var PolygonGeometryLibrary = {};
  27. PolygonGeometryLibrary.computeHierarchyPackedLength = function (
  28. polygonHierarchy
  29. ) {
  30. var numComponents = 0;
  31. var stack = [polygonHierarchy];
  32. while (stack.length > 0) {
  33. var hierarchy = stack.pop();
  34. if (!defined(hierarchy)) {
  35. continue;
  36. }
  37. numComponents += 2;
  38. var positions = hierarchy.positions;
  39. var holes = hierarchy.holes;
  40. if (defined(positions)) {
  41. numComponents += positions.length * Cartesian3.packedLength;
  42. }
  43. if (defined(holes)) {
  44. var length = holes.length;
  45. for (var i = 0; i < length; ++i) {
  46. stack.push(holes[i]);
  47. }
  48. }
  49. }
  50. return numComponents;
  51. };
  52. PolygonGeometryLibrary.packPolygonHierarchy = function (
  53. polygonHierarchy,
  54. array,
  55. startingIndex
  56. ) {
  57. var stack = [polygonHierarchy];
  58. while (stack.length > 0) {
  59. var hierarchy = stack.pop();
  60. if (!defined(hierarchy)) {
  61. continue;
  62. }
  63. var positions = hierarchy.positions;
  64. var holes = hierarchy.holes;
  65. array[startingIndex++] = defined(positions) ? positions.length : 0;
  66. array[startingIndex++] = defined(holes) ? holes.length : 0;
  67. if (defined(positions)) {
  68. var positionsLength = positions.length;
  69. for (var i = 0; i < positionsLength; ++i, startingIndex += 3) {
  70. Cartesian3.pack(positions[i], array, startingIndex);
  71. }
  72. }
  73. if (defined(holes)) {
  74. var holesLength = holes.length;
  75. for (var j = 0; j < holesLength; ++j) {
  76. stack.push(holes[j]);
  77. }
  78. }
  79. }
  80. return startingIndex;
  81. };
  82. PolygonGeometryLibrary.unpackPolygonHierarchy = function (
  83. array,
  84. startingIndex
  85. ) {
  86. var positionsLength = array[startingIndex++];
  87. var holesLength = array[startingIndex++];
  88. var positions = new Array(positionsLength);
  89. var holes = holesLength > 0 ? new Array(holesLength) : undefined;
  90. for (
  91. var i = 0;
  92. i < positionsLength;
  93. ++i, startingIndex += Cartesian3.packedLength
  94. ) {
  95. positions[i] = Cartesian3.unpack(array, startingIndex);
  96. }
  97. for (var j = 0; j < holesLength; ++j) {
  98. holes[j] = PolygonGeometryLibrary.unpackPolygonHierarchy(
  99. array,
  100. startingIndex
  101. );
  102. startingIndex = holes[j].startingIndex;
  103. delete holes[j].startingIndex;
  104. }
  105. return {
  106. positions: positions,
  107. holes: holes,
  108. startingIndex: startingIndex,
  109. };
  110. };
  111. var distanceScratch = new Cartesian3();
  112. function getPointAtDistance(p0, p1, distance, length) {
  113. Cartesian3.subtract(p1, p0, distanceScratch);
  114. Cartesian3.multiplyByScalar(
  115. distanceScratch,
  116. distance / length,
  117. distanceScratch
  118. );
  119. Cartesian3.add(p0, distanceScratch, distanceScratch);
  120. return [distanceScratch.x, distanceScratch.y, distanceScratch.z];
  121. }
  122. PolygonGeometryLibrary.subdivideLineCount = function (p0, p1, minDistance) {
  123. var distance = Cartesian3.distance(p0, p1);
  124. var n = distance / minDistance;
  125. var countDivide = Math.max(0, Math.ceil(CesiumMath.log2(n)));
  126. return Math.pow(2, countDivide);
  127. };
  128. var scratchCartographic0 = new Cartographic();
  129. var scratchCartographic1 = new Cartographic();
  130. var scratchCartographic2 = new Cartographic();
  131. var scratchCartesian0 = new Cartesian3();
  132. PolygonGeometryLibrary.subdivideRhumbLineCount = function (
  133. ellipsoid,
  134. p0,
  135. p1,
  136. minDistance
  137. ) {
  138. var c0 = ellipsoid.cartesianToCartographic(p0, scratchCartographic0);
  139. var c1 = ellipsoid.cartesianToCartographic(p1, scratchCartographic1);
  140. var rhumb = new EllipsoidRhumbLine(c0, c1, ellipsoid);
  141. var n = rhumb.surfaceDistance / minDistance;
  142. var countDivide = Math.max(0, Math.ceil(CesiumMath.log2(n)));
  143. return Math.pow(2, countDivide);
  144. };
  145. PolygonGeometryLibrary.subdivideLine = function (p0, p1, minDistance, result) {
  146. var numVertices = PolygonGeometryLibrary.subdivideLineCount(
  147. p0,
  148. p1,
  149. minDistance
  150. );
  151. var length = Cartesian3.distance(p0, p1);
  152. var distanceBetweenVertices = length / numVertices;
  153. if (!defined(result)) {
  154. result = [];
  155. }
  156. var positions = result;
  157. positions.length = numVertices * 3;
  158. var index = 0;
  159. for (var i = 0; i < numVertices; i++) {
  160. var p = getPointAtDistance(p0, p1, i * distanceBetweenVertices, length);
  161. positions[index++] = p[0];
  162. positions[index++] = p[1];
  163. positions[index++] = p[2];
  164. }
  165. return positions;
  166. };
  167. PolygonGeometryLibrary.subdivideRhumbLine = function (
  168. ellipsoid,
  169. p0,
  170. p1,
  171. minDistance,
  172. result
  173. ) {
  174. var c0 = ellipsoid.cartesianToCartographic(p0, scratchCartographic0);
  175. var c1 = ellipsoid.cartesianToCartographic(p1, scratchCartographic1);
  176. var rhumb = new EllipsoidRhumbLine(c0, c1, ellipsoid);
  177. var n = rhumb.surfaceDistance / minDistance;
  178. var countDivide = Math.max(0, Math.ceil(CesiumMath.log2(n)));
  179. var numVertices = Math.pow(2, countDivide);
  180. var distanceBetweenVertices = rhumb.surfaceDistance / numVertices;
  181. if (!defined(result)) {
  182. result = [];
  183. }
  184. var positions = result;
  185. positions.length = numVertices * 3;
  186. var index = 0;
  187. for (var i = 0; i < numVertices; i++) {
  188. var c = rhumb.interpolateUsingSurfaceDistance(
  189. i * distanceBetweenVertices,
  190. scratchCartographic2
  191. );
  192. var p = ellipsoid.cartographicToCartesian(c, scratchCartesian0);
  193. positions[index++] = p.x;
  194. positions[index++] = p.y;
  195. positions[index++] = p.z;
  196. }
  197. return positions;
  198. };
  199. var scaleToGeodeticHeightN1 = new Cartesian3();
  200. var scaleToGeodeticHeightN2 = new Cartesian3();
  201. var scaleToGeodeticHeightP1 = new Cartesian3();
  202. var scaleToGeodeticHeightP2 = new Cartesian3();
  203. PolygonGeometryLibrary.scaleToGeodeticHeightExtruded = function (
  204. geometry,
  205. maxHeight,
  206. minHeight,
  207. ellipsoid,
  208. perPositionHeight
  209. ) {
  210. ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84);
  211. var n1 = scaleToGeodeticHeightN1;
  212. var n2 = scaleToGeodeticHeightN2;
  213. var p = scaleToGeodeticHeightP1;
  214. var p2 = scaleToGeodeticHeightP2;
  215. if (
  216. defined(geometry) &&
  217. defined(geometry.attributes) &&
  218. defined(geometry.attributes.position)
  219. ) {
  220. var positions = geometry.attributes.position.values;
  221. var length = positions.length / 2;
  222. for (var i = 0; i < length; i += 3) {
  223. Cartesian3.fromArray(positions, i, p);
  224. ellipsoid.geodeticSurfaceNormal(p, n1);
  225. p2 = ellipsoid.scaleToGeodeticSurface(p, p2);
  226. n2 = Cartesian3.multiplyByScalar(n1, minHeight, n2);
  227. n2 = Cartesian3.add(p2, n2, n2);
  228. positions[i + length] = n2.x;
  229. positions[i + 1 + length] = n2.y;
  230. positions[i + 2 + length] = n2.z;
  231. if (perPositionHeight) {
  232. p2 = Cartesian3.clone(p, p2);
  233. }
  234. n2 = Cartesian3.multiplyByScalar(n1, maxHeight, n2);
  235. n2 = Cartesian3.add(p2, n2, n2);
  236. positions[i] = n2.x;
  237. positions[i + 1] = n2.y;
  238. positions[i + 2] = n2.z;
  239. }
  240. }
  241. return geometry;
  242. };
  243. PolygonGeometryLibrary.polygonOutlinesFromHierarchy = function (
  244. polygonHierarchy,
  245. scaleToEllipsoidSurface,
  246. ellipsoid
  247. ) {
  248. // create from a polygon hierarchy
  249. // Algorithm adapted from http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
  250. var polygons = [];
  251. var queue = new Queue();
  252. queue.enqueue(polygonHierarchy);
  253. var i;
  254. var j;
  255. var length;
  256. while (queue.length !== 0) {
  257. var outerNode = queue.dequeue();
  258. var outerRing = outerNode.positions;
  259. if (scaleToEllipsoidSurface) {
  260. length = outerRing.length;
  261. for (i = 0; i < length; i++) {
  262. ellipsoid.scaleToGeodeticSurface(outerRing[i], outerRing[i]);
  263. }
  264. }
  265. outerRing = arrayRemoveDuplicates(
  266. outerRing,
  267. Cartesian3.equalsEpsilon,
  268. true
  269. );
  270. if (outerRing.length < 3) {
  271. continue;
  272. }
  273. var numChildren = outerNode.holes ? outerNode.holes.length : 0;
  274. // The outer polygon contains inner polygons
  275. for (i = 0; i < numChildren; i++) {
  276. var hole = outerNode.holes[i];
  277. var holePositions = hole.positions;
  278. if (scaleToEllipsoidSurface) {
  279. length = holePositions.length;
  280. for (j = 0; j < length; ++j) {
  281. ellipsoid.scaleToGeodeticSurface(holePositions[j], holePositions[j]);
  282. }
  283. }
  284. holePositions = arrayRemoveDuplicates(
  285. holePositions,
  286. Cartesian3.equalsEpsilon,
  287. true
  288. );
  289. if (holePositions.length < 3) {
  290. continue;
  291. }
  292. polygons.push(holePositions);
  293. var numGrandchildren = 0;
  294. if (defined(hole.holes)) {
  295. numGrandchildren = hole.holes.length;
  296. }
  297. for (j = 0; j < numGrandchildren; j++) {
  298. queue.enqueue(hole.holes[j]);
  299. }
  300. }
  301. polygons.push(outerRing);
  302. }
  303. return polygons;
  304. };
  305. PolygonGeometryLibrary.polygonsFromHierarchy = function (
  306. polygonHierarchy,
  307. projectPointsTo2D,
  308. scaleToEllipsoidSurface,
  309. ellipsoid
  310. ) {
  311. // create from a polygon hierarchy
  312. // Algorithm adapted from http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
  313. var hierarchy = [];
  314. var polygons = [];
  315. var queue = new Queue();
  316. queue.enqueue(polygonHierarchy);
  317. while (queue.length !== 0) {
  318. var outerNode = queue.dequeue();
  319. var outerRing = outerNode.positions;
  320. var holes = outerNode.holes;
  321. var i;
  322. var length;
  323. if (scaleToEllipsoidSurface) {
  324. length = outerRing.length;
  325. for (i = 0; i < length; i++) {
  326. ellipsoid.scaleToGeodeticSurface(outerRing[i], outerRing[i]);
  327. }
  328. }
  329. outerRing = arrayRemoveDuplicates(
  330. outerRing,
  331. Cartesian3.equalsEpsilon,
  332. true
  333. );
  334. if (outerRing.length < 3) {
  335. continue;
  336. }
  337. var positions2D = projectPointsTo2D(outerRing);
  338. if (!defined(positions2D)) {
  339. continue;
  340. }
  341. var holeIndices = [];
  342. var originalWindingOrder = PolygonPipeline.computeWindingOrder2D(
  343. positions2D
  344. );
  345. if (originalWindingOrder === WindingOrder.CLOCKWISE) {
  346. positions2D.reverse();
  347. outerRing = outerRing.slice().reverse();
  348. }
  349. var positions = outerRing.slice();
  350. var numChildren = defined(holes) ? holes.length : 0;
  351. var polygonHoles = [];
  352. var j;
  353. for (i = 0; i < numChildren; i++) {
  354. var hole = holes[i];
  355. var holePositions = hole.positions;
  356. if (scaleToEllipsoidSurface) {
  357. length = holePositions.length;
  358. for (j = 0; j < length; ++j) {
  359. ellipsoid.scaleToGeodeticSurface(holePositions[j], holePositions[j]);
  360. }
  361. }
  362. holePositions = arrayRemoveDuplicates(
  363. holePositions,
  364. Cartesian3.equalsEpsilon,
  365. true
  366. );
  367. if (holePositions.length < 3) {
  368. continue;
  369. }
  370. var holePositions2D = projectPointsTo2D(holePositions);
  371. if (!defined(holePositions2D)) {
  372. continue;
  373. }
  374. originalWindingOrder = PolygonPipeline.computeWindingOrder2D(
  375. holePositions2D
  376. );
  377. if (originalWindingOrder === WindingOrder.CLOCKWISE) {
  378. holePositions2D.reverse();
  379. holePositions = holePositions.slice().reverse();
  380. }
  381. polygonHoles.push(holePositions);
  382. holeIndices.push(positions.length);
  383. positions = positions.concat(holePositions);
  384. positions2D = positions2D.concat(holePositions2D);
  385. var numGrandchildren = 0;
  386. if (defined(hole.holes)) {
  387. numGrandchildren = hole.holes.length;
  388. }
  389. for (j = 0; j < numGrandchildren; j++) {
  390. queue.enqueue(hole.holes[j]);
  391. }
  392. }
  393. hierarchy.push({
  394. outerRing: outerRing,
  395. holes: polygonHoles,
  396. });
  397. polygons.push({
  398. positions: positions,
  399. positions2D: positions2D,
  400. holes: holeIndices,
  401. });
  402. }
  403. return {
  404. hierarchy: hierarchy,
  405. polygons: polygons,
  406. };
  407. };
  408. var computeBoundingRectangleCartesian2 = new Cartesian2();
  409. var computeBoundingRectangleCartesian3 = new Cartesian3();
  410. var computeBoundingRectangleQuaternion = new Quaternion();
  411. var computeBoundingRectangleMatrix3 = new Matrix3();
  412. PolygonGeometryLibrary.computeBoundingRectangle = function (
  413. planeNormal,
  414. projectPointTo2D,
  415. positions,
  416. angle,
  417. result
  418. ) {
  419. var rotation = Quaternion.fromAxisAngle(
  420. planeNormal,
  421. angle,
  422. computeBoundingRectangleQuaternion
  423. );
  424. var textureMatrix = Matrix3.fromQuaternion(
  425. rotation,
  426. computeBoundingRectangleMatrix3
  427. );
  428. var minX = Number.POSITIVE_INFINITY;
  429. var maxX = Number.NEGATIVE_INFINITY;
  430. var minY = Number.POSITIVE_INFINITY;
  431. var maxY = Number.NEGATIVE_INFINITY;
  432. var length = positions.length;
  433. for (var i = 0; i < length; ++i) {
  434. var p = Cartesian3.clone(positions[i], computeBoundingRectangleCartesian3);
  435. Matrix3.multiplyByVector(textureMatrix, p, p);
  436. var st = projectPointTo2D(p, computeBoundingRectangleCartesian2);
  437. if (defined(st)) {
  438. minX = Math.min(minX, st.x);
  439. maxX = Math.max(maxX, st.x);
  440. minY = Math.min(minY, st.y);
  441. maxY = Math.max(maxY, st.y);
  442. }
  443. }
  444. result.x = minX;
  445. result.y = minY;
  446. result.width = maxX - minX;
  447. result.height = maxY - minY;
  448. return result;
  449. };
  450. PolygonGeometryLibrary.createGeometryFromPositions = function (
  451. ellipsoid,
  452. polygon,
  453. granularity,
  454. perPositionHeight,
  455. vertexFormat,
  456. arcType
  457. ) {
  458. var indices = PolygonPipeline.triangulate(polygon.positions2D, polygon.holes);
  459. /* If polygon is completely unrenderable, just use the first three vertices */
  460. if (indices.length < 3) {
  461. indices = [0, 1, 2];
  462. }
  463. var positions = polygon.positions;
  464. if (perPositionHeight) {
  465. var length = positions.length;
  466. var flattenedPositions = new Array(length * 3);
  467. var index = 0;
  468. for (var i = 0; i < length; i++) {
  469. var p = positions[i];
  470. flattenedPositions[index++] = p.x;
  471. flattenedPositions[index++] = p.y;
  472. flattenedPositions[index++] = p.z;
  473. }
  474. var geometry = new Geometry({
  475. attributes: {
  476. position: new GeometryAttribute({
  477. componentDatatype: ComponentDatatype.DOUBLE,
  478. componentsPerAttribute: 3,
  479. values: flattenedPositions,
  480. }),
  481. },
  482. indices: indices,
  483. primitiveType: PrimitiveType.TRIANGLES,
  484. });
  485. if (vertexFormat.normal) {
  486. return GeometryPipeline.computeNormal(geometry);
  487. }
  488. return geometry;
  489. }
  490. if (arcType === ArcType.GEODESIC) {
  491. return PolygonPipeline.computeSubdivision(
  492. ellipsoid,
  493. positions,
  494. indices,
  495. granularity
  496. );
  497. } else if (arcType === ArcType.RHUMB) {
  498. return PolygonPipeline.computeRhumbLineSubdivision(
  499. ellipsoid,
  500. positions,
  501. indices,
  502. granularity
  503. );
  504. }
  505. };
  506. var computeWallIndicesSubdivided = [];
  507. var p1Scratch = new Cartesian3();
  508. var p2Scratch = new Cartesian3();
  509. PolygonGeometryLibrary.computeWallGeometry = function (
  510. positions,
  511. ellipsoid,
  512. granularity,
  513. perPositionHeight,
  514. arcType
  515. ) {
  516. var edgePositions;
  517. var topEdgeLength;
  518. var i;
  519. var p1;
  520. var p2;
  521. var length = positions.length;
  522. var index = 0;
  523. if (!perPositionHeight) {
  524. var minDistance = CesiumMath.chordLength(
  525. granularity,
  526. ellipsoid.maximumRadius
  527. );
  528. var numVertices = 0;
  529. if (arcType === ArcType.GEODESIC) {
  530. for (i = 0; i < length; i++) {
  531. numVertices += PolygonGeometryLibrary.subdivideLineCount(
  532. positions[i],
  533. positions[(i + 1) % length],
  534. minDistance
  535. );
  536. }
  537. } else if (arcType === ArcType.RHUMB) {
  538. for (i = 0; i < length; i++) {
  539. numVertices += PolygonGeometryLibrary.subdivideRhumbLineCount(
  540. ellipsoid,
  541. positions[i],
  542. positions[(i + 1) % length],
  543. minDistance
  544. );
  545. }
  546. }
  547. topEdgeLength = (numVertices + length) * 3;
  548. edgePositions = new Array(topEdgeLength * 2);
  549. for (i = 0; i < length; i++) {
  550. p1 = positions[i];
  551. p2 = positions[(i + 1) % length];
  552. var tempPositions;
  553. if (arcType === ArcType.GEODESIC) {
  554. tempPositions = PolygonGeometryLibrary.subdivideLine(
  555. p1,
  556. p2,
  557. minDistance,
  558. computeWallIndicesSubdivided
  559. );
  560. } else if (arcType === ArcType.RHUMB) {
  561. tempPositions = PolygonGeometryLibrary.subdivideRhumbLine(
  562. ellipsoid,
  563. p1,
  564. p2,
  565. minDistance,
  566. computeWallIndicesSubdivided
  567. );
  568. }
  569. var tempPositionsLength = tempPositions.length;
  570. for (var j = 0; j < tempPositionsLength; ++j, ++index) {
  571. edgePositions[index] = tempPositions[j];
  572. edgePositions[index + topEdgeLength] = tempPositions[j];
  573. }
  574. edgePositions[index] = p2.x;
  575. edgePositions[index + topEdgeLength] = p2.x;
  576. ++index;
  577. edgePositions[index] = p2.y;
  578. edgePositions[index + topEdgeLength] = p2.y;
  579. ++index;
  580. edgePositions[index] = p2.z;
  581. edgePositions[index + topEdgeLength] = p2.z;
  582. ++index;
  583. }
  584. } else {
  585. topEdgeLength = length * 3 * 2;
  586. edgePositions = new Array(topEdgeLength * 2);
  587. for (i = 0; i < length; i++) {
  588. p1 = positions[i];
  589. p2 = positions[(i + 1) % length];
  590. edgePositions[index] = edgePositions[index + topEdgeLength] = p1.x;
  591. ++index;
  592. edgePositions[index] = edgePositions[index + topEdgeLength] = p1.y;
  593. ++index;
  594. edgePositions[index] = edgePositions[index + topEdgeLength] = p1.z;
  595. ++index;
  596. edgePositions[index] = edgePositions[index + topEdgeLength] = p2.x;
  597. ++index;
  598. edgePositions[index] = edgePositions[index + topEdgeLength] = p2.y;
  599. ++index;
  600. edgePositions[index] = edgePositions[index + topEdgeLength] = p2.z;
  601. ++index;
  602. }
  603. }
  604. length = edgePositions.length;
  605. var indices = IndexDatatype.createTypedArray(
  606. length / 3,
  607. length - positions.length * 6
  608. );
  609. var edgeIndex = 0;
  610. length /= 6;
  611. for (i = 0; i < length; i++) {
  612. var UL = i;
  613. var UR = UL + 1;
  614. var LL = UL + length;
  615. var LR = LL + 1;
  616. p1 = Cartesian3.fromArray(edgePositions, UL * 3, p1Scratch);
  617. p2 = Cartesian3.fromArray(edgePositions, UR * 3, p2Scratch);
  618. if (
  619. Cartesian3.equalsEpsilon(
  620. p1,
  621. p2,
  622. CesiumMath.EPSILON10,
  623. CesiumMath.EPSILON10
  624. )
  625. ) {
  626. //skip corner
  627. continue;
  628. }
  629. indices[edgeIndex++] = UL;
  630. indices[edgeIndex++] = LL;
  631. indices[edgeIndex++] = UR;
  632. indices[edgeIndex++] = UR;
  633. indices[edgeIndex++] = LL;
  634. indices[edgeIndex++] = LR;
  635. }
  636. return new Geometry({
  637. attributes: new GeometryAttributes({
  638. position: new GeometryAttribute({
  639. componentDatatype: ComponentDatatype.DOUBLE,
  640. componentsPerAttribute: 3,
  641. values: edgePositions,
  642. }),
  643. }),
  644. indices: indices,
  645. primitiveType: PrimitiveType.TRIANGLES,
  646. });
  647. };
  648. export default PolygonGeometryLibrary;