createVerticesFromGoogleEarthEnterpriseBuffer.js 22 KB

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