createVectorTilePolylines.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. import AttributeCompression from '../Core/AttributeCompression.js';
  2. import Cartesian3 from '../Core/Cartesian3.js';
  3. import Cartographic from '../Core/Cartographic.js';
  4. import Ellipsoid from '../Core/Ellipsoid.js';
  5. import IndexDatatype from '../Core/IndexDatatype.js';
  6. import CesiumMath from '../Core/Math.js';
  7. import Rectangle from '../Core/Rectangle.js';
  8. import createTaskProcessorWorker from './createTaskProcessorWorker.js';
  9. var maxShort = 32767;
  10. var scratchBVCartographic = new Cartographic();
  11. var scratchEncodedPosition = new Cartesian3();
  12. function decodePositions(positions, rectangle, minimumHeight, maximumHeight, ellipsoid) {
  13. var positionsLength = positions.length / 3;
  14. var uBuffer = positions.subarray(0, positionsLength);
  15. var vBuffer = positions.subarray(positionsLength, 2 * positionsLength);
  16. var heightBuffer = positions.subarray(2 * positionsLength, 3 * positionsLength);
  17. AttributeCompression.zigZagDeltaDecode(uBuffer, vBuffer, heightBuffer);
  18. var decoded = new Float32Array(positions.length);
  19. for (var i = 0; i < positionsLength; ++i) {
  20. var u = uBuffer[i];
  21. var v = vBuffer[i];
  22. var h = heightBuffer[i];
  23. var lon = CesiumMath.lerp(rectangle.west, rectangle.east, u / maxShort);
  24. var lat = CesiumMath.lerp(rectangle.south, rectangle.north, v / maxShort);
  25. var alt = CesiumMath.lerp(minimumHeight, maximumHeight, h / maxShort);
  26. var cartographic = Cartographic.fromRadians(lon, lat, alt, scratchBVCartographic);
  27. var decodedPosition = ellipsoid.cartographicToCartesian(cartographic, scratchEncodedPosition);
  28. Cartesian3.pack(decodedPosition, decoded, i * 3);
  29. }
  30. return decoded;
  31. }
  32. var scratchRectangle = new Rectangle();
  33. var scratchEllipsoid = new Ellipsoid();
  34. var scratchCenter = new Cartesian3();
  35. var scratchMinMaxHeights = {
  36. min : undefined,
  37. max : undefined
  38. };
  39. function unpackBuffer(packedBuffer) {
  40. packedBuffer = new Float64Array(packedBuffer);
  41. var offset = 0;
  42. scratchMinMaxHeights.min = packedBuffer[offset++];
  43. scratchMinMaxHeights.max = packedBuffer[offset++];
  44. Rectangle.unpack(packedBuffer, offset, scratchRectangle);
  45. offset += Rectangle.packedLength;
  46. Ellipsoid.unpack(packedBuffer, offset, scratchEllipsoid);
  47. offset += Ellipsoid.packedLength;
  48. Cartesian3.unpack(packedBuffer, offset, scratchCenter);
  49. }
  50. var scratchP0 = new Cartesian3();
  51. var scratchP1 = new Cartesian3();
  52. var scratchPrev = new Cartesian3();
  53. var scratchCur = new Cartesian3();
  54. var scratchNext = new Cartesian3();
  55. function createVectorTilePolylines(parameters, transferableObjects) {
  56. var encodedPositions = new Uint16Array(parameters.positions);
  57. var widths = new Uint16Array(parameters.widths);
  58. var counts = new Uint32Array(parameters.counts);
  59. var batchIds = new Uint16Array(parameters.batchIds);
  60. unpackBuffer(parameters.packedBuffer);
  61. var rectangle = scratchRectangle;
  62. var ellipsoid = scratchEllipsoid;
  63. var center = scratchCenter;
  64. var minimumHeight = scratchMinMaxHeights.min;
  65. var maximumHeight = scratchMinMaxHeights.max;
  66. var positions = decodePositions(encodedPositions, rectangle, minimumHeight, maximumHeight, ellipsoid);
  67. var positionsLength = positions.length / 3;
  68. var size = positionsLength * 4 - 4;
  69. var curPositions = new Float32Array(size * 3);
  70. var prevPositions = new Float32Array(size * 3);
  71. var nextPositions = new Float32Array(size * 3);
  72. var expandAndWidth = new Float32Array(size * 2);
  73. var vertexBatchIds = new Uint16Array(size);
  74. var positionIndex = 0;
  75. var expandAndWidthIndex = 0;
  76. var batchIdIndex = 0;
  77. var i;
  78. var offset = 0;
  79. var length = counts.length;
  80. for (i = 0; i < length; ++i) {
  81. var count = counts [i];
  82. var width = widths[i];
  83. var batchId = batchIds[i];
  84. for (var j = 0; j < count; ++j) {
  85. var previous;
  86. if (j === 0) {
  87. var p0 = Cartesian3.unpack(positions, offset * 3, scratchP0);
  88. var p1 = Cartesian3.unpack(positions, (offset + 1) * 3, scratchP1);
  89. previous = Cartesian3.subtract(p0, p1, scratchPrev);
  90. Cartesian3.add(p0, previous, previous);
  91. } else {
  92. previous = Cartesian3.unpack(positions, (offset + j - 1) * 3, scratchPrev);
  93. }
  94. var current = Cartesian3.unpack(positions, (offset + j) * 3, scratchCur);
  95. var next;
  96. if (j === count - 1) {
  97. var p2 = Cartesian3.unpack(positions, (offset + count - 1) * 3, scratchP0);
  98. var p3 = Cartesian3.unpack(positions, (offset + count - 2) * 3, scratchP1);
  99. next = Cartesian3.subtract(p2, p3, scratchNext);
  100. Cartesian3.add(p2, next, next);
  101. } else {
  102. next = Cartesian3.unpack(positions, (offset + j + 1) * 3, scratchNext);
  103. }
  104. Cartesian3.subtract(previous, center, previous);
  105. Cartesian3.subtract(current, center, current);
  106. Cartesian3.subtract(next, center, next);
  107. var startK = j === 0 ? 2 : 0;
  108. var endK = j === count - 1 ? 2 : 4;
  109. for (var k = startK; k < endK; ++k) {
  110. Cartesian3.pack(current, curPositions, positionIndex);
  111. Cartesian3.pack(previous, prevPositions, positionIndex);
  112. Cartesian3.pack(next, nextPositions, positionIndex);
  113. positionIndex += 3;
  114. var direction = (k - 2 < 0) ? -1.0 : 1.0;
  115. expandAndWidth[expandAndWidthIndex++] = 2 * (k % 2) - 1;
  116. expandAndWidth[expandAndWidthIndex++] = direction * width;
  117. vertexBatchIds[batchIdIndex++] = batchId;
  118. }
  119. }
  120. offset += count;
  121. }
  122. var indices = IndexDatatype.createTypedArray(size, positionsLength * 6 - 6);
  123. var index = 0;
  124. var indicesIndex = 0;
  125. length = positionsLength - 1;
  126. for (i = 0; i < length; ++i) {
  127. indices[indicesIndex++] = index;
  128. indices[indicesIndex++] = index + 2;
  129. indices[indicesIndex++] = index + 1;
  130. indices[indicesIndex++] = index + 1;
  131. indices[indicesIndex++] = index + 2;
  132. indices[indicesIndex++] = index + 3;
  133. index += 4;
  134. }
  135. transferableObjects.push(curPositions.buffer, prevPositions.buffer, nextPositions.buffer);
  136. transferableObjects.push(expandAndWidth.buffer, vertexBatchIds.buffer, indices.buffer);
  137. return {
  138. indexDatatype : (indices.BYTES_PER_ELEMENT === 2) ? IndexDatatype.UNSIGNED_SHORT : IndexDatatype.UNSIGNED_INT,
  139. currentPositions : curPositions.buffer,
  140. previousPositions : prevPositions.buffer,
  141. nextPositions : nextPositions.buffer,
  142. expandAndWidth : expandAndWidth.buffer,
  143. batchIds : vertexBatchIds.buffer,
  144. indices : indices.buffer
  145. };
  146. }
  147. export default createTaskProcessorWorker(createVectorTilePolylines);