createVectorTileGeometries.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. define(['./Transforms-bc45e707', './BoxGeometry-7eb1af60', './Matrix3-41c58dde', './Color-2dc49658', './CylinderGeometry-23c67a6c', './defaultValue-fe22d8c0', './EllipsoidGeometry-508da15c', './IndexDatatype-2643aa47', './Matrix2-e1298525', './createTaskProcessorWorker', './Check-6ede7e26', './Math-0a2ac845', './combine-d9581036', './RuntimeError-ef395448', './ComponentDatatype-cf1fa08e', './WebGLConstants-0b1ce7ba', './GeometryAttribute-a466e9c7', './GeometryAttributes-ad136444', './GeometryOffsetAttribute-9ad0019c', './VertexFormat-030f11ff', './CylinderGeometryLibrary-7bf291b4'], (function (Transforms, BoxGeometry, Matrix3, Color, CylinderGeometry, defaultValue, EllipsoidGeometry, IndexDatatype, Matrix2, createTaskProcessorWorker, Check, Math$1, combine, RuntimeError, ComponentDatatype, WebGLConstants, GeometryAttribute, GeometryAttributes, GeometryOffsetAttribute, VertexFormat, CylinderGeometryLibrary) { 'use strict';
  2. /**
  3. * Describes a renderable batch of geometry.
  4. *
  5. * @alias Vector3DTileBatch
  6. * @constructor
  7. *
  8. * @param {object} options An object with the following properties:
  9. * @param {number} options.offset The offset of the batch into the indices buffer.
  10. * @param {number} options.count The number of indices in the batch.
  11. * @param {Color} options.color The color of the geometry in the batch.
  12. * @param {number[]} options.batchIds An array where each element is the batch id of the geometry in the batch.
  13. *
  14. * @private
  15. */
  16. function Vector3DTileBatch(options) {
  17. /**
  18. * The offset of the batch into the indices buffer.
  19. * @type {number}
  20. */
  21. this.offset = options.offset;
  22. /**
  23. * The number of indices in the batch.
  24. * @type {number}
  25. */
  26. this.count = options.count;
  27. /**
  28. * The color of the geometry in the batch.
  29. * @type {Color}
  30. */
  31. this.color = options.color;
  32. /**
  33. * An array where each element is the batch id of the geometry in the batch.
  34. * @type {number[]}
  35. */
  36. this.batchIds = options.batchIds;
  37. }
  38. const scratchCartesian = new Matrix3.Cartesian3();
  39. const packedBoxLength = Matrix2.Matrix4.packedLength + Matrix3.Cartesian3.packedLength;
  40. const packedCylinderLength = Matrix2.Matrix4.packedLength + 2;
  41. const packedEllipsoidLength = Matrix2.Matrix4.packedLength + Matrix3.Cartesian3.packedLength;
  42. const packedSphereLength = Matrix3.Cartesian3.packedLength + 1;
  43. const scratchModelMatrixAndBV = {
  44. modelMatrix: new Matrix2.Matrix4(),
  45. boundingVolume: new Transforms.BoundingSphere(),
  46. };
  47. function boxModelMatrixAndBoundingVolume(boxes, index) {
  48. let boxIndex = index * packedBoxLength;
  49. const dimensions = Matrix3.Cartesian3.unpack(boxes, boxIndex, scratchCartesian);
  50. boxIndex += Matrix3.Cartesian3.packedLength;
  51. const boxModelMatrix = Matrix2.Matrix4.unpack(
  52. boxes,
  53. boxIndex,
  54. scratchModelMatrixAndBV.modelMatrix
  55. );
  56. Matrix2.Matrix4.multiplyByScale(boxModelMatrix, dimensions, boxModelMatrix);
  57. const boundingVolume = scratchModelMatrixAndBV.boundingVolume;
  58. Matrix3.Cartesian3.clone(Matrix3.Cartesian3.ZERO, boundingVolume.center);
  59. boundingVolume.radius = Math.sqrt(3.0);
  60. return scratchModelMatrixAndBV;
  61. }
  62. function cylinderModelMatrixAndBoundingVolume(cylinders, index) {
  63. let cylinderIndex = index * packedCylinderLength;
  64. const cylinderRadius = cylinders[cylinderIndex++];
  65. const length = cylinders[cylinderIndex++];
  66. const scale = Matrix3.Cartesian3.fromElements(
  67. cylinderRadius,
  68. cylinderRadius,
  69. length,
  70. scratchCartesian
  71. );
  72. const cylinderModelMatrix = Matrix2.Matrix4.unpack(
  73. cylinders,
  74. cylinderIndex,
  75. scratchModelMatrixAndBV.modelMatrix
  76. );
  77. Matrix2.Matrix4.multiplyByScale(cylinderModelMatrix, scale, cylinderModelMatrix);
  78. const boundingVolume = scratchModelMatrixAndBV.boundingVolume;
  79. Matrix3.Cartesian3.clone(Matrix3.Cartesian3.ZERO, boundingVolume.center);
  80. boundingVolume.radius = Math.sqrt(2.0);
  81. return scratchModelMatrixAndBV;
  82. }
  83. function ellipsoidModelMatrixAndBoundingVolume(ellipsoids, index) {
  84. let ellipsoidIndex = index * packedEllipsoidLength;
  85. const radii = Matrix3.Cartesian3.unpack(ellipsoids, ellipsoidIndex, scratchCartesian);
  86. ellipsoidIndex += Matrix3.Cartesian3.packedLength;
  87. const ellipsoidModelMatrix = Matrix2.Matrix4.unpack(
  88. ellipsoids,
  89. ellipsoidIndex,
  90. scratchModelMatrixAndBV.modelMatrix
  91. );
  92. Matrix2.Matrix4.multiplyByScale(ellipsoidModelMatrix, radii, ellipsoidModelMatrix);
  93. const boundingVolume = scratchModelMatrixAndBV.boundingVolume;
  94. Matrix3.Cartesian3.clone(Matrix3.Cartesian3.ZERO, boundingVolume.center);
  95. boundingVolume.radius = 1.0;
  96. return scratchModelMatrixAndBV;
  97. }
  98. function sphereModelMatrixAndBoundingVolume(spheres, index) {
  99. let sphereIndex = index * packedSphereLength;
  100. const sphereRadius = spheres[sphereIndex++];
  101. const sphereTranslation = Matrix3.Cartesian3.unpack(
  102. spheres,
  103. sphereIndex,
  104. scratchCartesian
  105. );
  106. const sphereModelMatrix = Matrix2.Matrix4.fromTranslation(
  107. sphereTranslation,
  108. scratchModelMatrixAndBV.modelMatrix
  109. );
  110. Matrix2.Matrix4.multiplyByUniformScale(
  111. sphereModelMatrix,
  112. sphereRadius,
  113. sphereModelMatrix
  114. );
  115. const boundingVolume = scratchModelMatrixAndBV.boundingVolume;
  116. Matrix3.Cartesian3.clone(Matrix3.Cartesian3.ZERO, boundingVolume.center);
  117. boundingVolume.radius = 1.0;
  118. return scratchModelMatrixAndBV;
  119. }
  120. const scratchPosition = new Matrix3.Cartesian3();
  121. function createPrimitive(
  122. options,
  123. primitive,
  124. primitiveBatchIds,
  125. geometry,
  126. getModelMatrixAndBoundingVolume
  127. ) {
  128. if (!defaultValue.defined(primitive)) {
  129. return;
  130. }
  131. const numberOfPrimitives = primitiveBatchIds.length;
  132. const geometryPositions = geometry.attributes.position.values;
  133. const geometryIndices = geometry.indices;
  134. const positions = options.positions;
  135. const vertexBatchIds = options.vertexBatchIds;
  136. const indices = options.indices;
  137. const batchIds = options.batchIds;
  138. const batchTableColors = options.batchTableColors;
  139. const batchedIndices = options.batchedIndices;
  140. const indexOffsets = options.indexOffsets;
  141. const indexCounts = options.indexCounts;
  142. const boundingVolumes = options.boundingVolumes;
  143. const modelMatrix = options.modelMatrix;
  144. const center = options.center;
  145. let positionOffset = options.positionOffset;
  146. let batchIdIndex = options.batchIdIndex;
  147. let indexOffset = options.indexOffset;
  148. const batchedIndicesOffset = options.batchedIndicesOffset;
  149. for (let i = 0; i < numberOfPrimitives; ++i) {
  150. const primitiveModelMatrixAndBV = getModelMatrixAndBoundingVolume(
  151. primitive,
  152. i
  153. );
  154. const primitiveModelMatrix = primitiveModelMatrixAndBV.modelMatrix;
  155. Matrix2.Matrix4.multiply(modelMatrix, primitiveModelMatrix, primitiveModelMatrix);
  156. const batchId = primitiveBatchIds[i];
  157. const positionsLength = geometryPositions.length;
  158. for (let j = 0; j < positionsLength; j += 3) {
  159. const position = Matrix3.Cartesian3.unpack(geometryPositions, j, scratchPosition);
  160. Matrix2.Matrix4.multiplyByPoint(primitiveModelMatrix, position, position);
  161. Matrix3.Cartesian3.subtract(position, center, position);
  162. Matrix3.Cartesian3.pack(position, positions, positionOffset * 3 + j);
  163. vertexBatchIds[batchIdIndex++] = batchId;
  164. }
  165. const indicesLength = geometryIndices.length;
  166. for (let k = 0; k < indicesLength; ++k) {
  167. indices[indexOffset + k] = geometryIndices[k] + positionOffset;
  168. }
  169. const offset = i + batchedIndicesOffset;
  170. batchedIndices[offset] = new Vector3DTileBatch({
  171. offset: indexOffset,
  172. count: indicesLength,
  173. color: Color.Color.fromRgba(batchTableColors[batchId]),
  174. batchIds: [batchId],
  175. });
  176. batchIds[offset] = batchId;
  177. indexOffsets[offset] = indexOffset;
  178. indexCounts[offset] = indicesLength;
  179. boundingVolumes[offset] = Transforms.BoundingSphere.transform(
  180. primitiveModelMatrixAndBV.boundingVolume,
  181. primitiveModelMatrix
  182. );
  183. positionOffset += positionsLength / 3;
  184. indexOffset += indicesLength;
  185. }
  186. options.positionOffset = positionOffset;
  187. options.batchIdIndex = batchIdIndex;
  188. options.indexOffset = indexOffset;
  189. options.batchedIndicesOffset += numberOfPrimitives;
  190. }
  191. const scratchCenter = new Matrix3.Cartesian3();
  192. const scratchMatrix4 = new Matrix2.Matrix4();
  193. function unpackBuffer(buffer) {
  194. const packedBuffer = new Float64Array(buffer);
  195. let offset = 0;
  196. Matrix3.Cartesian3.unpack(packedBuffer, offset, scratchCenter);
  197. offset += Matrix3.Cartesian3.packedLength;
  198. Matrix2.Matrix4.unpack(packedBuffer, offset, scratchMatrix4);
  199. }
  200. function packedBatchedIndicesLength(batchedIndices) {
  201. const length = batchedIndices.length;
  202. let count = 0;
  203. for (let i = 0; i < length; ++i) {
  204. count += Color.Color.packedLength + 3 + batchedIndices[i].batchIds.length;
  205. }
  206. return count;
  207. }
  208. function packBuffer(indicesBytesPerElement, batchedIndices, boundingVolumes) {
  209. const numBVs = boundingVolumes.length;
  210. const length =
  211. 1 +
  212. 1 +
  213. numBVs * Transforms.BoundingSphere.packedLength +
  214. 1 +
  215. packedBatchedIndicesLength(batchedIndices);
  216. const packedBuffer = new Float64Array(length);
  217. let offset = 0;
  218. packedBuffer[offset++] = indicesBytesPerElement;
  219. packedBuffer[offset++] = numBVs;
  220. for (let i = 0; i < numBVs; ++i) {
  221. Transforms.BoundingSphere.pack(boundingVolumes[i], packedBuffer, offset);
  222. offset += Transforms.BoundingSphere.packedLength;
  223. }
  224. const indicesLength = batchedIndices.length;
  225. packedBuffer[offset++] = indicesLength;
  226. for (let j = 0; j < indicesLength; ++j) {
  227. const batchedIndex = batchedIndices[j];
  228. Color.Color.pack(batchedIndex.color, packedBuffer, offset);
  229. offset += Color.Color.packedLength;
  230. packedBuffer[offset++] = batchedIndex.offset;
  231. packedBuffer[offset++] = batchedIndex.count;
  232. const batchIds = batchedIndex.batchIds;
  233. const batchIdsLength = batchIds.length;
  234. packedBuffer[offset++] = batchIdsLength;
  235. for (let k = 0; k < batchIdsLength; ++k) {
  236. packedBuffer[offset++] = batchIds[k];
  237. }
  238. }
  239. return packedBuffer;
  240. }
  241. function createVectorTileGeometries(parameters, transferableObjects) {
  242. const boxes = defaultValue.defined(parameters.boxes)
  243. ? new Float32Array(parameters.boxes)
  244. : undefined;
  245. const boxBatchIds = defaultValue.defined(parameters.boxBatchIds)
  246. ? new Uint16Array(parameters.boxBatchIds)
  247. : undefined;
  248. const cylinders = defaultValue.defined(parameters.cylinders)
  249. ? new Float32Array(parameters.cylinders)
  250. : undefined;
  251. const cylinderBatchIds = defaultValue.defined(parameters.cylinderBatchIds)
  252. ? new Uint16Array(parameters.cylinderBatchIds)
  253. : undefined;
  254. const ellipsoids = defaultValue.defined(parameters.ellipsoids)
  255. ? new Float32Array(parameters.ellipsoids)
  256. : undefined;
  257. const ellipsoidBatchIds = defaultValue.defined(parameters.ellipsoidBatchIds)
  258. ? new Uint16Array(parameters.ellipsoidBatchIds)
  259. : undefined;
  260. const spheres = defaultValue.defined(parameters.spheres)
  261. ? new Float32Array(parameters.spheres)
  262. : undefined;
  263. const sphereBatchIds = defaultValue.defined(parameters.sphereBatchIds)
  264. ? new Uint16Array(parameters.sphereBatchIds)
  265. : undefined;
  266. const numberOfBoxes = defaultValue.defined(boxes) ? boxBatchIds.length : 0;
  267. const numberOfCylinders = defaultValue.defined(cylinders) ? cylinderBatchIds.length : 0;
  268. const numberOfEllipsoids = defaultValue.defined(ellipsoids) ? ellipsoidBatchIds.length : 0;
  269. const numberOfSpheres = defaultValue.defined(spheres) ? sphereBatchIds.length : 0;
  270. const boxGeometry = BoxGeometry.BoxGeometry.getUnitBox();
  271. const cylinderGeometry = CylinderGeometry.CylinderGeometry.getUnitCylinder();
  272. const ellipsoidGeometry = EllipsoidGeometry.EllipsoidGeometry.getUnitEllipsoid();
  273. const boxPositions = boxGeometry.attributes.position.values;
  274. const cylinderPositions = cylinderGeometry.attributes.position.values;
  275. const ellipsoidPositions = ellipsoidGeometry.attributes.position.values;
  276. let numberOfPositions = boxPositions.length * numberOfBoxes;
  277. numberOfPositions += cylinderPositions.length * numberOfCylinders;
  278. numberOfPositions +=
  279. ellipsoidPositions.length * (numberOfEllipsoids + numberOfSpheres);
  280. const boxIndices = boxGeometry.indices;
  281. const cylinderIndices = cylinderGeometry.indices;
  282. const ellipsoidIndices = ellipsoidGeometry.indices;
  283. let numberOfIndices = boxIndices.length * numberOfBoxes;
  284. numberOfIndices += cylinderIndices.length * numberOfCylinders;
  285. numberOfIndices +=
  286. ellipsoidIndices.length * (numberOfEllipsoids + numberOfSpheres);
  287. const positions = new Float32Array(numberOfPositions);
  288. const vertexBatchIds = new Uint16Array(numberOfPositions / 3);
  289. const indices = IndexDatatype.IndexDatatype.createTypedArray(
  290. numberOfPositions / 3,
  291. numberOfIndices
  292. );
  293. const numberOfGeometries =
  294. numberOfBoxes + numberOfCylinders + numberOfEllipsoids + numberOfSpheres;
  295. const batchIds = new Uint16Array(numberOfGeometries);
  296. const batchedIndices = new Array(numberOfGeometries);
  297. const indexOffsets = new Uint32Array(numberOfGeometries);
  298. const indexCounts = new Uint32Array(numberOfGeometries);
  299. const boundingVolumes = new Array(numberOfGeometries);
  300. unpackBuffer(parameters.packedBuffer);
  301. const options = {
  302. batchTableColors: new Uint32Array(parameters.batchTableColors),
  303. positions: positions,
  304. vertexBatchIds: vertexBatchIds,
  305. indices: indices,
  306. batchIds: batchIds,
  307. batchedIndices: batchedIndices,
  308. indexOffsets: indexOffsets,
  309. indexCounts: indexCounts,
  310. boundingVolumes: boundingVolumes,
  311. positionOffset: 0,
  312. batchIdIndex: 0,
  313. indexOffset: 0,
  314. batchedIndicesOffset: 0,
  315. modelMatrix: scratchMatrix4,
  316. center: scratchCenter,
  317. };
  318. createPrimitive(
  319. options,
  320. boxes,
  321. boxBatchIds,
  322. boxGeometry,
  323. boxModelMatrixAndBoundingVolume
  324. );
  325. createPrimitive(
  326. options,
  327. cylinders,
  328. cylinderBatchIds,
  329. cylinderGeometry,
  330. cylinderModelMatrixAndBoundingVolume
  331. );
  332. createPrimitive(
  333. options,
  334. ellipsoids,
  335. ellipsoidBatchIds,
  336. ellipsoidGeometry,
  337. ellipsoidModelMatrixAndBoundingVolume
  338. );
  339. createPrimitive(
  340. options,
  341. spheres,
  342. sphereBatchIds,
  343. ellipsoidGeometry,
  344. sphereModelMatrixAndBoundingVolume
  345. );
  346. const packedBuffer = packBuffer(
  347. indices.BYTES_PER_ELEMENT,
  348. batchedIndices,
  349. boundingVolumes
  350. );
  351. transferableObjects.push(
  352. positions.buffer,
  353. vertexBatchIds.buffer,
  354. indices.buffer
  355. );
  356. transferableObjects.push(
  357. batchIds.buffer,
  358. indexOffsets.buffer,
  359. indexCounts.buffer
  360. );
  361. transferableObjects.push(packedBuffer.buffer);
  362. return {
  363. positions: positions.buffer,
  364. vertexBatchIds: vertexBatchIds.buffer,
  365. indices: indices.buffer,
  366. indexOffsets: indexOffsets.buffer,
  367. indexCounts: indexCounts.buffer,
  368. batchIds: batchIds.buffer,
  369. packedBuffer: packedBuffer.buffer,
  370. };
  371. }
  372. var createVectorTileGeometries$1 = createTaskProcessorWorker(createVectorTileGeometries);
  373. return createVectorTileGeometries$1;
  374. }));