createVectorTileGeometries.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. import BoundingSphere from '../Core/BoundingSphere.js';
  2. import BoxGeometry from '../Core/BoxGeometry.js';
  3. import Cartesian3 from '../Core/Cartesian3.js';
  4. import Color from '../Core/Color.js';
  5. import CylinderGeometry from '../Core/CylinderGeometry.js';
  6. import defined from '../Core/defined.js';
  7. import EllipsoidGeometry from '../Core/EllipsoidGeometry.js';
  8. import IndexDatatype from '../Core/IndexDatatype.js';
  9. import Matrix4 from '../Core/Matrix4.js';
  10. import Vector3DTileBatch from '../Scene/Vector3DTileBatch.js';
  11. import createTaskProcessorWorker from './createTaskProcessorWorker.js';
  12. var scratchCartesian = new Cartesian3();
  13. var packedBoxLength = Matrix4.packedLength + Cartesian3.packedLength;
  14. var packedCylinderLength = Matrix4.packedLength + 2;
  15. var packedEllipsoidLength = Matrix4.packedLength + Cartesian3.packedLength;
  16. var packedSphereLength = Cartesian3.packedLength + 1;
  17. var scratchModelMatrixAndBV = {
  18. modelMatrix : new Matrix4(),
  19. boundingVolume : new BoundingSphere()
  20. };
  21. function boxModelMatrixAndBoundingVolume(boxes, index) {
  22. var boxIndex = index * packedBoxLength;
  23. var dimensions = Cartesian3.unpack(boxes, boxIndex, scratchCartesian);
  24. boxIndex += Cartesian3.packedLength;
  25. var boxModelMatrix = Matrix4.unpack(boxes, boxIndex, scratchModelMatrixAndBV.modelMatrix);
  26. Matrix4.multiplyByScale(boxModelMatrix, dimensions, boxModelMatrix);
  27. var boundingVolume = scratchModelMatrixAndBV.boundingVolume;
  28. Cartesian3.clone(Cartesian3.ZERO, boundingVolume.center);
  29. boundingVolume.radius = Math.sqrt(3.0);
  30. return scratchModelMatrixAndBV;
  31. }
  32. function cylinderModelMatrixAndBoundingVolume(cylinders, index) {
  33. var cylinderIndex = index * packedCylinderLength;
  34. var cylinderRadius = cylinders[cylinderIndex++];
  35. var length = cylinders[cylinderIndex++];
  36. var scale = Cartesian3.fromElements(cylinderRadius, cylinderRadius, length, scratchCartesian);
  37. var cylinderModelMatrix = Matrix4.unpack(cylinders, cylinderIndex, scratchModelMatrixAndBV.modelMatrix);
  38. Matrix4.multiplyByScale(cylinderModelMatrix, scale, cylinderModelMatrix);
  39. var boundingVolume = scratchModelMatrixAndBV.boundingVolume;
  40. Cartesian3.clone(Cartesian3.ZERO, boundingVolume.center);
  41. boundingVolume.radius = Math.sqrt(2.0);
  42. return scratchModelMatrixAndBV;
  43. }
  44. function ellipsoidModelMatrixAndBoundingVolume(ellipsoids, index) {
  45. var ellipsoidIndex = index * packedEllipsoidLength;
  46. var radii = Cartesian3.unpack(ellipsoids, ellipsoidIndex, scratchCartesian);
  47. ellipsoidIndex += Cartesian3.packedLength;
  48. var ellipsoidModelMatrix = Matrix4.unpack(ellipsoids, ellipsoidIndex, scratchModelMatrixAndBV.modelMatrix);
  49. Matrix4.multiplyByScale(ellipsoidModelMatrix, radii, ellipsoidModelMatrix);
  50. var boundingVolume = scratchModelMatrixAndBV.boundingVolume;
  51. Cartesian3.clone(Cartesian3.ZERO, boundingVolume.center);
  52. boundingVolume.radius = 1.0;
  53. return scratchModelMatrixAndBV;
  54. }
  55. function sphereModelMatrixAndBoundingVolume(spheres, index) {
  56. var sphereIndex = index * packedSphereLength;
  57. var sphereRadius = spheres[sphereIndex++];
  58. var sphereTranslation = Cartesian3.unpack(spheres, sphereIndex, scratchCartesian);
  59. var sphereModelMatrix = Matrix4.fromTranslation(sphereTranslation, scratchModelMatrixAndBV.modelMatrix);
  60. Matrix4.multiplyByUniformScale(sphereModelMatrix, sphereRadius, sphereModelMatrix);
  61. var boundingVolume = scratchModelMatrixAndBV.boundingVolume;
  62. Cartesian3.clone(Cartesian3.ZERO, boundingVolume.center);
  63. boundingVolume.radius = 1.0;
  64. return scratchModelMatrixAndBV;
  65. }
  66. var scratchPosition = new Cartesian3();
  67. function createPrimitive(options, primitive, primitiveBatchIds, geometry, getModelMatrixAndBoundingVolume) {
  68. if (!defined(primitive)) {
  69. return;
  70. }
  71. var numberOfPrimitives = primitiveBatchIds.length;
  72. var geometryPositions = geometry.attributes.position.values;
  73. var geometryIndices = geometry.indices;
  74. var positions = options.positions;
  75. var vertexBatchIds = options.vertexBatchIds;
  76. var indices = options.indices;
  77. var batchIds = options.batchIds;
  78. var batchTableColors = options.batchTableColors;
  79. var batchedIndices = options.batchedIndices;
  80. var indexOffsets = options.indexOffsets;
  81. var indexCounts = options.indexCounts;
  82. var boundingVolumes = options.boundingVolumes;
  83. var modelMatrix = options.modelMatrix;
  84. var center = options.center;
  85. var positionOffset = options.positionOffset;
  86. var batchIdIndex = options.batchIdIndex;
  87. var indexOffset = options.indexOffset;
  88. var batchedIndicesOffset = options.batchedIndicesOffset;
  89. for (var i = 0; i < numberOfPrimitives; ++i) {
  90. var primitiveModelMatrixAndBV = getModelMatrixAndBoundingVolume(primitive, i);
  91. var primitiveModelMatrix = primitiveModelMatrixAndBV.modelMatrix;
  92. Matrix4.multiply(modelMatrix, primitiveModelMatrix, primitiveModelMatrix);
  93. var batchId = primitiveBatchIds[i];
  94. var positionsLength = geometryPositions.length;
  95. for (var j = 0; j < positionsLength; j += 3) {
  96. var position = Cartesian3.unpack(geometryPositions, j, scratchPosition);
  97. Matrix4.multiplyByPoint(primitiveModelMatrix, position, position);
  98. Cartesian3.subtract(position, center, position);
  99. Cartesian3.pack(position, positions, positionOffset * 3 + j);
  100. vertexBatchIds[batchIdIndex++] = batchId;
  101. }
  102. var indicesLength = geometryIndices.length;
  103. for (var k = 0; k < indicesLength; ++k) {
  104. indices[indexOffset + k] = geometryIndices[k] + positionOffset;
  105. }
  106. var offset = i + batchedIndicesOffset;
  107. batchedIndices[offset] = new Vector3DTileBatch({
  108. offset : indexOffset,
  109. count : indicesLength,
  110. color : Color.fromRgba(batchTableColors[batchId]),
  111. batchIds : [batchId]
  112. });
  113. batchIds[offset] = batchId;
  114. indexOffsets[offset] = indexOffset;
  115. indexCounts[offset] = indicesLength;
  116. boundingVolumes[offset] = BoundingSphere.transform(primitiveModelMatrixAndBV.boundingVolume, primitiveModelMatrix);
  117. positionOffset += positionsLength / 3;
  118. indexOffset += indicesLength;
  119. }
  120. options.positionOffset = positionOffset;
  121. options.batchIdIndex = batchIdIndex;
  122. options.indexOffset = indexOffset;
  123. options.batchedIndicesOffset += numberOfPrimitives;
  124. }
  125. var scratchCenter = new Cartesian3();
  126. var scratchMatrix4 = new Matrix4();
  127. function unpackBuffer(buffer) {
  128. var packedBuffer = new Float64Array(buffer);
  129. var offset = 0;
  130. Cartesian3.unpack(packedBuffer, offset, scratchCenter);
  131. offset += Cartesian3.packedLength;
  132. Matrix4.unpack(packedBuffer, offset, scratchMatrix4);
  133. }
  134. function packedBatchedIndicesLength(batchedIndices) {
  135. var length = batchedIndices.length;
  136. var count = 0;
  137. for (var i = 0; i < length; ++i) {
  138. count += Color.packedLength + 3 + batchedIndices[i].batchIds.length;
  139. }
  140. return count;
  141. }
  142. function packBuffer(indicesBytesPerElement, batchedIndices, boundingVolumes) {
  143. var numBVs = boundingVolumes.length;
  144. var length = 1 + 1 + numBVs * BoundingSphere.packedLength + 1 + packedBatchedIndicesLength(batchedIndices);
  145. var packedBuffer = new Float64Array(length);
  146. var offset = 0;
  147. packedBuffer[offset++] = indicesBytesPerElement;
  148. packedBuffer[offset++] = numBVs;
  149. for (var i = 0; i < numBVs; ++i) {
  150. BoundingSphere.pack(boundingVolumes[i], packedBuffer, offset);
  151. offset += BoundingSphere.packedLength;
  152. }
  153. var indicesLength = batchedIndices.length;
  154. packedBuffer[offset++] = indicesLength;
  155. for (var j = 0; j < indicesLength; ++j) {
  156. var batchedIndex = batchedIndices[j];
  157. Color.pack(batchedIndex.color, packedBuffer, offset);
  158. offset += Color.packedLength;
  159. packedBuffer[offset++] = batchedIndex.offset;
  160. packedBuffer[offset++] = batchedIndex.count;
  161. var batchIds = batchedIndex.batchIds;
  162. var batchIdsLength = batchIds.length;
  163. packedBuffer[offset++] = batchIdsLength;
  164. for (var k = 0; k < batchIdsLength; ++k) {
  165. packedBuffer[offset++] = batchIds[k];
  166. }
  167. }
  168. return packedBuffer;
  169. }
  170. function createVectorTileGeometries(parameters, transferableObjects) {
  171. var boxes = defined(parameters.boxes) ? new Float32Array(parameters.boxes) : undefined;
  172. var boxBatchIds = defined(parameters.boxBatchIds) ? new Uint16Array(parameters.boxBatchIds) : undefined;
  173. var cylinders = defined(parameters.cylinders) ? new Float32Array(parameters.cylinders) : undefined;
  174. var cylinderBatchIds = defined(parameters.cylinderBatchIds) ? new Uint16Array(parameters.cylinderBatchIds) : undefined;
  175. var ellipsoids = defined(parameters.ellipsoids) ? new Float32Array(parameters.ellipsoids) : undefined;
  176. var ellipsoidBatchIds = defined(parameters.ellipsoidBatchIds) ? new Uint16Array(parameters.ellipsoidBatchIds) : undefined;
  177. var spheres = defined(parameters.spheres) ? new Float32Array(parameters.spheres) : undefined;
  178. var sphereBatchIds = defined(parameters.sphereBatchIds) ? new Uint16Array(parameters.sphereBatchIds) : undefined;
  179. var numberOfBoxes = defined(boxes) ? boxBatchIds.length : 0;
  180. var numberOfCylinders = defined(cylinders) ? cylinderBatchIds.length : 0;
  181. var numberOfEllipsoids = defined(ellipsoids) ? ellipsoidBatchIds.length : 0;
  182. var numberOfSpheres = defined(spheres) ? sphereBatchIds.length : 0;
  183. var boxGeometry = BoxGeometry.getUnitBox();
  184. var cylinderGeometry = CylinderGeometry.getUnitCylinder();
  185. var ellipsoidGeometry = EllipsoidGeometry.getUnitEllipsoid();
  186. var boxPositions = boxGeometry.attributes.position.values;
  187. var cylinderPositions = cylinderGeometry.attributes.position.values;
  188. var ellipsoidPositions = ellipsoidGeometry.attributes.position.values;
  189. var numberOfPositions = boxPositions.length * numberOfBoxes;
  190. numberOfPositions += cylinderPositions.length * numberOfCylinders;
  191. numberOfPositions += ellipsoidPositions.length * (numberOfEllipsoids + numberOfSpheres);
  192. var boxIndices = boxGeometry.indices;
  193. var cylinderIndices = cylinderGeometry.indices;
  194. var ellipsoidIndices = ellipsoidGeometry.indices;
  195. var numberOfIndices = boxIndices.length * numberOfBoxes;
  196. numberOfIndices += cylinderIndices.length * numberOfCylinders;
  197. numberOfIndices += ellipsoidIndices.length * (numberOfEllipsoids + numberOfSpheres);
  198. var positions = new Float32Array(numberOfPositions);
  199. var vertexBatchIds = new Uint16Array(numberOfPositions / 3);
  200. var indices = IndexDatatype.createTypedArray(numberOfPositions / 3, numberOfIndices);
  201. var numberOfGeometries = numberOfBoxes + numberOfCylinders + numberOfEllipsoids + numberOfSpheres;
  202. var batchIds = new Uint16Array(numberOfGeometries);
  203. var batchedIndices = new Array(numberOfGeometries);
  204. var indexOffsets = new Uint32Array(numberOfGeometries);
  205. var indexCounts = new Uint32Array(numberOfGeometries);
  206. var boundingVolumes = new Array(numberOfGeometries);
  207. unpackBuffer(parameters.packedBuffer);
  208. var options = {
  209. batchTableColors : new Uint32Array(parameters.batchTableColors),
  210. positions : positions,
  211. vertexBatchIds : vertexBatchIds,
  212. indices : indices,
  213. batchIds : batchIds,
  214. batchedIndices : batchedIndices,
  215. indexOffsets : indexOffsets,
  216. indexCounts : indexCounts,
  217. boundingVolumes : boundingVolumes,
  218. positionOffset : 0,
  219. batchIdIndex : 0,
  220. indexOffset : 0,
  221. batchedIndicesOffset : 0,
  222. modelMatrix : scratchMatrix4,
  223. center : scratchCenter
  224. };
  225. createPrimitive(options, boxes, boxBatchIds, boxGeometry, boxModelMatrixAndBoundingVolume);
  226. createPrimitive(options, cylinders, cylinderBatchIds, cylinderGeometry, cylinderModelMatrixAndBoundingVolume);
  227. createPrimitive(options, ellipsoids, ellipsoidBatchIds, ellipsoidGeometry, ellipsoidModelMatrixAndBoundingVolume);
  228. createPrimitive(options, spheres, sphereBatchIds, ellipsoidGeometry, sphereModelMatrixAndBoundingVolume);
  229. var packedBuffer = packBuffer(indices.BYTES_PER_ELEMENT, batchedIndices, boundingVolumes);
  230. transferableObjects.push(positions.buffer, vertexBatchIds.buffer, indices.buffer);
  231. transferableObjects.push(batchIds.buffer, indexOffsets.buffer, indexCounts.buffer);
  232. transferableObjects.push(packedBuffer.buffer);
  233. return {
  234. positions : positions.buffer,
  235. vertexBatchIds : vertexBatchIds.buffer,
  236. indices : indices.buffer,
  237. indexOffsets : indexOffsets.buffer,
  238. indexCounts : indexCounts.buffer,
  239. batchIds : batchIds.buffer,
  240. packedBuffer : packedBuffer.buffer
  241. };
  242. }
  243. export default createTaskProcessorWorker(createVectorTileGeometries);