createVectorTileGeometries.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. /**
  2. * Cesium - https://github.com/AnalyticalGraphicsInc/cesium
  3. *
  4. * Copyright 2011-2017 Cesium Contributors
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * Columbus View (Pat. Pend.)
  19. *
  20. * Portions licensed separately.
  21. * See https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md for full licensing details.
  22. */
  23. define(['./when-8d13db60', './Check-70bec281', './Math-61ede240', './Cartographic-fe4be337', './Cartesian2-85064f09', './BoundingSphere-775c5788', './Cartesian4-5af5bb24', './RuntimeError-ba10bc3e', './WebGLConstants-4c11ee5f', './ComponentDatatype-5862616f', './GeometryAttribute-91704ebb', './PrimitiveType-97893bc7', './FeatureDetection-7bd32c34', './Transforms-b2e71640', './buildModuleUrl-14bfe498', './GeometryAttributes-aacecde6', './IndexDatatype-9435b55f', './createTaskProcessorWorker', './GeometryOffsetAttribute-ca302482', './VertexFormat-fe4db402', './BoxGeometry-a9de8775', './CylinderGeometryLibrary-8c0fda9f', './CylinderGeometry-6fabfda1', './EllipsoidGeometry-8093d9f2', './Color-69f1845f'], function (when, Check, _Math, Cartographic, Cartesian2, BoundingSphere, Cartesian4, RuntimeError, WebGLConstants, ComponentDatatype, GeometryAttribute, PrimitiveType, FeatureDetection, Transforms, buildModuleUrl, GeometryAttributes, IndexDatatype, createTaskProcessorWorker, GeometryOffsetAttribute, VertexFormat, BoxGeometry, CylinderGeometryLibrary, CylinderGeometry, EllipsoidGeometry, Color) { 'use strict';
  24. /**
  25. * Describes a renderable batch of geometry.
  26. *
  27. * @alias Vector3DTileBatch
  28. * @constructor
  29. *
  30. * @param {Object} options An object with the following properties:
  31. * @param {Number} options.offset The offset of the batch into the indices buffer.
  32. * @param {Number} options.count The number of indices in the batch.
  33. * @param {Color} options.color The color of the geometry in the batch.
  34. * @param {Number[]} options.batchIds An array where each element is the batch id of the geometry in the batch.
  35. *
  36. * @private
  37. */
  38. function Vector3DTileBatch(options) {
  39. /**
  40. * The offset of the batch into the indices buffer.
  41. * @type {Number}
  42. */
  43. this.offset = options.offset;
  44. /**
  45. * The number of indices in the batch.
  46. * @type {Number}
  47. */
  48. this.count = options.count;
  49. /**
  50. * The color of the geometry in the batch.
  51. * @type {Color}
  52. */
  53. this.color = options.color;
  54. /**
  55. * An array where each element is the batch id of the geometry in the batch.
  56. * @type {Number[]}
  57. */
  58. this.batchIds = options.batchIds;
  59. }
  60. var scratchCartesian = new Cartographic.Cartesian3();
  61. var packedBoxLength = BoundingSphere.Matrix4.packedLength + Cartographic.Cartesian3.packedLength;
  62. var packedCylinderLength = BoundingSphere.Matrix4.packedLength + 2;
  63. var packedEllipsoidLength = BoundingSphere.Matrix4.packedLength + Cartographic.Cartesian3.packedLength;
  64. var packedSphereLength = Cartographic.Cartesian3.packedLength + 1;
  65. var scratchModelMatrixAndBV = {
  66. modelMatrix : new BoundingSphere.Matrix4(),
  67. boundingVolume : new BoundingSphere.BoundingSphere()
  68. };
  69. function boxModelMatrixAndBoundingVolume(boxes, index) {
  70. var boxIndex = index * packedBoxLength;
  71. var dimensions = Cartographic.Cartesian3.unpack(boxes, boxIndex, scratchCartesian);
  72. boxIndex += Cartographic.Cartesian3.packedLength;
  73. var boxModelMatrix = BoundingSphere.Matrix4.unpack(boxes, boxIndex, scratchModelMatrixAndBV.modelMatrix);
  74. BoundingSphere.Matrix4.multiplyByScale(boxModelMatrix, dimensions, boxModelMatrix);
  75. var boundingVolume = scratchModelMatrixAndBV.boundingVolume;
  76. Cartographic.Cartesian3.clone(Cartographic.Cartesian3.ZERO, boundingVolume.center);
  77. boundingVolume.radius = Math.sqrt(3.0);
  78. return scratchModelMatrixAndBV;
  79. }
  80. function cylinderModelMatrixAndBoundingVolume(cylinders, index) {
  81. var cylinderIndex = index * packedCylinderLength;
  82. var cylinderRadius = cylinders[cylinderIndex++];
  83. var length = cylinders[cylinderIndex++];
  84. var scale = Cartographic.Cartesian3.fromElements(cylinderRadius, cylinderRadius, length, scratchCartesian);
  85. var cylinderModelMatrix = BoundingSphere.Matrix4.unpack(cylinders, cylinderIndex, scratchModelMatrixAndBV.modelMatrix);
  86. BoundingSphere.Matrix4.multiplyByScale(cylinderModelMatrix, scale, cylinderModelMatrix);
  87. var boundingVolume = scratchModelMatrixAndBV.boundingVolume;
  88. Cartographic.Cartesian3.clone(Cartographic.Cartesian3.ZERO, boundingVolume.center);
  89. boundingVolume.radius = Math.sqrt(2.0);
  90. return scratchModelMatrixAndBV;
  91. }
  92. function ellipsoidModelMatrixAndBoundingVolume(ellipsoids, index) {
  93. var ellipsoidIndex = index * packedEllipsoidLength;
  94. var radii = Cartographic.Cartesian3.unpack(ellipsoids, ellipsoidIndex, scratchCartesian);
  95. ellipsoidIndex += Cartographic.Cartesian3.packedLength;
  96. var ellipsoidModelMatrix = BoundingSphere.Matrix4.unpack(ellipsoids, ellipsoidIndex, scratchModelMatrixAndBV.modelMatrix);
  97. BoundingSphere.Matrix4.multiplyByScale(ellipsoidModelMatrix, radii, ellipsoidModelMatrix);
  98. var boundingVolume = scratchModelMatrixAndBV.boundingVolume;
  99. Cartographic.Cartesian3.clone(Cartographic.Cartesian3.ZERO, boundingVolume.center);
  100. boundingVolume.radius = 1.0;
  101. return scratchModelMatrixAndBV;
  102. }
  103. function sphereModelMatrixAndBoundingVolume(spheres, index) {
  104. var sphereIndex = index * packedSphereLength;
  105. var sphereRadius = spheres[sphereIndex++];
  106. var sphereTranslation = Cartographic.Cartesian3.unpack(spheres, sphereIndex, scratchCartesian);
  107. var sphereModelMatrix = BoundingSphere.Matrix4.fromTranslation(sphereTranslation, scratchModelMatrixAndBV.modelMatrix);
  108. BoundingSphere.Matrix4.multiplyByUniformScale(sphereModelMatrix, sphereRadius, sphereModelMatrix);
  109. var boundingVolume = scratchModelMatrixAndBV.boundingVolume;
  110. Cartographic.Cartesian3.clone(Cartographic.Cartesian3.ZERO, boundingVolume.center);
  111. boundingVolume.radius = 1.0;
  112. return scratchModelMatrixAndBV;
  113. }
  114. var scratchPosition = new Cartographic.Cartesian3();
  115. function createPrimitive(options, primitive, primitiveBatchIds, geometry, getModelMatrixAndBoundingVolume) {
  116. if (!when.defined(primitive)) {
  117. return;
  118. }
  119. var numberOfPrimitives = primitiveBatchIds.length;
  120. var geometryPositions = geometry.attributes.position.values;
  121. var geometryIndices = geometry.indices;
  122. var positions = options.positions;
  123. var vertexBatchIds = options.vertexBatchIds;
  124. var indices = options.indices;
  125. var batchIds = options.batchIds;
  126. var batchTableColors = options.batchTableColors;
  127. var batchedIndices = options.batchedIndices;
  128. var indexOffsets = options.indexOffsets;
  129. var indexCounts = options.indexCounts;
  130. var boundingVolumes = options.boundingVolumes;
  131. var modelMatrix = options.modelMatrix;
  132. var center = options.center;
  133. var positionOffset = options.positionOffset;
  134. var batchIdIndex = options.batchIdIndex;
  135. var indexOffset = options.indexOffset;
  136. var batchedIndicesOffset = options.batchedIndicesOffset;
  137. for (var i = 0; i < numberOfPrimitives; ++i) {
  138. var primitiveModelMatrixAndBV = getModelMatrixAndBoundingVolume(primitive, i);
  139. var primitiveModelMatrix = primitiveModelMatrixAndBV.modelMatrix;
  140. BoundingSphere.Matrix4.multiply(modelMatrix, primitiveModelMatrix, primitiveModelMatrix);
  141. var batchId = primitiveBatchIds[i];
  142. var positionsLength = geometryPositions.length;
  143. for (var j = 0; j < positionsLength; j += 3) {
  144. var position = Cartographic.Cartesian3.unpack(geometryPositions, j, scratchPosition);
  145. BoundingSphere.Matrix4.multiplyByPoint(primitiveModelMatrix, position, position);
  146. Cartographic.Cartesian3.subtract(position, center, position);
  147. Cartographic.Cartesian3.pack(position, positions, positionOffset * 3 + j);
  148. vertexBatchIds[batchIdIndex++] = batchId;
  149. }
  150. var indicesLength = geometryIndices.length;
  151. for (var k = 0; k < indicesLength; ++k) {
  152. indices[indexOffset + k] = geometryIndices[k] + positionOffset;
  153. }
  154. var offset = i + batchedIndicesOffset;
  155. batchedIndices[offset] = new Vector3DTileBatch({
  156. offset : indexOffset,
  157. count : indicesLength,
  158. color : Color.Color.fromRgba(batchTableColors[batchId]),
  159. batchIds : [batchId]
  160. });
  161. batchIds[offset] = batchId;
  162. indexOffsets[offset] = indexOffset;
  163. indexCounts[offset] = indicesLength;
  164. boundingVolumes[offset] = BoundingSphere.BoundingSphere.transform(primitiveModelMatrixAndBV.boundingVolume, primitiveModelMatrix);
  165. positionOffset += positionsLength / 3;
  166. indexOffset += indicesLength;
  167. }
  168. options.positionOffset = positionOffset;
  169. options.batchIdIndex = batchIdIndex;
  170. options.indexOffset = indexOffset;
  171. options.batchedIndicesOffset += numberOfPrimitives;
  172. }
  173. var scratchCenter = new Cartographic.Cartesian3();
  174. var scratchMatrix4 = new BoundingSphere.Matrix4();
  175. function unpackBuffer(buffer) {
  176. var packedBuffer = new Float64Array(buffer);
  177. var offset = 0;
  178. Cartographic.Cartesian3.unpack(packedBuffer, offset, scratchCenter);
  179. offset += Cartographic.Cartesian3.packedLength;
  180. BoundingSphere.Matrix4.unpack(packedBuffer, offset, scratchMatrix4);
  181. }
  182. function packedBatchedIndicesLength(batchedIndices) {
  183. var length = batchedIndices.length;
  184. var count = 0;
  185. for (var i = 0; i < length; ++i) {
  186. count += Color.Color.packedLength + 3 + batchedIndices[i].batchIds.length;
  187. }
  188. return count;
  189. }
  190. function packBuffer(indicesBytesPerElement, batchedIndices, boundingVolumes) {
  191. var numBVs = boundingVolumes.length;
  192. var length = 1 + 1 + numBVs * BoundingSphere.BoundingSphere.packedLength + 1 + packedBatchedIndicesLength(batchedIndices);
  193. var packedBuffer = new Float64Array(length);
  194. var offset = 0;
  195. packedBuffer[offset++] = indicesBytesPerElement;
  196. packedBuffer[offset++] = numBVs;
  197. for (var i = 0; i < numBVs; ++i) {
  198. BoundingSphere.BoundingSphere.pack(boundingVolumes[i], packedBuffer, offset);
  199. offset += BoundingSphere.BoundingSphere.packedLength;
  200. }
  201. var indicesLength = batchedIndices.length;
  202. packedBuffer[offset++] = indicesLength;
  203. for (var j = 0; j < indicesLength; ++j) {
  204. var batchedIndex = batchedIndices[j];
  205. Color.Color.pack(batchedIndex.color, packedBuffer, offset);
  206. offset += Color.Color.packedLength;
  207. packedBuffer[offset++] = batchedIndex.offset;
  208. packedBuffer[offset++] = batchedIndex.count;
  209. var batchIds = batchedIndex.batchIds;
  210. var batchIdsLength = batchIds.length;
  211. packedBuffer[offset++] = batchIdsLength;
  212. for (var k = 0; k < batchIdsLength; ++k) {
  213. packedBuffer[offset++] = batchIds[k];
  214. }
  215. }
  216. return packedBuffer;
  217. }
  218. function createVectorTileGeometries(parameters, transferableObjects) {
  219. var boxes = when.defined(parameters.boxes) ? new Float32Array(parameters.boxes) : undefined;
  220. var boxBatchIds = when.defined(parameters.boxBatchIds) ? new Uint16Array(parameters.boxBatchIds) : undefined;
  221. var cylinders = when.defined(parameters.cylinders) ? new Float32Array(parameters.cylinders) : undefined;
  222. var cylinderBatchIds = when.defined(parameters.cylinderBatchIds) ? new Uint16Array(parameters.cylinderBatchIds) : undefined;
  223. var ellipsoids = when.defined(parameters.ellipsoids) ? new Float32Array(parameters.ellipsoids) : undefined;
  224. var ellipsoidBatchIds = when.defined(parameters.ellipsoidBatchIds) ? new Uint16Array(parameters.ellipsoidBatchIds) : undefined;
  225. var spheres = when.defined(parameters.spheres) ? new Float32Array(parameters.spheres) : undefined;
  226. var sphereBatchIds = when.defined(parameters.sphereBatchIds) ? new Uint16Array(parameters.sphereBatchIds) : undefined;
  227. var numberOfBoxes = when.defined(boxes) ? boxBatchIds.length : 0;
  228. var numberOfCylinders = when.defined(cylinders) ? cylinderBatchIds.length : 0;
  229. var numberOfEllipsoids = when.defined(ellipsoids) ? ellipsoidBatchIds.length : 0;
  230. var numberOfSpheres = when.defined(spheres) ? sphereBatchIds.length : 0;
  231. var boxGeometry = BoxGeometry.BoxGeometry.getUnitBox();
  232. var cylinderGeometry = CylinderGeometry.CylinderGeometry.getUnitCylinder();
  233. var ellipsoidGeometry = EllipsoidGeometry.EllipsoidGeometry.getUnitEllipsoid();
  234. var boxPositions = boxGeometry.attributes.position.values;
  235. var cylinderPositions = cylinderGeometry.attributes.position.values;
  236. var ellipsoidPositions = ellipsoidGeometry.attributes.position.values;
  237. var numberOfPositions = boxPositions.length * numberOfBoxes;
  238. numberOfPositions += cylinderPositions.length * numberOfCylinders;
  239. numberOfPositions += ellipsoidPositions.length * (numberOfEllipsoids + numberOfSpheres);
  240. var boxIndices = boxGeometry.indices;
  241. var cylinderIndices = cylinderGeometry.indices;
  242. var ellipsoidIndices = ellipsoidGeometry.indices;
  243. var numberOfIndices = boxIndices.length * numberOfBoxes;
  244. numberOfIndices += cylinderIndices.length * numberOfCylinders;
  245. numberOfIndices += ellipsoidIndices.length * (numberOfEllipsoids + numberOfSpheres);
  246. var positions = new Float32Array(numberOfPositions);
  247. var vertexBatchIds = new Uint16Array(numberOfPositions / 3);
  248. var indices = IndexDatatype.IndexDatatype.createTypedArray(numberOfPositions / 3, numberOfIndices);
  249. var numberOfGeometries = numberOfBoxes + numberOfCylinders + numberOfEllipsoids + numberOfSpheres;
  250. var batchIds = new Uint16Array(numberOfGeometries);
  251. var batchedIndices = new Array(numberOfGeometries);
  252. var indexOffsets = new Uint32Array(numberOfGeometries);
  253. var indexCounts = new Uint32Array(numberOfGeometries);
  254. var boundingVolumes = new Array(numberOfGeometries);
  255. unpackBuffer(parameters.packedBuffer);
  256. var options = {
  257. batchTableColors : new Uint32Array(parameters.batchTableColors),
  258. positions : positions,
  259. vertexBatchIds : vertexBatchIds,
  260. indices : indices,
  261. batchIds : batchIds,
  262. batchedIndices : batchedIndices,
  263. indexOffsets : indexOffsets,
  264. indexCounts : indexCounts,
  265. boundingVolumes : boundingVolumes,
  266. positionOffset : 0,
  267. batchIdIndex : 0,
  268. indexOffset : 0,
  269. batchedIndicesOffset : 0,
  270. modelMatrix : scratchMatrix4,
  271. center : scratchCenter
  272. };
  273. createPrimitive(options, boxes, boxBatchIds, boxGeometry, boxModelMatrixAndBoundingVolume);
  274. createPrimitive(options, cylinders, cylinderBatchIds, cylinderGeometry, cylinderModelMatrixAndBoundingVolume);
  275. createPrimitive(options, ellipsoids, ellipsoidBatchIds, ellipsoidGeometry, ellipsoidModelMatrixAndBoundingVolume);
  276. createPrimitive(options, spheres, sphereBatchIds, ellipsoidGeometry, sphereModelMatrixAndBoundingVolume);
  277. var packedBuffer = packBuffer(indices.BYTES_PER_ELEMENT, batchedIndices, boundingVolumes);
  278. transferableObjects.push(positions.buffer, vertexBatchIds.buffer, indices.buffer);
  279. transferableObjects.push(batchIds.buffer, indexOffsets.buffer, indexCounts.buffer);
  280. transferableObjects.push(packedBuffer.buffer);
  281. return {
  282. positions : positions.buffer,
  283. vertexBatchIds : vertexBatchIds.buffer,
  284. indices : indices.buffer,
  285. indexOffsets : indexOffsets.buffer,
  286. indexCounts : indexCounts.buffer,
  287. batchIds : batchIds.buffer,
  288. packedBuffer : packedBuffer.buffer
  289. };
  290. }
  291. var createVectorTileGeometries$1 = createTaskProcessorWorker(createVectorTileGeometries);
  292. return createVectorTileGeometries$1;
  293. });