createVerticesFromQuantizedTerrainMesh.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*global define*/
  2. define([
  3. '../Core/AttributeCompression',
  4. '../Core/Cartesian2',
  5. '../Core/Cartesian3',
  6. '../Core/Cartographic',
  7. '../Core/defined',
  8. '../Core/Ellipsoid',
  9. '../Core/IndexDatatype',
  10. '../Core/Math',
  11. './createTaskProcessorWorker'
  12. ], function(
  13. AttributeCompression,
  14. Cartesian2,
  15. Cartesian3,
  16. Cartographic,
  17. defined,
  18. Ellipsoid,
  19. IndexDatatype,
  20. CesiumMath,
  21. createTaskProcessorWorker) {
  22. "use strict";
  23. var maxShort = 32767;
  24. var xIndex = 0;
  25. var yIndex = 1;
  26. var zIndex = 2;
  27. var hIndex = 3;
  28. var uIndex = 4;
  29. var vIndex = 5;
  30. var nIndex = 6;
  31. var cartesian3Scratch = new Cartesian3();
  32. var cartographicScratch = new Cartographic();
  33. var toPack = new Cartesian2();
  34. function createVerticesFromQuantizedTerrainMesh(parameters, transferableObjects) {
  35. var quantizedVertices = parameters.quantizedVertices;
  36. var quantizedVertexCount = quantizedVertices.length / 3;
  37. var octEncodedNormals = parameters.octEncodedNormals;
  38. var edgeVertexCount = parameters.westIndices.length + parameters.eastIndices.length +
  39. parameters.southIndices.length + parameters.northIndices.length;
  40. var minimumHeight = parameters.minimumHeight;
  41. var maximumHeight = parameters.maximumHeight;
  42. var center = parameters.relativeToCenter;
  43. var rectangle = parameters.rectangle;
  44. var west = rectangle.west;
  45. var south = rectangle.south;
  46. var east = rectangle.east;
  47. var north = rectangle.north;
  48. var ellipsoid = Ellipsoid.clone(parameters.ellipsoid);
  49. var uBuffer = quantizedVertices.subarray(0, quantizedVertexCount);
  50. var vBuffer = quantizedVertices.subarray(quantizedVertexCount, 2 * quantizedVertexCount);
  51. var heightBuffer = quantizedVertices.subarray(quantizedVertexCount * 2, 3 * quantizedVertexCount);
  52. var hasVertexNormals = defined(octEncodedNormals);
  53. var vertexStride = 6;
  54. if (hasVertexNormals) {
  55. vertexStride += 1;
  56. }
  57. var vertexBuffer = new Float32Array(quantizedVertexCount * vertexStride + edgeVertexCount * vertexStride);
  58. for (var i = 0, bufferIndex = 0, n = 0; i < quantizedVertexCount; ++i, bufferIndex += vertexStride, n += 2) {
  59. var u = uBuffer[i] / maxShort;
  60. var v = vBuffer[i] / maxShort;
  61. var height = CesiumMath.lerp(minimumHeight, maximumHeight, heightBuffer[i] / maxShort);
  62. cartographicScratch.longitude = CesiumMath.lerp(west, east, u);
  63. cartographicScratch.latitude = CesiumMath.lerp(south, north, v);
  64. cartographicScratch.height = height;
  65. ellipsoid.cartographicToCartesian(cartographicScratch, cartesian3Scratch);
  66. vertexBuffer[bufferIndex + xIndex] = cartesian3Scratch.x - center.x;
  67. vertexBuffer[bufferIndex + yIndex] = cartesian3Scratch.y - center.y;
  68. vertexBuffer[bufferIndex + zIndex] = cartesian3Scratch.z - center.z;
  69. vertexBuffer[bufferIndex + hIndex] = height;
  70. vertexBuffer[bufferIndex + uIndex] = u;
  71. vertexBuffer[bufferIndex + vIndex] = v;
  72. if (hasVertexNormals) {
  73. toPack.x = octEncodedNormals[n];
  74. toPack.y = octEncodedNormals[n + 1];
  75. vertexBuffer[bufferIndex + nIndex] = AttributeCompression.octPackFloat(toPack);
  76. }
  77. }
  78. var edgeTriangleCount = Math.max(0, (edgeVertexCount - 4) * 2);
  79. var indexBufferLength = parameters.indices.length + edgeTriangleCount * 3;
  80. var indexBuffer = IndexDatatype.createTypedArray(quantizedVertexCount + edgeVertexCount, indexBufferLength);
  81. indexBuffer.set(parameters.indices, 0);
  82. // Add skirts.
  83. var vertexBufferIndex = quantizedVertexCount * vertexStride;
  84. var indexBufferIndex = parameters.indices.length;
  85. indexBufferIndex = addSkirt(vertexBuffer, vertexBufferIndex, indexBuffer, indexBufferIndex, parameters.westIndices, center, ellipsoid, rectangle, parameters.westSkirtHeight, true, hasVertexNormals);
  86. vertexBufferIndex += parameters.westIndices.length * vertexStride;
  87. indexBufferIndex = addSkirt(vertexBuffer, vertexBufferIndex, indexBuffer, indexBufferIndex, parameters.southIndices, center, ellipsoid, rectangle, parameters.southSkirtHeight, false, hasVertexNormals);
  88. vertexBufferIndex += parameters.southIndices.length * vertexStride;
  89. indexBufferIndex = addSkirt(vertexBuffer, vertexBufferIndex, indexBuffer, indexBufferIndex, parameters.eastIndices, center, ellipsoid, rectangle, parameters.eastSkirtHeight, false, hasVertexNormals);
  90. vertexBufferIndex += parameters.eastIndices.length * vertexStride;
  91. indexBufferIndex = addSkirt(vertexBuffer, vertexBufferIndex, indexBuffer, indexBufferIndex, parameters.northIndices, center, ellipsoid, rectangle, parameters.northSkirtHeight, true, hasVertexNormals);
  92. vertexBufferIndex += parameters.northIndices.length * vertexStride;
  93. transferableObjects.push(vertexBuffer.buffer, indexBuffer.buffer);
  94. return {
  95. vertices : vertexBuffer.buffer,
  96. indices : indexBuffer.buffer
  97. };
  98. }
  99. function addSkirt(vertexBuffer, vertexBufferIndex, indexBuffer, indexBufferIndex, edgeVertices, center, ellipsoid, rectangle, skirtLength, isWestOrNorthEdge, hasVertexNormals) {
  100. var start, end, increment;
  101. var vertexStride = 6;
  102. if (hasVertexNormals) {
  103. vertexStride += 1;
  104. }
  105. if (isWestOrNorthEdge) {
  106. start = edgeVertices.length - 1;
  107. end = -1;
  108. increment = -1;
  109. } else {
  110. start = 0;
  111. end = edgeVertices.length;
  112. increment = 1;
  113. }
  114. var previousIndex = -1;
  115. var vertexIndex = vertexBufferIndex / vertexStride;
  116. var north = rectangle.north;
  117. var south = rectangle.south;
  118. var east = rectangle.east;
  119. var west = rectangle.west;
  120. if (east < west) {
  121. east += CesiumMath.TWO_PI;
  122. }
  123. for (var i = start; i !== end; i += increment) {
  124. var index = edgeVertices[i];
  125. var offset = index * vertexStride;
  126. var u = vertexBuffer[offset + uIndex];
  127. var v = vertexBuffer[offset + vIndex];
  128. var h = vertexBuffer[offset + hIndex];
  129. cartographicScratch.longitude = CesiumMath.lerp(west, east, u);
  130. cartographicScratch.latitude = CesiumMath.lerp(south, north, v);
  131. cartographicScratch.height = h - skirtLength;
  132. var position = ellipsoid.cartographicToCartesian(cartographicScratch, cartesian3Scratch);
  133. Cartesian3.subtract(position, center, position);
  134. vertexBuffer[vertexBufferIndex++] = position.x;
  135. vertexBuffer[vertexBufferIndex++] = position.y;
  136. vertexBuffer[vertexBufferIndex++] = position.z;
  137. vertexBuffer[vertexBufferIndex++] = cartographicScratch.height;
  138. vertexBuffer[vertexBufferIndex++] = u;
  139. vertexBuffer[vertexBufferIndex++] = v;
  140. if (hasVertexNormals) {
  141. vertexBuffer[vertexBufferIndex++] = vertexBuffer[offset + nIndex];
  142. }
  143. if (previousIndex !== -1) {
  144. indexBuffer[indexBufferIndex++] = previousIndex;
  145. indexBuffer[indexBufferIndex++] = vertexIndex - 1;
  146. indexBuffer[indexBufferIndex++] = index;
  147. indexBuffer[indexBufferIndex++] = vertexIndex - 1;
  148. indexBuffer[indexBufferIndex++] = vertexIndex;
  149. indexBuffer[indexBufferIndex++] = index;
  150. }
  151. previousIndex = index;
  152. ++vertexIndex;
  153. }
  154. return indexBufferIndex;
  155. }
  156. return createTaskProcessorWorker(createVerticesFromQuantizedTerrainMesh);
  157. });