createVerticesFromGoogleEarthEnterpriseBuffer.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. define(['./AxisAlignedBoundingBox-31fadcf0', './Transforms-bc45e707', './Matrix2-e1298525', './Matrix3-41c58dde', './defaultValue-fe22d8c0', './TerrainEncoding-51b8b33b', './Math-0a2ac845', './OrientedBoundingBox-2dd47921', './RuntimeError-ef395448', './WebMercatorProjection-13ed1a6e', './createTaskProcessorWorker', './Check-6ede7e26', './combine-d9581036', './AttributeCompression-f9f6c717', './ComponentDatatype-cf1fa08e', './WebGLConstants-0b1ce7ba', './EllipsoidTangentPlane-46d4d9c2', './IntersectionTests-88c49b2e', './Plane-4c3d403b'], (function (AxisAlignedBoundingBox, Transforms, Matrix2, Matrix3, defaultValue, TerrainEncoding, Math$1, OrientedBoundingBox, RuntimeError, WebMercatorProjection, createTaskProcessorWorker, Check, combine, AttributeCompression, ComponentDatatype, WebGLConstants, EllipsoidTangentPlane, IntersectionTests, Plane) { 'use strict';
  2. const sizeOfUint16 = Uint16Array.BYTES_PER_ELEMENT;
  3. const sizeOfInt32 = Int32Array.BYTES_PER_ELEMENT;
  4. const sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT;
  5. const sizeOfFloat = Float32Array.BYTES_PER_ELEMENT;
  6. const sizeOfDouble = Float64Array.BYTES_PER_ELEMENT;
  7. function indexOfEpsilon(arr, elem, elemType) {
  8. elemType = defaultValue.defaultValue(elemType, Math$1.CesiumMath);
  9. const count = arr.length;
  10. for (let i = 0; i < count; ++i) {
  11. if (elemType.equalsEpsilon(arr[i], elem, Math$1.CesiumMath.EPSILON12)) {
  12. return i;
  13. }
  14. }
  15. return -1;
  16. }
  17. function createVerticesFromGoogleEarthEnterpriseBuffer(
  18. parameters,
  19. transferableObjects
  20. ) {
  21. parameters.ellipsoid = Matrix3.Ellipsoid.clone(parameters.ellipsoid);
  22. parameters.rectangle = Matrix2.Rectangle.clone(parameters.rectangle);
  23. const statistics = processBuffer(
  24. parameters.buffer,
  25. parameters.relativeToCenter,
  26. parameters.ellipsoid,
  27. parameters.rectangle,
  28. parameters.nativeRectangle,
  29. parameters.exaggeration,
  30. parameters.exaggerationRelativeHeight,
  31. parameters.skirtHeight,
  32. parameters.includeWebMercatorT,
  33. parameters.negativeAltitudeExponentBias,
  34. parameters.negativeElevationThreshold
  35. );
  36. const vertices = statistics.vertices;
  37. transferableObjects.push(vertices.buffer);
  38. const indices = statistics.indices;
  39. transferableObjects.push(indices.buffer);
  40. return {
  41. vertices: vertices.buffer,
  42. indices: indices.buffer,
  43. numberOfAttributes: statistics.encoding.stride,
  44. minimumHeight: statistics.minimumHeight,
  45. maximumHeight: statistics.maximumHeight,
  46. boundingSphere3D: statistics.boundingSphere3D,
  47. orientedBoundingBox: statistics.orientedBoundingBox,
  48. occludeePointInScaledSpace: statistics.occludeePointInScaledSpace,
  49. encoding: statistics.encoding,
  50. vertexCountWithoutSkirts: statistics.vertexCountWithoutSkirts,
  51. indexCountWithoutSkirts: statistics.indexCountWithoutSkirts,
  52. westIndicesSouthToNorth: statistics.westIndicesSouthToNorth,
  53. southIndicesEastToWest: statistics.southIndicesEastToWest,
  54. eastIndicesNorthToSouth: statistics.eastIndicesNorthToSouth,
  55. northIndicesWestToEast: statistics.northIndicesWestToEast,
  56. };
  57. }
  58. const scratchCartographic = new Matrix3.Cartographic();
  59. const scratchCartesian = new Matrix3.Cartesian3();
  60. const minimumScratch = new Matrix3.Cartesian3();
  61. const maximumScratch = new Matrix3.Cartesian3();
  62. const matrix4Scratch = new Matrix2.Matrix4();
  63. function processBuffer(
  64. buffer,
  65. relativeToCenter,
  66. ellipsoid,
  67. rectangle,
  68. nativeRectangle,
  69. exaggeration,
  70. exaggerationRelativeHeight,
  71. skirtHeight,
  72. includeWebMercatorT,
  73. negativeAltitudeExponentBias,
  74. negativeElevationThreshold
  75. ) {
  76. let geographicWest;
  77. let geographicSouth;
  78. let geographicEast;
  79. let geographicNorth;
  80. let rectangleWidth, rectangleHeight;
  81. if (!defaultValue.defined(rectangle)) {
  82. geographicWest = Math$1.CesiumMath.toRadians(nativeRectangle.west);
  83. geographicSouth = Math$1.CesiumMath.toRadians(nativeRectangle.south);
  84. geographicEast = Math$1.CesiumMath.toRadians(nativeRectangle.east);
  85. geographicNorth = Math$1.CesiumMath.toRadians(nativeRectangle.north);
  86. rectangleWidth = Math$1.CesiumMath.toRadians(rectangle.width);
  87. rectangleHeight = Math$1.CesiumMath.toRadians(rectangle.height);
  88. } else {
  89. geographicWest = rectangle.west;
  90. geographicSouth = rectangle.south;
  91. geographicEast = rectangle.east;
  92. geographicNorth = rectangle.north;
  93. rectangleWidth = rectangle.width;
  94. rectangleHeight = rectangle.height;
  95. }
  96. // Keep track of quad borders so we can remove duplicates around the borders
  97. const quadBorderLatitudes = [geographicSouth, geographicNorth];
  98. const quadBorderLongitudes = [geographicWest, geographicEast];
  99. const fromENU = Transforms.Transforms.eastNorthUpToFixedFrame(
  100. relativeToCenter,
  101. ellipsoid
  102. );
  103. const toENU = Matrix2.Matrix4.inverseTransformation(fromENU, matrix4Scratch);
  104. let southMercatorY;
  105. let oneOverMercatorHeight;
  106. if (includeWebMercatorT) {
  107. southMercatorY = WebMercatorProjection.WebMercatorProjection.geodeticLatitudeToMercatorAngle(
  108. geographicSouth
  109. );
  110. oneOverMercatorHeight =
  111. 1.0 /
  112. (WebMercatorProjection.WebMercatorProjection.geodeticLatitudeToMercatorAngle(geographicNorth) -
  113. southMercatorY);
  114. }
  115. const hasExaggeration = exaggeration !== 1.0;
  116. const includeGeodeticSurfaceNormals = hasExaggeration;
  117. const dv = new DataView(buffer);
  118. let minHeight = Number.POSITIVE_INFINITY;
  119. let maxHeight = Number.NEGATIVE_INFINITY;
  120. const minimum = minimumScratch;
  121. minimum.x = Number.POSITIVE_INFINITY;
  122. minimum.y = Number.POSITIVE_INFINITY;
  123. minimum.z = Number.POSITIVE_INFINITY;
  124. const maximum = maximumScratch;
  125. maximum.x = Number.NEGATIVE_INFINITY;
  126. maximum.y = Number.NEGATIVE_INFINITY;
  127. maximum.z = Number.NEGATIVE_INFINITY;
  128. // Compute sizes
  129. let offset = 0;
  130. let size = 0;
  131. let indicesSize = 0;
  132. let quadSize;
  133. let quad;
  134. for (quad = 0; quad < 4; ++quad) {
  135. let o = offset;
  136. quadSize = dv.getUint32(o, true);
  137. o += sizeOfUint32;
  138. const x = Math$1.CesiumMath.toRadians(dv.getFloat64(o, true) * 180.0);
  139. o += sizeOfDouble;
  140. if (indexOfEpsilon(quadBorderLongitudes, x) === -1) {
  141. quadBorderLongitudes.push(x);
  142. }
  143. const y = Math$1.CesiumMath.toRadians(dv.getFloat64(o, true) * 180.0);
  144. o += sizeOfDouble;
  145. if (indexOfEpsilon(quadBorderLatitudes, y) === -1) {
  146. quadBorderLatitudes.push(y);
  147. }
  148. o += 2 * sizeOfDouble; // stepX + stepY
  149. let c = dv.getInt32(o, true); // Read point count
  150. o += sizeOfInt32;
  151. size += c;
  152. c = dv.getInt32(o, true); // Read index count
  153. indicesSize += c * 3;
  154. offset += quadSize + sizeOfUint32; // Jump to next quad
  155. }
  156. // Quad Border points to remove duplicates
  157. const quadBorderPoints = [];
  158. const quadBorderIndices = [];
  159. // Create arrays
  160. const positions = new Array(size);
  161. const uvs = new Array(size);
  162. const heights = new Array(size);
  163. const webMercatorTs = includeWebMercatorT ? new Array(size) : [];
  164. const geodeticSurfaceNormals = includeGeodeticSurfaceNormals
  165. ? new Array(size)
  166. : [];
  167. const indices = new Array(indicesSize);
  168. // Points are laid out in rows starting at SW, so storing border points as we
  169. // come across them all points will be adjacent.
  170. const westBorder = [];
  171. const southBorder = [];
  172. const eastBorder = [];
  173. const northBorder = [];
  174. // Each tile is split into 4 parts
  175. let pointOffset = 0;
  176. let indicesOffset = 0;
  177. offset = 0;
  178. for (quad = 0; quad < 4; ++quad) {
  179. quadSize = dv.getUint32(offset, true);
  180. offset += sizeOfUint32;
  181. const startQuad = offset;
  182. const originX = Math$1.CesiumMath.toRadians(dv.getFloat64(offset, true) * 180.0);
  183. offset += sizeOfDouble;
  184. const originY = Math$1.CesiumMath.toRadians(dv.getFloat64(offset, true) * 180.0);
  185. offset += sizeOfDouble;
  186. const stepX = Math$1.CesiumMath.toRadians(dv.getFloat64(offset, true) * 180.0);
  187. const halfStepX = stepX * 0.5;
  188. offset += sizeOfDouble;
  189. const stepY = Math$1.CesiumMath.toRadians(dv.getFloat64(offset, true) * 180.0);
  190. const halfStepY = stepY * 0.5;
  191. offset += sizeOfDouble;
  192. const numPoints = dv.getInt32(offset, true);
  193. offset += sizeOfInt32;
  194. const numFaces = dv.getInt32(offset, true);
  195. offset += sizeOfInt32;
  196. //const level = dv.getInt32(offset, true);
  197. offset += sizeOfInt32;
  198. // Keep track of quad indices to overall tile indices
  199. const indicesMapping = new Array(numPoints);
  200. for (let i = 0; i < numPoints; ++i) {
  201. const longitude = originX + dv.getUint8(offset++) * stepX;
  202. scratchCartographic.longitude = longitude;
  203. const latitude = originY + dv.getUint8(offset++) * stepY;
  204. scratchCartographic.latitude = latitude;
  205. let height = dv.getFloat32(offset, true);
  206. offset += sizeOfFloat;
  207. // In order to support old clients, negative altitude values are stored as
  208. // height/-2^32. Old clients see the value as really close to 0 but new clients multiply
  209. // by -2^32 to get the real negative altitude value.
  210. if (height !== 0 && height < negativeElevationThreshold) {
  211. height *= -Math.pow(2, negativeAltitudeExponentBias);
  212. }
  213. // Height is stored in units of (1/EarthRadius) or (1/6371010.0)
  214. height *= 6371010.0;
  215. scratchCartographic.height = height;
  216. // Is it along a quad border - if so check if already exists and use that index
  217. if (
  218. indexOfEpsilon(quadBorderLongitudes, longitude) !== -1 ||
  219. indexOfEpsilon(quadBorderLatitudes, latitude) !== -1
  220. ) {
  221. const index = indexOfEpsilon(
  222. quadBorderPoints,
  223. scratchCartographic,
  224. Matrix3.Cartographic
  225. );
  226. if (index === -1) {
  227. quadBorderPoints.push(Matrix3.Cartographic.clone(scratchCartographic));
  228. quadBorderIndices.push(pointOffset);
  229. } else {
  230. indicesMapping[i] = quadBorderIndices[index];
  231. continue;
  232. }
  233. }
  234. indicesMapping[i] = pointOffset;
  235. if (Math.abs(longitude - geographicWest) < halfStepX) {
  236. westBorder.push({
  237. index: pointOffset,
  238. cartographic: Matrix3.Cartographic.clone(scratchCartographic),
  239. });
  240. } else if (Math.abs(longitude - geographicEast) < halfStepX) {
  241. eastBorder.push({
  242. index: pointOffset,
  243. cartographic: Matrix3.Cartographic.clone(scratchCartographic),
  244. });
  245. } else if (Math.abs(latitude - geographicSouth) < halfStepY) {
  246. southBorder.push({
  247. index: pointOffset,
  248. cartographic: Matrix3.Cartographic.clone(scratchCartographic),
  249. });
  250. } else if (Math.abs(latitude - geographicNorth) < halfStepY) {
  251. northBorder.push({
  252. index: pointOffset,
  253. cartographic: Matrix3.Cartographic.clone(scratchCartographic),
  254. });
  255. }
  256. minHeight = Math.min(height, minHeight);
  257. maxHeight = Math.max(height, maxHeight);
  258. heights[pointOffset] = height;
  259. const pos = ellipsoid.cartographicToCartesian(scratchCartographic);
  260. positions[pointOffset] = pos;
  261. if (includeWebMercatorT) {
  262. webMercatorTs[pointOffset] =
  263. (WebMercatorProjection.WebMercatorProjection.geodeticLatitudeToMercatorAngle(latitude) -
  264. southMercatorY) *
  265. oneOverMercatorHeight;
  266. }
  267. if (includeGeodeticSurfaceNormals) {
  268. const normal = ellipsoid.geodeticSurfaceNormal(pos);
  269. geodeticSurfaceNormals[pointOffset] = normal;
  270. }
  271. Matrix2.Matrix4.multiplyByPoint(toENU, pos, scratchCartesian);
  272. Matrix3.Cartesian3.minimumByComponent(scratchCartesian, minimum, minimum);
  273. Matrix3.Cartesian3.maximumByComponent(scratchCartesian, maximum, maximum);
  274. let u = (longitude - geographicWest) / (geographicEast - geographicWest);
  275. u = Math$1.CesiumMath.clamp(u, 0.0, 1.0);
  276. let v =
  277. (latitude - geographicSouth) / (geographicNorth - geographicSouth);
  278. v = Math$1.CesiumMath.clamp(v, 0.0, 1.0);
  279. uvs[pointOffset] = new Matrix2.Cartesian2(u, v);
  280. ++pointOffset;
  281. }
  282. const facesElementCount = numFaces * 3;
  283. for (let j = 0; j < facesElementCount; ++j, ++indicesOffset) {
  284. indices[indicesOffset] = indicesMapping[dv.getUint16(offset, true)];
  285. offset += sizeOfUint16;
  286. }
  287. if (quadSize !== offset - startQuad) {
  288. throw new RuntimeError.RuntimeError("Invalid terrain tile.");
  289. }
  290. }
  291. positions.length = pointOffset;
  292. uvs.length = pointOffset;
  293. heights.length = pointOffset;
  294. if (includeWebMercatorT) {
  295. webMercatorTs.length = pointOffset;
  296. }
  297. if (includeGeodeticSurfaceNormals) {
  298. geodeticSurfaceNormals.length = pointOffset;
  299. }
  300. const vertexCountWithoutSkirts = pointOffset;
  301. const indexCountWithoutSkirts = indicesOffset;
  302. // Add skirt points
  303. const skirtOptions = {
  304. hMin: minHeight,
  305. lastBorderPoint: undefined,
  306. skirtHeight: skirtHeight,
  307. toENU: toENU,
  308. ellipsoid: ellipsoid,
  309. minimum: minimum,
  310. maximum: maximum,
  311. };
  312. // Sort counter clockwise from NW corner
  313. // Corner points are in the east/west arrays
  314. westBorder.sort(function (a, b) {
  315. return b.cartographic.latitude - a.cartographic.latitude;
  316. });
  317. southBorder.sort(function (a, b) {
  318. return a.cartographic.longitude - b.cartographic.longitude;
  319. });
  320. eastBorder.sort(function (a, b) {
  321. return a.cartographic.latitude - b.cartographic.latitude;
  322. });
  323. northBorder.sort(function (a, b) {
  324. return b.cartographic.longitude - a.cartographic.longitude;
  325. });
  326. const percentage = 0.00001;
  327. addSkirt(
  328. positions,
  329. heights,
  330. uvs,
  331. webMercatorTs,
  332. geodeticSurfaceNormals,
  333. indices,
  334. skirtOptions,
  335. westBorder,
  336. -percentage * rectangleWidth,
  337. true,
  338. -percentage * rectangleHeight
  339. );
  340. addSkirt(
  341. positions,
  342. heights,
  343. uvs,
  344. webMercatorTs,
  345. geodeticSurfaceNormals,
  346. indices,
  347. skirtOptions,
  348. southBorder,
  349. -percentage * rectangleHeight,
  350. false
  351. );
  352. addSkirt(
  353. positions,
  354. heights,
  355. uvs,
  356. webMercatorTs,
  357. geodeticSurfaceNormals,
  358. indices,
  359. skirtOptions,
  360. eastBorder,
  361. percentage * rectangleWidth,
  362. true,
  363. percentage * rectangleHeight
  364. );
  365. addSkirt(
  366. positions,
  367. heights,
  368. uvs,
  369. webMercatorTs,
  370. geodeticSurfaceNormals,
  371. indices,
  372. skirtOptions,
  373. northBorder,
  374. percentage * rectangleHeight,
  375. false
  376. );
  377. // Since the corner between the north and west sides is in the west array, generate the last
  378. // two triangles between the last north vertex and the first west vertex
  379. if (westBorder.length > 0 && northBorder.length > 0) {
  380. const firstBorderIndex = westBorder[0].index;
  381. const firstSkirtIndex = vertexCountWithoutSkirts;
  382. const lastBorderIndex = northBorder[northBorder.length - 1].index;
  383. const lastSkirtIndex = positions.length - 1;
  384. indices.push(
  385. lastBorderIndex,
  386. lastSkirtIndex,
  387. firstSkirtIndex,
  388. firstSkirtIndex,
  389. firstBorderIndex,
  390. lastBorderIndex
  391. );
  392. }
  393. size = positions.length; // Get new size with skirt vertices
  394. const boundingSphere3D = Transforms.BoundingSphere.fromPoints(positions);
  395. let orientedBoundingBox;
  396. if (defaultValue.defined(rectangle)) {
  397. orientedBoundingBox = OrientedBoundingBox.OrientedBoundingBox.fromRectangle(
  398. rectangle,
  399. minHeight,
  400. maxHeight,
  401. ellipsoid
  402. );
  403. }
  404. const occluder = new TerrainEncoding.EllipsoidalOccluder(ellipsoid);
  405. const occludeePointInScaledSpace = occluder.computeHorizonCullingPointPossiblyUnderEllipsoid(
  406. relativeToCenter,
  407. positions,
  408. minHeight
  409. );
  410. const aaBox = new AxisAlignedBoundingBox.AxisAlignedBoundingBox(minimum, maximum, relativeToCenter);
  411. const encoding = new TerrainEncoding.TerrainEncoding(
  412. relativeToCenter,
  413. aaBox,
  414. skirtOptions.hMin,
  415. maxHeight,
  416. fromENU,
  417. false,
  418. includeWebMercatorT,
  419. includeGeodeticSurfaceNormals,
  420. exaggeration,
  421. exaggerationRelativeHeight
  422. );
  423. const vertices = new Float32Array(size * encoding.stride);
  424. let bufferIndex = 0;
  425. for (let k = 0; k < size; ++k) {
  426. bufferIndex = encoding.encode(
  427. vertices,
  428. bufferIndex,
  429. positions[k],
  430. uvs[k],
  431. heights[k],
  432. undefined,
  433. webMercatorTs[k],
  434. geodeticSurfaceNormals[k]
  435. );
  436. }
  437. const westIndicesSouthToNorth = westBorder
  438. .map(function (vertex) {
  439. return vertex.index;
  440. })
  441. .reverse();
  442. const southIndicesEastToWest = southBorder
  443. .map(function (vertex) {
  444. return vertex.index;
  445. })
  446. .reverse();
  447. const eastIndicesNorthToSouth = eastBorder
  448. .map(function (vertex) {
  449. return vertex.index;
  450. })
  451. .reverse();
  452. const northIndicesWestToEast = northBorder
  453. .map(function (vertex) {
  454. return vertex.index;
  455. })
  456. .reverse();
  457. southIndicesEastToWest.unshift(
  458. eastIndicesNorthToSouth[eastIndicesNorthToSouth.length - 1]
  459. );
  460. southIndicesEastToWest.push(westIndicesSouthToNorth[0]);
  461. northIndicesWestToEast.unshift(
  462. westIndicesSouthToNorth[westIndicesSouthToNorth.length - 1]
  463. );
  464. northIndicesWestToEast.push(eastIndicesNorthToSouth[0]);
  465. return {
  466. vertices: vertices,
  467. indices: new Uint16Array(indices),
  468. maximumHeight: maxHeight,
  469. minimumHeight: minHeight,
  470. encoding: encoding,
  471. boundingSphere3D: boundingSphere3D,
  472. orientedBoundingBox: orientedBoundingBox,
  473. occludeePointInScaledSpace: occludeePointInScaledSpace,
  474. vertexCountWithoutSkirts: vertexCountWithoutSkirts,
  475. indexCountWithoutSkirts: indexCountWithoutSkirts,
  476. westIndicesSouthToNorth: westIndicesSouthToNorth,
  477. southIndicesEastToWest: southIndicesEastToWest,
  478. eastIndicesNorthToSouth: eastIndicesNorthToSouth,
  479. northIndicesWestToEast: northIndicesWestToEast,
  480. };
  481. }
  482. function addSkirt(
  483. positions,
  484. heights,
  485. uvs,
  486. webMercatorTs,
  487. geodeticSurfaceNormals,
  488. indices,
  489. skirtOptions,
  490. borderPoints,
  491. fudgeFactor,
  492. eastOrWest,
  493. cornerFudge
  494. ) {
  495. const count = borderPoints.length;
  496. for (let j = 0; j < count; ++j) {
  497. const borderPoint = borderPoints[j];
  498. const borderCartographic = borderPoint.cartographic;
  499. const borderIndex = borderPoint.index;
  500. const currentIndex = positions.length;
  501. const longitude = borderCartographic.longitude;
  502. let latitude = borderCartographic.latitude;
  503. latitude = Math$1.CesiumMath.clamp(
  504. latitude,
  505. -Math$1.CesiumMath.PI_OVER_TWO,
  506. Math$1.CesiumMath.PI_OVER_TWO
  507. ); // Don't go over the poles
  508. const height = borderCartographic.height - skirtOptions.skirtHeight;
  509. skirtOptions.hMin = Math.min(skirtOptions.hMin, height);
  510. Matrix3.Cartographic.fromRadians(longitude, latitude, height, scratchCartographic);
  511. // Adjust sides to angle out
  512. if (eastOrWest) {
  513. scratchCartographic.longitude += fudgeFactor;
  514. }
  515. // Adjust top or bottom to angle out
  516. // Since corners are in the east/west arrays angle the first and last points as well
  517. if (!eastOrWest) {
  518. scratchCartographic.latitude += fudgeFactor;
  519. } else if (j === count - 1) {
  520. scratchCartographic.latitude += cornerFudge;
  521. } else if (j === 0) {
  522. scratchCartographic.latitude -= cornerFudge;
  523. }
  524. const pos = skirtOptions.ellipsoid.cartographicToCartesian(
  525. scratchCartographic
  526. );
  527. positions.push(pos);
  528. heights.push(height);
  529. uvs.push(Matrix2.Cartesian2.clone(uvs[borderIndex])); // Copy UVs from border point
  530. if (webMercatorTs.length > 0) {
  531. webMercatorTs.push(webMercatorTs[borderIndex]);
  532. }
  533. if (geodeticSurfaceNormals.length > 0) {
  534. geodeticSurfaceNormals.push(geodeticSurfaceNormals[borderIndex]);
  535. }
  536. Matrix2.Matrix4.multiplyByPoint(skirtOptions.toENU, pos, scratchCartesian);
  537. const minimum = skirtOptions.minimum;
  538. const maximum = skirtOptions.maximum;
  539. Matrix3.Cartesian3.minimumByComponent(scratchCartesian, minimum, minimum);
  540. Matrix3.Cartesian3.maximumByComponent(scratchCartesian, maximum, maximum);
  541. const lastBorderPoint = skirtOptions.lastBorderPoint;
  542. if (defaultValue.defined(lastBorderPoint)) {
  543. const lastBorderIndex = lastBorderPoint.index;
  544. indices.push(
  545. lastBorderIndex,
  546. currentIndex - 1,
  547. currentIndex,
  548. currentIndex,
  549. borderIndex,
  550. lastBorderIndex
  551. );
  552. }
  553. skirtOptions.lastBorderPoint = borderPoint;
  554. }
  555. }
  556. var createVerticesFromGoogleEarthEnterpriseBuffer$1 = createTaskProcessorWorker(
  557. createVerticesFromGoogleEarthEnterpriseBuffer
  558. );
  559. return createVerticesFromGoogleEarthEnterpriseBuffer$1;
  560. }));