upsampleQuantizedTerrainMesh.js 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  1. /* This file is automatically rebuilt by the Cesium build process. */
  2. define(['./defined-26bd4a03', './Check-da037458', './freezeObject-2d83f591', './defaultValue-f2e68450', './Math-fa6e45cb', './Cartesian2-2a723276', './defineProperties-6f7a50f2', './Transforms-65aba0a4', './RuntimeError-ad75c885', './WebGLConstants-497deb20', './ComponentDatatype-69643096', './when-ee12a2cb', './AttributeCompression-87682214', './IndexDatatype-3de60176', './IntersectionTests-c2360ffa', './Plane-a1a3fd52', './createTaskProcessorWorker', './EllipsoidTangentPlane-10c6053a', './OrientedBoundingBox-a786ab5d', './EllipsoidalOccluder-5541419b', './TerrainEncoding-4dcd0461'], function (defined, Check, freezeObject, defaultValue, _Math, Cartesian2, defineProperties, Transforms, RuntimeError, WebGLConstants, ComponentDatatype, when, AttributeCompression, IndexDatatype, IntersectionTests, Plane, createTaskProcessorWorker, EllipsoidTangentPlane, OrientedBoundingBox, EllipsoidalOccluder, TerrainEncoding) { 'use strict';
  3. /**
  4. * Contains functions for operating on 2D triangles.
  5. *
  6. * @exports Intersections2D
  7. */
  8. var Intersections2D = {};
  9. /**
  10. * Splits a 2D triangle at given axis-aligned threshold value and returns the resulting
  11. * polygon on a given side of the threshold. The resulting polygon may have 0, 1, 2,
  12. * 3, or 4 vertices.
  13. *
  14. * @param {Number} threshold The threshold coordinate value at which to clip the triangle.
  15. * @param {Boolean} keepAbove true to keep the portion of the triangle above the threshold, or false
  16. * to keep the portion below.
  17. * @param {Number} u0 The coordinate of the first vertex in the triangle, in counter-clockwise order.
  18. * @param {Number} u1 The coordinate of the second vertex in the triangle, in counter-clockwise order.
  19. * @param {Number} u2 The coordinate of the third vertex in the triangle, in counter-clockwise order.
  20. * @param {Number[]} [result] The array into which to copy the result. If this parameter is not supplied,
  21. * a new array is constructed and returned.
  22. * @returns {Number[]} The polygon that results after the clip, specified as a list of
  23. * vertices. The vertices are specified in counter-clockwise order.
  24. * Each vertex is either an index from the existing list (identified as
  25. * a 0, 1, or 2) or -1 indicating a new vertex not in the original triangle.
  26. * For new vertices, the -1 is followed by three additional numbers: the
  27. * index of each of the two original vertices forming the line segment that
  28. * the new vertex lies on, and the fraction of the distance from the first
  29. * vertex to the second one.
  30. *
  31. * @example
  32. * var result = Cesium.Intersections2D.clipTriangleAtAxisAlignedThreshold(0.5, false, 0.2, 0.6, 0.4);
  33. * // result === [2, 0, -1, 1, 0, 0.25, -1, 1, 2, 0.5]
  34. */
  35. Intersections2D.clipTriangleAtAxisAlignedThreshold = function(threshold, keepAbove, u0, u1, u2, result) {
  36. //>>includeStart('debug', pragmas.debug);
  37. if (!defined.defined(threshold)) {
  38. throw new Check.DeveloperError('threshold is required.');
  39. }
  40. if (!defined.defined(keepAbove)) {
  41. throw new Check.DeveloperError('keepAbove is required.');
  42. }
  43. if (!defined.defined(u0)) {
  44. throw new Check.DeveloperError('u0 is required.');
  45. }
  46. if (!defined.defined(u1)) {
  47. throw new Check.DeveloperError('u1 is required.');
  48. }
  49. if (!defined.defined(u2)) {
  50. throw new Check.DeveloperError('u2 is required.');
  51. }
  52. //>>includeEnd('debug');
  53. if (!defined.defined(result)) {
  54. result = [];
  55. } else {
  56. result.length = 0;
  57. }
  58. var u0Behind;
  59. var u1Behind;
  60. var u2Behind;
  61. if (keepAbove) {
  62. u0Behind = u0 < threshold;
  63. u1Behind = u1 < threshold;
  64. u2Behind = u2 < threshold;
  65. } else {
  66. u0Behind = u0 > threshold;
  67. u1Behind = u1 > threshold;
  68. u2Behind = u2 > threshold;
  69. }
  70. var numBehind = u0Behind + u1Behind + u2Behind;
  71. var u01Ratio;
  72. var u02Ratio;
  73. var u12Ratio;
  74. var u10Ratio;
  75. var u20Ratio;
  76. var u21Ratio;
  77. if (numBehind === 1) {
  78. if (u0Behind) {
  79. u01Ratio = (threshold - u0) / (u1 - u0);
  80. u02Ratio = (threshold - u0) / (u2 - u0);
  81. result.push(1);
  82. result.push(2);
  83. if (u02Ratio !== 1.0) {
  84. result.push(-1);
  85. result.push(0);
  86. result.push(2);
  87. result.push(u02Ratio);
  88. }
  89. if (u01Ratio !== 1.0) {
  90. result.push(-1);
  91. result.push(0);
  92. result.push(1);
  93. result.push(u01Ratio);
  94. }
  95. } else if (u1Behind) {
  96. u12Ratio = (threshold - u1) / (u2 - u1);
  97. u10Ratio = (threshold - u1) / (u0 - u1);
  98. result.push(2);
  99. result.push(0);
  100. if (u10Ratio !== 1.0) {
  101. result.push(-1);
  102. result.push(1);
  103. result.push(0);
  104. result.push(u10Ratio);
  105. }
  106. if (u12Ratio !== 1.0) {
  107. result.push(-1);
  108. result.push(1);
  109. result.push(2);
  110. result.push(u12Ratio);
  111. }
  112. } else if (u2Behind) {
  113. u20Ratio = (threshold - u2) / (u0 - u2);
  114. u21Ratio = (threshold - u2) / (u1 - u2);
  115. result.push(0);
  116. result.push(1);
  117. if (u21Ratio !== 1.0) {
  118. result.push(-1);
  119. result.push(2);
  120. result.push(1);
  121. result.push(u21Ratio);
  122. }
  123. if (u20Ratio !== 1.0) {
  124. result.push(-1);
  125. result.push(2);
  126. result.push(0);
  127. result.push(u20Ratio);
  128. }
  129. }
  130. } else if (numBehind === 2) {
  131. if (!u0Behind && u0 !== threshold) {
  132. u10Ratio = (threshold - u1) / (u0 - u1);
  133. u20Ratio = (threshold - u2) / (u0 - u2);
  134. result.push(0);
  135. result.push(-1);
  136. result.push(1);
  137. result.push(0);
  138. result.push(u10Ratio);
  139. result.push(-1);
  140. result.push(2);
  141. result.push(0);
  142. result.push(u20Ratio);
  143. } else if (!u1Behind && u1 !== threshold) {
  144. u21Ratio = (threshold - u2) / (u1 - u2);
  145. u01Ratio = (threshold - u0) / (u1 - u0);
  146. result.push(1);
  147. result.push(-1);
  148. result.push(2);
  149. result.push(1);
  150. result.push(u21Ratio);
  151. result.push(-1);
  152. result.push(0);
  153. result.push(1);
  154. result.push(u01Ratio);
  155. } else if (!u2Behind && u2 !== threshold) {
  156. u02Ratio = (threshold - u0) / (u2 - u0);
  157. u12Ratio = (threshold - u1) / (u2 - u1);
  158. result.push(2);
  159. result.push(-1);
  160. result.push(0);
  161. result.push(2);
  162. result.push(u02Ratio);
  163. result.push(-1);
  164. result.push(1);
  165. result.push(2);
  166. result.push(u12Ratio);
  167. }
  168. } else if (numBehind !== 3) {
  169. // Completely in front of threshold
  170. result.push(0);
  171. result.push(1);
  172. result.push(2);
  173. }
  174. // else Completely behind threshold
  175. return result;
  176. };
  177. /**
  178. * Compute the barycentric coordinates of a 2D position within a 2D triangle.
  179. *
  180. * @param {Number} x The x coordinate of the position for which to find the barycentric coordinates.
  181. * @param {Number} y The y coordinate of the position for which to find the barycentric coordinates.
  182. * @param {Number} x1 The x coordinate of the triangle's first vertex.
  183. * @param {Number} y1 The y coordinate of the triangle's first vertex.
  184. * @param {Number} x2 The x coordinate of the triangle's second vertex.
  185. * @param {Number} y2 The y coordinate of the triangle's second vertex.
  186. * @param {Number} x3 The x coordinate of the triangle's third vertex.
  187. * @param {Number} y3 The y coordinate of the triangle's third vertex.
  188. * @param {Cartesian3} [result] The instance into to which to copy the result. If this parameter
  189. * is undefined, a new instance is created and returned.
  190. * @returns {Cartesian3} The barycentric coordinates of the position within the triangle.
  191. *
  192. * @example
  193. * var result = Cesium.Intersections2D.computeBarycentricCoordinates(0.0, 0.0, 0.0, 1.0, -1, -0.5, 1, -0.5);
  194. * // result === new Cesium.Cartesian3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0);
  195. */
  196. Intersections2D.computeBarycentricCoordinates = function(x, y, x1, y1, x2, y2, x3, y3, result) {
  197. //>>includeStart('debug', pragmas.debug);
  198. if (!defined.defined(x)) {
  199. throw new Check.DeveloperError('x is required.');
  200. }
  201. if (!defined.defined(y)) {
  202. throw new Check.DeveloperError('y is required.');
  203. }
  204. if (!defined.defined(x1)) {
  205. throw new Check.DeveloperError('x1 is required.');
  206. }
  207. if (!defined.defined(y1)) {
  208. throw new Check.DeveloperError('y1 is required.');
  209. }
  210. if (!defined.defined(x2)) {
  211. throw new Check.DeveloperError('x2 is required.');
  212. }
  213. if (!defined.defined(y2)) {
  214. throw new Check.DeveloperError('y2 is required.');
  215. }
  216. if (!defined.defined(x3)) {
  217. throw new Check.DeveloperError('x3 is required.');
  218. }
  219. if (!defined.defined(y3)) {
  220. throw new Check.DeveloperError('y3 is required.');
  221. }
  222. //>>includeEnd('debug');
  223. var x1mx3 = x1 - x3;
  224. var x3mx2 = x3 - x2;
  225. var y2my3 = y2 - y3;
  226. var y1my3 = y1 - y3;
  227. var inverseDeterminant = 1.0 / (y2my3 * x1mx3 + x3mx2 * y1my3);
  228. var ymy3 = y - y3;
  229. var xmx3 = x - x3;
  230. var l1 = (y2my3 * xmx3 + x3mx2 * ymy3) * inverseDeterminant;
  231. var l2 = (-y1my3 * xmx3 + x1mx3 * ymy3) * inverseDeterminant;
  232. var l3 = 1.0 - l1 - l2;
  233. if (defined.defined(result)) {
  234. result.x = l1;
  235. result.y = l2;
  236. result.z = l3;
  237. return result;
  238. }
  239. return new Cartesian2.Cartesian3(l1, l2, l3);
  240. };
  241. /**
  242. * Compute the intersection between 2 line segments
  243. *
  244. * @param {Number} x00 The x coordinate of the first line's first vertex.
  245. * @param {Number} y00 The y coordinate of the first line's first vertex.
  246. * @param {Number} x01 The x coordinate of the first line's second vertex.
  247. * @param {Number} y01 The y coordinate of the first line's second vertex.
  248. * @param {Number} x10 The x coordinate of the second line's first vertex.
  249. * @param {Number} y10 The y coordinate of the second line's first vertex.
  250. * @param {Number} x11 The x coordinate of the second line's second vertex.
  251. * @param {Number} y11 The y coordinate of the second line's second vertex.
  252. * @param {Cartesian2} [result] The instance into to which to copy the result. If this parameter
  253. * is undefined, a new instance is created and returned.
  254. * @returns {Cartesian2} The intersection point, undefined if there is no intersection point or lines are coincident.
  255. *
  256. * @example
  257. * var result = Cesium.Intersections2D.computeLineSegmentLineSegmentIntersection(0.0, 0.0, 0.0, 2.0, -1, 1, 1, 1);
  258. * // result === new Cesium.Cartesian2(0.0, 1.0);
  259. */
  260. Intersections2D.computeLineSegmentLineSegmentIntersection = function(x00, y00, x01, y01, x10, y10, x11, y11, result) {
  261. //>>includeStart('debug', pragmas.debug);
  262. Check.Check.typeOf.number('x00', x00);
  263. Check.Check.typeOf.number('y00', y00);
  264. Check.Check.typeOf.number('x01', x01);
  265. Check.Check.typeOf.number('y01', y01);
  266. Check.Check.typeOf.number('x10', x10);
  267. Check.Check.typeOf.number('y10', y10);
  268. Check.Check.typeOf.number('x11', x11);
  269. Check.Check.typeOf.number('y11', y11);
  270. //>>includeEnd('debug');
  271. var numerator1A = (x11 - x10) * (y00 - y10) - (y11 - y10) * (x00 - x10);
  272. var numerator1B = (x01 - x00) * (y00 - y10) - (y01 - y00) * (x00 - x10);
  273. var denominator1 = (y11 - y10) * (x01 - x00) - (x11 - x10) * (y01 - y00);
  274. // If denominator = 0, then lines are parallel. If denominator = 0 and both numerators are 0, then coincident
  275. if (denominator1 === 0) {
  276. return;
  277. }
  278. var ua1 = numerator1A / denominator1;
  279. var ub1 = numerator1B / denominator1;
  280. if (ua1 >= 0 && ua1 <= 1 && ub1 >= 0 && ub1 <= 1) {
  281. if (!defined.defined(result)) {
  282. result = new Cartesian2.Cartesian2();
  283. }
  284. result.x = x00 + ua1 * (x01 - x00);
  285. result.y = y00 + ua1 * (y01 - y00);
  286. return result;
  287. }
  288. };
  289. var maxShort = 32767;
  290. var halfMaxShort = (maxShort / 2) | 0;
  291. var clipScratch = [];
  292. var clipScratch2 = [];
  293. var verticesScratch = [];
  294. var cartographicScratch = new Cartesian2.Cartographic();
  295. var cartesian3Scratch = new Cartesian2.Cartesian3();
  296. var uScratch = [];
  297. var vScratch = [];
  298. var heightScratch = [];
  299. var indicesScratch = [];
  300. var normalsScratch = [];
  301. var horizonOcclusionPointScratch = new Cartesian2.Cartesian3();
  302. var boundingSphereScratch = new Transforms.BoundingSphere();
  303. var orientedBoundingBoxScratch = new OrientedBoundingBox.OrientedBoundingBox();
  304. var decodeTexCoordsScratch = new Cartesian2.Cartesian2();
  305. var octEncodedNormalScratch = new Cartesian2.Cartesian3();
  306. function upsampleQuantizedTerrainMesh(parameters, transferableObjects) {
  307. var isEastChild = parameters.isEastChild;
  308. var isNorthChild = parameters.isNorthChild;
  309. var minU = isEastChild ? halfMaxShort : 0;
  310. var maxU = isEastChild ? maxShort : halfMaxShort;
  311. var minV = isNorthChild ? halfMaxShort : 0;
  312. var maxV = isNorthChild ? maxShort : halfMaxShort;
  313. var uBuffer = uScratch;
  314. var vBuffer = vScratch;
  315. var heightBuffer = heightScratch;
  316. var normalBuffer = normalsScratch;
  317. uBuffer.length = 0;
  318. vBuffer.length = 0;
  319. heightBuffer.length = 0;
  320. normalBuffer.length = 0;
  321. var indices = indicesScratch;
  322. indices.length = 0;
  323. var vertexMap = {};
  324. var parentVertices = parameters.vertices;
  325. var parentIndices = parameters.indices;
  326. parentIndices = parentIndices.subarray(0, parameters.skirtIndex);
  327. var encoding = TerrainEncoding.TerrainEncoding.clone(parameters.encoding);
  328. var hasVertexNormals = encoding.hasVertexNormals;
  329. var exaggeration = parameters.exaggeration;
  330. var vertexCount = 0;
  331. var quantizedVertexCount = parameters.vertexCountWithoutSkirts;
  332. var parentMinimumHeight = parameters.minimumHeight;
  333. var parentMaximumHeight = parameters.maximumHeight;
  334. var parentUBuffer = new Array(quantizedVertexCount);
  335. var parentVBuffer = new Array(quantizedVertexCount);
  336. var parentHeightBuffer = new Array(quantizedVertexCount);
  337. var parentNormalBuffer = hasVertexNormals ? new Array(quantizedVertexCount * 2) : undefined;
  338. var threshold = 20;
  339. var height;
  340. var i, n;
  341. var u, v;
  342. for (i = 0, n = 0; i < quantizedVertexCount; ++i, n += 2) {
  343. var texCoords = encoding.decodeTextureCoordinates(parentVertices, i, decodeTexCoordsScratch);
  344. height = encoding.decodeHeight(parentVertices, i) / exaggeration;
  345. u = _Math.CesiumMath.clamp((texCoords.x * maxShort) | 0, 0, maxShort);
  346. v = _Math.CesiumMath.clamp((texCoords.y * maxShort) | 0, 0, maxShort);
  347. parentHeightBuffer[i] = _Math.CesiumMath.clamp((((height - parentMinimumHeight) / (parentMaximumHeight - parentMinimumHeight)) * maxShort) | 0, 0, maxShort);
  348. if (u < threshold) {
  349. u = 0;
  350. }
  351. if (v < threshold) {
  352. v = 0;
  353. }
  354. if (maxShort - u < threshold) {
  355. u = maxShort;
  356. }
  357. if (maxShort - v < threshold) {
  358. v = maxShort;
  359. }
  360. parentUBuffer[i] = u;
  361. parentVBuffer[i] = v;
  362. if (hasVertexNormals) {
  363. var encodedNormal = encoding.getOctEncodedNormal(parentVertices, i, octEncodedNormalScratch);
  364. parentNormalBuffer[n] = encodedNormal.x;
  365. parentNormalBuffer[n + 1] = encodedNormal.y;
  366. }
  367. if ((isEastChild && u >= halfMaxShort || !isEastChild && u <= halfMaxShort) &&
  368. (isNorthChild && v >= halfMaxShort || !isNorthChild && v <= halfMaxShort)) {
  369. vertexMap[i] = vertexCount;
  370. uBuffer.push(u);
  371. vBuffer.push(v);
  372. heightBuffer.push(parentHeightBuffer[i]);
  373. if (hasVertexNormals) {
  374. normalBuffer.push(parentNormalBuffer[n]);
  375. normalBuffer.push(parentNormalBuffer[n + 1]);
  376. }
  377. ++vertexCount;
  378. }
  379. }
  380. var triangleVertices = [];
  381. triangleVertices.push(new Vertex());
  382. triangleVertices.push(new Vertex());
  383. triangleVertices.push(new Vertex());
  384. var clippedTriangleVertices = [];
  385. clippedTriangleVertices.push(new Vertex());
  386. clippedTriangleVertices.push(new Vertex());
  387. clippedTriangleVertices.push(new Vertex());
  388. var clippedIndex;
  389. var clipped2;
  390. for (i = 0; i < parentIndices.length; i += 3) {
  391. var i0 = parentIndices[i];
  392. var i1 = parentIndices[i + 1];
  393. var i2 = parentIndices[i + 2];
  394. var u0 = parentUBuffer[i0];
  395. var u1 = parentUBuffer[i1];
  396. var u2 = parentUBuffer[i2];
  397. triangleVertices[0].initializeIndexed(parentUBuffer, parentVBuffer, parentHeightBuffer, parentNormalBuffer, i0);
  398. triangleVertices[1].initializeIndexed(parentUBuffer, parentVBuffer, parentHeightBuffer, parentNormalBuffer, i1);
  399. triangleVertices[2].initializeIndexed(parentUBuffer, parentVBuffer, parentHeightBuffer, parentNormalBuffer, i2);
  400. // Clip triangle on the east-west boundary.
  401. var clipped = Intersections2D.clipTriangleAtAxisAlignedThreshold(halfMaxShort, isEastChild, u0, u1, u2, clipScratch);
  402. // Get the first clipped triangle, if any.
  403. clippedIndex = 0;
  404. if (clippedIndex >= clipped.length) {
  405. continue;
  406. }
  407. clippedIndex = clippedTriangleVertices[0].initializeFromClipResult(clipped, clippedIndex, triangleVertices);
  408. if (clippedIndex >= clipped.length) {
  409. continue;
  410. }
  411. clippedIndex = clippedTriangleVertices[1].initializeFromClipResult(clipped, clippedIndex, triangleVertices);
  412. if (clippedIndex >= clipped.length) {
  413. continue;
  414. }
  415. clippedIndex = clippedTriangleVertices[2].initializeFromClipResult(clipped, clippedIndex, triangleVertices);
  416. // Clip the triangle against the North-south boundary.
  417. clipped2 = Intersections2D.clipTriangleAtAxisAlignedThreshold(halfMaxShort, isNorthChild, clippedTriangleVertices[0].getV(), clippedTriangleVertices[1].getV(), clippedTriangleVertices[2].getV(), clipScratch2);
  418. addClippedPolygon(uBuffer, vBuffer, heightBuffer, normalBuffer, indices, vertexMap, clipped2, clippedTriangleVertices, hasVertexNormals);
  419. // If there's another vertex in the original clipped result,
  420. // it forms a second triangle. Clip it as well.
  421. if (clippedIndex < clipped.length) {
  422. clippedTriangleVertices[2].clone(clippedTriangleVertices[1]);
  423. clippedTriangleVertices[2].initializeFromClipResult(clipped, clippedIndex, triangleVertices);
  424. clipped2 = Intersections2D.clipTriangleAtAxisAlignedThreshold(halfMaxShort, isNorthChild, clippedTriangleVertices[0].getV(), clippedTriangleVertices[1].getV(), clippedTriangleVertices[2].getV(), clipScratch2);
  425. addClippedPolygon(uBuffer, vBuffer, heightBuffer, normalBuffer, indices, vertexMap, clipped2, clippedTriangleVertices, hasVertexNormals);
  426. }
  427. }
  428. var uOffset = isEastChild ? -maxShort : 0;
  429. var vOffset = isNorthChild ? -maxShort : 0;
  430. var westIndices = [];
  431. var southIndices = [];
  432. var eastIndices = [];
  433. var northIndices = [];
  434. var minimumHeight = Number.MAX_VALUE;
  435. var maximumHeight = -minimumHeight;
  436. var cartesianVertices = verticesScratch;
  437. cartesianVertices.length = 0;
  438. var ellipsoid = Cartesian2.Ellipsoid.clone(parameters.ellipsoid);
  439. var rectangle = parameters.childRectangle;
  440. var north = rectangle.north;
  441. var south = rectangle.south;
  442. var east = rectangle.east;
  443. var west = rectangle.west;
  444. if (east < west) {
  445. east += _Math.CesiumMath.TWO_PI;
  446. }
  447. for (i = 0; i < uBuffer.length; ++i) {
  448. u = Math.round(uBuffer[i]);
  449. if (u <= minU) {
  450. westIndices.push(i);
  451. u = 0;
  452. } else if (u >= maxU) {
  453. eastIndices.push(i);
  454. u = maxShort;
  455. } else {
  456. u = u * 2 + uOffset;
  457. }
  458. uBuffer[i] = u;
  459. v = Math.round(vBuffer[i]);
  460. if (v <= minV) {
  461. southIndices.push(i);
  462. v = 0;
  463. } else if (v >= maxV) {
  464. northIndices.push(i);
  465. v = maxShort;
  466. } else {
  467. v = v * 2 + vOffset;
  468. }
  469. vBuffer[i] = v;
  470. height = _Math.CesiumMath.lerp(parentMinimumHeight, parentMaximumHeight, heightBuffer[i] / maxShort);
  471. if (height < minimumHeight) {
  472. minimumHeight = height;
  473. }
  474. if (height > maximumHeight) {
  475. maximumHeight = height;
  476. }
  477. heightBuffer[i] = height;
  478. cartographicScratch.longitude = _Math.CesiumMath.lerp(west, east, u / maxShort);
  479. cartographicScratch.latitude = _Math.CesiumMath.lerp(south, north, v / maxShort);
  480. cartographicScratch.height = height;
  481. ellipsoid.cartographicToCartesian(cartographicScratch, cartesian3Scratch);
  482. cartesianVertices.push(cartesian3Scratch.x);
  483. cartesianVertices.push(cartesian3Scratch.y);
  484. cartesianVertices.push(cartesian3Scratch.z);
  485. }
  486. var boundingSphere = Transforms.BoundingSphere.fromVertices(cartesianVertices, Cartesian2.Cartesian3.ZERO, 3, boundingSphereScratch);
  487. var orientedBoundingBox = OrientedBoundingBox.OrientedBoundingBox.fromRectangle(rectangle, minimumHeight, maximumHeight, ellipsoid, orientedBoundingBoxScratch);
  488. var occluder = new EllipsoidalOccluder.EllipsoidalOccluder(ellipsoid);
  489. var horizonOcclusionPoint = occluder.computeHorizonCullingPointFromVertices(boundingSphere.center, cartesianVertices, 3, boundingSphere.center, horizonOcclusionPointScratch);
  490. var heightRange = maximumHeight - minimumHeight;
  491. var vertices = new Uint16Array(uBuffer.length + vBuffer.length + heightBuffer.length);
  492. for (i = 0; i < uBuffer.length; ++i) {
  493. vertices[i] = uBuffer[i];
  494. }
  495. var start = uBuffer.length;
  496. for (i = 0; i < vBuffer.length; ++i) {
  497. vertices[start + i] = vBuffer[i];
  498. }
  499. start += vBuffer.length;
  500. for (i = 0; i < heightBuffer.length; ++i) {
  501. vertices[start + i] = maxShort * (heightBuffer[i] - minimumHeight) / heightRange;
  502. }
  503. var indicesTypedArray = IndexDatatype.IndexDatatype.createTypedArray(uBuffer.length, indices);
  504. var encodedNormals;
  505. if (hasVertexNormals) {
  506. var normalArray = new Uint8Array(normalBuffer);
  507. transferableObjects.push(vertices.buffer, indicesTypedArray.buffer, normalArray.buffer);
  508. encodedNormals = normalArray.buffer;
  509. } else {
  510. transferableObjects.push(vertices.buffer, indicesTypedArray.buffer);
  511. }
  512. return {
  513. vertices : vertices.buffer,
  514. encodedNormals : encodedNormals,
  515. indices : indicesTypedArray.buffer,
  516. minimumHeight : minimumHeight,
  517. maximumHeight : maximumHeight,
  518. westIndices : westIndices,
  519. southIndices : southIndices,
  520. eastIndices : eastIndices,
  521. northIndices : northIndices,
  522. boundingSphere : boundingSphere,
  523. orientedBoundingBox : orientedBoundingBox,
  524. horizonOcclusionPoint : horizonOcclusionPoint
  525. };
  526. }
  527. function Vertex() {
  528. this.vertexBuffer = undefined;
  529. this.index = undefined;
  530. this.first = undefined;
  531. this.second = undefined;
  532. this.ratio = undefined;
  533. }
  534. Vertex.prototype.clone = function(result) {
  535. if (!defined.defined(result)) {
  536. result = new Vertex();
  537. }
  538. result.uBuffer = this.uBuffer;
  539. result.vBuffer = this.vBuffer;
  540. result.heightBuffer = this.heightBuffer;
  541. result.normalBuffer = this.normalBuffer;
  542. result.index = this.index;
  543. result.first = this.first;
  544. result.second = this.second;
  545. result.ratio = this.ratio;
  546. return result;
  547. };
  548. Vertex.prototype.initializeIndexed = function(uBuffer, vBuffer, heightBuffer, normalBuffer, index) {
  549. this.uBuffer = uBuffer;
  550. this.vBuffer = vBuffer;
  551. this.heightBuffer = heightBuffer;
  552. this.normalBuffer = normalBuffer;
  553. this.index = index;
  554. this.first = undefined;
  555. this.second = undefined;
  556. this.ratio = undefined;
  557. };
  558. Vertex.prototype.initializeFromClipResult = function(clipResult, index, vertices) {
  559. var nextIndex = index + 1;
  560. if (clipResult[index] !== -1) {
  561. vertices[clipResult[index]].clone(this);
  562. } else {
  563. this.vertexBuffer = undefined;
  564. this.index = undefined;
  565. this.first = vertices[clipResult[nextIndex]];
  566. ++nextIndex;
  567. this.second = vertices[clipResult[nextIndex]];
  568. ++nextIndex;
  569. this.ratio = clipResult[nextIndex];
  570. ++nextIndex;
  571. }
  572. return nextIndex;
  573. };
  574. Vertex.prototype.getKey = function() {
  575. if (this.isIndexed()) {
  576. return this.index;
  577. }
  578. return JSON.stringify({
  579. first : this.first.getKey(),
  580. second : this.second.getKey(),
  581. ratio : this.ratio
  582. });
  583. };
  584. Vertex.prototype.isIndexed = function() {
  585. return defined.defined(this.index);
  586. };
  587. Vertex.prototype.getH = function() {
  588. if (defined.defined(this.index)) {
  589. return this.heightBuffer[this.index];
  590. }
  591. return _Math.CesiumMath.lerp(this.first.getH(), this.second.getH(), this.ratio);
  592. };
  593. Vertex.prototype.getU = function() {
  594. if (defined.defined(this.index)) {
  595. return this.uBuffer[this.index];
  596. }
  597. return _Math.CesiumMath.lerp(this.first.getU(), this.second.getU(), this.ratio);
  598. };
  599. Vertex.prototype.getV = function() {
  600. if (defined.defined(this.index)) {
  601. return this.vBuffer[this.index];
  602. }
  603. return _Math.CesiumMath.lerp(this.first.getV(), this.second.getV(), this.ratio);
  604. };
  605. var encodedScratch = new Cartesian2.Cartesian2();
  606. // An upsampled triangle may be clipped twice before it is assigned an index
  607. // In this case, we need a buffer to handle the recursion of getNormalX() and getNormalY().
  608. var depth = -1;
  609. var cartesianScratch1 = [new Cartesian2.Cartesian3(), new Cartesian2.Cartesian3()];
  610. var cartesianScratch2 = [new Cartesian2.Cartesian3(), new Cartesian2.Cartesian3()];
  611. function lerpOctEncodedNormal(vertex, result) {
  612. ++depth;
  613. var first = cartesianScratch1[depth];
  614. var second = cartesianScratch2[depth];
  615. first = AttributeCompression.AttributeCompression.octDecode(vertex.first.getNormalX(), vertex.first.getNormalY(), first);
  616. second = AttributeCompression.AttributeCompression.octDecode(vertex.second.getNormalX(), vertex.second.getNormalY(), second);
  617. cartesian3Scratch = Cartesian2.Cartesian3.lerp(first, second, vertex.ratio, cartesian3Scratch);
  618. Cartesian2.Cartesian3.normalize(cartesian3Scratch, cartesian3Scratch);
  619. AttributeCompression.AttributeCompression.octEncode(cartesian3Scratch, result);
  620. --depth;
  621. return result;
  622. }
  623. Vertex.prototype.getNormalX = function() {
  624. if (defined.defined(this.index)) {
  625. return this.normalBuffer[this.index * 2];
  626. }
  627. encodedScratch = lerpOctEncodedNormal(this, encodedScratch);
  628. return encodedScratch.x;
  629. };
  630. Vertex.prototype.getNormalY = function() {
  631. if (defined.defined(this.index)) {
  632. return this.normalBuffer[this.index * 2 + 1];
  633. }
  634. encodedScratch = lerpOctEncodedNormal(this, encodedScratch);
  635. return encodedScratch.y;
  636. };
  637. var polygonVertices = [];
  638. polygonVertices.push(new Vertex());
  639. polygonVertices.push(new Vertex());
  640. polygonVertices.push(new Vertex());
  641. polygonVertices.push(new Vertex());
  642. function addClippedPolygon(uBuffer, vBuffer, heightBuffer, normalBuffer, indices, vertexMap, clipped, triangleVertices, hasVertexNormals) {
  643. if (clipped.length === 0) {
  644. return;
  645. }
  646. var numVertices = 0;
  647. var clippedIndex = 0;
  648. while (clippedIndex < clipped.length) {
  649. clippedIndex = polygonVertices[numVertices++].initializeFromClipResult(clipped, clippedIndex, triangleVertices);
  650. }
  651. for (var i = 0; i < numVertices; ++i) {
  652. var polygonVertex = polygonVertices[i];
  653. if (!polygonVertex.isIndexed()) {
  654. var key = polygonVertex.getKey();
  655. if (defined.defined(vertexMap[key])) {
  656. polygonVertex.newIndex = vertexMap[key];
  657. } else {
  658. var newIndex = uBuffer.length;
  659. uBuffer.push(polygonVertex.getU());
  660. vBuffer.push(polygonVertex.getV());
  661. heightBuffer.push(polygonVertex.getH());
  662. if (hasVertexNormals) {
  663. normalBuffer.push(polygonVertex.getNormalX());
  664. normalBuffer.push(polygonVertex.getNormalY());
  665. }
  666. polygonVertex.newIndex = newIndex;
  667. vertexMap[key] = newIndex;
  668. }
  669. } else {
  670. polygonVertex.newIndex = vertexMap[polygonVertex.index];
  671. polygonVertex.uBuffer = uBuffer;
  672. polygonVertex.vBuffer = vBuffer;
  673. polygonVertex.heightBuffer = heightBuffer;
  674. if (hasVertexNormals) {
  675. polygonVertex.normalBuffer = normalBuffer;
  676. }
  677. }
  678. }
  679. if (numVertices === 3) {
  680. // A triangle.
  681. indices.push(polygonVertices[0].newIndex);
  682. indices.push(polygonVertices[1].newIndex);
  683. indices.push(polygonVertices[2].newIndex);
  684. } else if (numVertices === 4) {
  685. // A quad - two triangles.
  686. indices.push(polygonVertices[0].newIndex);
  687. indices.push(polygonVertices[1].newIndex);
  688. indices.push(polygonVertices[2].newIndex);
  689. indices.push(polygonVertices[0].newIndex);
  690. indices.push(polygonVertices[2].newIndex);
  691. indices.push(polygonVertices[3].newIndex);
  692. }
  693. }
  694. var upsampleQuantizedTerrainMesh$1 = createTaskProcessorWorker(upsampleQuantizedTerrainMesh);
  695. return upsampleQuantizedTerrainMesh$1;
  696. });