PrimitivePipeline-247fa72e.js 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966
  1. /* This file is automatically rebuilt by the Cesium build process. */
  2. define(['exports', './Transforms-323408fe', './ComponentDatatype-b1ea011a', './defaultValue-94c3e563', './RuntimeError-c581ca93', './Matrix2-69c32d33', './GeometryAttribute-cb73bb3f', './GeometryAttributes-7df9bef6', './GeometryPipeline-e27e35f8', './IndexDatatype-c4099fe9', './WebMercatorProjection-f88d3d05'], (function (exports, Transforms, ComponentDatatype, defaultValue, RuntimeError, Matrix2, GeometryAttribute, GeometryAttributes, GeometryPipeline, IndexDatatype, WebMercatorProjection) { 'use strict';
  3. /**
  4. * Value and type information for per-instance geometry attribute that determines the geometry instance offset
  5. *
  6. * @alias OffsetGeometryInstanceAttribute
  7. * @constructor
  8. *
  9. * @param {Number} [x=0] The x translation
  10. * @param {Number} [y=0] The y translation
  11. * @param {Number} [z=0] The z translation
  12. *
  13. * @private
  14. *
  15. * @see GeometryInstance
  16. * @see GeometryInstanceAttribute
  17. */
  18. function OffsetGeometryInstanceAttribute(x, y, z) {
  19. x = defaultValue.defaultValue(x, 0);
  20. y = defaultValue.defaultValue(y, 0);
  21. z = defaultValue.defaultValue(z, 0);
  22. /**
  23. * The values for the attributes stored in a typed array.
  24. *
  25. * @type Float32Array
  26. */
  27. this.value = new Float32Array([x, y, z]);
  28. }
  29. Object.defineProperties(OffsetGeometryInstanceAttribute.prototype, {
  30. /**
  31. * The datatype of each component in the attribute, e.g., individual elements in
  32. * {@link OffsetGeometryInstanceAttribute#value}.
  33. *
  34. * @memberof OffsetGeometryInstanceAttribute.prototype
  35. *
  36. * @type {ComponentDatatype}
  37. * @readonly
  38. *
  39. * @default {@link ComponentDatatype.FLOAT}
  40. */
  41. componentDatatype: {
  42. get: function () {
  43. return ComponentDatatype.ComponentDatatype.FLOAT;
  44. },
  45. },
  46. /**
  47. * The number of components in the attributes, i.e., {@link OffsetGeometryInstanceAttribute#value}.
  48. *
  49. * @memberof OffsetGeometryInstanceAttribute.prototype
  50. *
  51. * @type {Number}
  52. * @readonly
  53. *
  54. * @default 3
  55. */
  56. componentsPerAttribute: {
  57. get: function () {
  58. return 3;
  59. },
  60. },
  61. /**
  62. * When <code>true</code> and <code>componentDatatype</code> is an integer format,
  63. * indicate that the components should be mapped to the range [0, 1] (unsigned)
  64. * or [-1, 1] (signed) when they are accessed as floating-point for rendering.
  65. *
  66. * @memberof OffsetGeometryInstanceAttribute.prototype
  67. *
  68. * @type {Boolean}
  69. * @readonly
  70. *
  71. * @default false
  72. */
  73. normalize: {
  74. get: function () {
  75. return false;
  76. },
  77. },
  78. });
  79. /**
  80. * Creates a new {@link OffsetGeometryInstanceAttribute} instance given the provided an enabled flag and {@link DistanceDisplayCondition}.
  81. *
  82. * @param {Cartesian3} offset The cartesian offset
  83. * @returns {OffsetGeometryInstanceAttribute} The new {@link OffsetGeometryInstanceAttribute} instance.
  84. */
  85. OffsetGeometryInstanceAttribute.fromCartesian3 = function (offset) {
  86. //>>includeStart('debug', pragmas.debug);
  87. RuntimeError.Check.defined("offset", offset);
  88. //>>includeEnd('debug');
  89. return new OffsetGeometryInstanceAttribute(offset.x, offset.y, offset.z);
  90. };
  91. /**
  92. * Converts a distance display condition to a typed array that can be used to assign a distance display condition attribute.
  93. *
  94. * @param {Cartesian3} offset The cartesian offset
  95. * @param {Float32Array} [result] The array to store the result in, if undefined a new instance will be created.
  96. * @returns {Float32Array} The modified result parameter or a new instance if result was undefined.
  97. *
  98. * @example
  99. * const attributes = primitive.getGeometryInstanceAttributes('an id');
  100. * attributes.modelMatrix = Cesium.OffsetGeometryInstanceAttribute.toValue(modelMatrix, attributes.modelMatrix);
  101. */
  102. OffsetGeometryInstanceAttribute.toValue = function (offset, result) {
  103. //>>includeStart('debug', pragmas.debug);
  104. RuntimeError.Check.defined("offset", offset);
  105. //>>includeEnd('debug');
  106. if (!defaultValue.defined(result)) {
  107. result = new Float32Array([offset.x, offset.y, offset.z]);
  108. }
  109. result[0] = offset.x;
  110. result[1] = offset.y;
  111. result[2] = offset.z;
  112. return result;
  113. };
  114. function transformToWorldCoordinates(
  115. instances,
  116. primitiveModelMatrix,
  117. scene3DOnly
  118. ) {
  119. let toWorld = !scene3DOnly;
  120. const length = instances.length;
  121. let i;
  122. if (!toWorld && length > 1) {
  123. const modelMatrix = instances[0].modelMatrix;
  124. for (i = 1; i < length; ++i) {
  125. if (!Matrix2.Matrix4.equals(modelMatrix, instances[i].modelMatrix)) {
  126. toWorld = true;
  127. break;
  128. }
  129. }
  130. }
  131. if (toWorld) {
  132. for (i = 0; i < length; ++i) {
  133. if (defaultValue.defined(instances[i].geometry)) {
  134. GeometryPipeline.GeometryPipeline.transformToWorldCoordinates(instances[i]);
  135. }
  136. }
  137. } else {
  138. // Leave geometry in local coordinate system; auto update model-matrix.
  139. Matrix2.Matrix4.multiplyTransformation(
  140. primitiveModelMatrix,
  141. instances[0].modelMatrix,
  142. primitiveModelMatrix
  143. );
  144. }
  145. }
  146. function addGeometryBatchId(geometry, batchId) {
  147. const attributes = geometry.attributes;
  148. const positionAttr = attributes.position;
  149. const numberOfComponents =
  150. positionAttr.values.length / positionAttr.componentsPerAttribute;
  151. attributes.batchId = new GeometryAttribute.GeometryAttribute({
  152. componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,
  153. componentsPerAttribute: 1,
  154. values: new Float32Array(numberOfComponents),
  155. });
  156. const values = attributes.batchId.values;
  157. for (let j = 0; j < numberOfComponents; ++j) {
  158. values[j] = batchId;
  159. }
  160. }
  161. function addBatchIds(instances) {
  162. const length = instances.length;
  163. for (let i = 0; i < length; ++i) {
  164. const instance = instances[i];
  165. if (defaultValue.defined(instance.geometry)) {
  166. addGeometryBatchId(instance.geometry, i);
  167. } else if (
  168. defaultValue.defined(instance.westHemisphereGeometry) &&
  169. defaultValue.defined(instance.eastHemisphereGeometry)
  170. ) {
  171. addGeometryBatchId(instance.westHemisphereGeometry, i);
  172. addGeometryBatchId(instance.eastHemisphereGeometry, i);
  173. }
  174. }
  175. }
  176. function geometryPipeline(parameters) {
  177. const instances = parameters.instances;
  178. const projection = parameters.projection;
  179. const uintIndexSupport = parameters.elementIndexUintSupported;
  180. const scene3DOnly = parameters.scene3DOnly;
  181. const vertexCacheOptimize = parameters.vertexCacheOptimize;
  182. const compressVertices = parameters.compressVertices;
  183. const modelMatrix = parameters.modelMatrix;
  184. let i;
  185. let geometry;
  186. let primitiveType;
  187. let length = instances.length;
  188. for (i = 0; i < length; ++i) {
  189. if (defaultValue.defined(instances[i].geometry)) {
  190. primitiveType = instances[i].geometry.primitiveType;
  191. break;
  192. }
  193. }
  194. //>>includeStart('debug', pragmas.debug);
  195. for (i = 1; i < length; ++i) {
  196. if (
  197. defaultValue.defined(instances[i].geometry) &&
  198. instances[i].geometry.primitiveType !== primitiveType
  199. ) {
  200. throw new RuntimeError.DeveloperError(
  201. "All instance geometries must have the same primitiveType."
  202. );
  203. }
  204. }
  205. //>>includeEnd('debug');
  206. // Unify to world coordinates before combining.
  207. transformToWorldCoordinates(instances, modelMatrix, scene3DOnly);
  208. // Clip to IDL
  209. if (!scene3DOnly) {
  210. for (i = 0; i < length; ++i) {
  211. if (defaultValue.defined(instances[i].geometry)) {
  212. GeometryPipeline.GeometryPipeline.splitLongitude(instances[i]);
  213. }
  214. }
  215. }
  216. addBatchIds(instances);
  217. // Optimize for vertex shader caches
  218. if (vertexCacheOptimize) {
  219. for (i = 0; i < length; ++i) {
  220. const instance = instances[i];
  221. if (defaultValue.defined(instance.geometry)) {
  222. GeometryPipeline.GeometryPipeline.reorderForPostVertexCache(instance.geometry);
  223. GeometryPipeline.GeometryPipeline.reorderForPreVertexCache(instance.geometry);
  224. } else if (
  225. defaultValue.defined(instance.westHemisphereGeometry) &&
  226. defaultValue.defined(instance.eastHemisphereGeometry)
  227. ) {
  228. GeometryPipeline.GeometryPipeline.reorderForPostVertexCache(
  229. instance.westHemisphereGeometry
  230. );
  231. GeometryPipeline.GeometryPipeline.reorderForPreVertexCache(
  232. instance.westHemisphereGeometry
  233. );
  234. GeometryPipeline.GeometryPipeline.reorderForPostVertexCache(
  235. instance.eastHemisphereGeometry
  236. );
  237. GeometryPipeline.GeometryPipeline.reorderForPreVertexCache(
  238. instance.eastHemisphereGeometry
  239. );
  240. }
  241. }
  242. }
  243. // Combine into single geometry for better rendering performance.
  244. let geometries = GeometryPipeline.GeometryPipeline.combineInstances(instances);
  245. length = geometries.length;
  246. for (i = 0; i < length; ++i) {
  247. geometry = geometries[i];
  248. // Split positions for GPU RTE
  249. const attributes = geometry.attributes;
  250. if (!scene3DOnly) {
  251. for (const name in attributes) {
  252. if (
  253. attributes.hasOwnProperty(name) &&
  254. attributes[name].componentDatatype === ComponentDatatype.ComponentDatatype.DOUBLE
  255. ) {
  256. const name3D = `${name}3D`;
  257. const name2D = `${name}2D`;
  258. // Compute 2D positions
  259. GeometryPipeline.GeometryPipeline.projectTo2D(
  260. geometry,
  261. name,
  262. name3D,
  263. name2D,
  264. projection
  265. );
  266. if (defaultValue.defined(geometry.boundingSphere) && name === "position") {
  267. geometry.boundingSphereCV = Transforms.BoundingSphere.fromVertices(
  268. geometry.attributes.position2D.values
  269. );
  270. }
  271. GeometryPipeline.GeometryPipeline.encodeAttribute(
  272. geometry,
  273. name3D,
  274. `${name3D}High`,
  275. `${name3D}Low`
  276. );
  277. GeometryPipeline.GeometryPipeline.encodeAttribute(
  278. geometry,
  279. name2D,
  280. `${name2D}High`,
  281. `${name2D}Low`
  282. );
  283. }
  284. }
  285. } else {
  286. for (const name in attributes) {
  287. if (
  288. attributes.hasOwnProperty(name) &&
  289. attributes[name].componentDatatype === ComponentDatatype.ComponentDatatype.DOUBLE
  290. ) {
  291. GeometryPipeline.GeometryPipeline.encodeAttribute(
  292. geometry,
  293. name,
  294. `${name}3DHigh`,
  295. `${name}3DLow`
  296. );
  297. }
  298. }
  299. }
  300. // oct encode and pack normals, compress texture coordinates
  301. if (compressVertices) {
  302. GeometryPipeline.GeometryPipeline.compressVertices(geometry);
  303. }
  304. }
  305. if (!uintIndexSupport) {
  306. // Break into multiple geometries to fit within unsigned short indices if needed
  307. let splitGeometries = [];
  308. length = geometries.length;
  309. for (i = 0; i < length; ++i) {
  310. geometry = geometries[i];
  311. splitGeometries = splitGeometries.concat(
  312. GeometryPipeline.GeometryPipeline.fitToUnsignedShortIndices(geometry)
  313. );
  314. }
  315. geometries = splitGeometries;
  316. }
  317. return geometries;
  318. }
  319. function createPickOffsets(instances, geometryName, geometries, pickOffsets) {
  320. let offset;
  321. let indexCount;
  322. let geometryIndex;
  323. const offsetIndex = pickOffsets.length - 1;
  324. if (offsetIndex >= 0) {
  325. const pickOffset = pickOffsets[offsetIndex];
  326. offset = pickOffset.offset + pickOffset.count;
  327. geometryIndex = pickOffset.index;
  328. indexCount = geometries[geometryIndex].indices.length;
  329. } else {
  330. offset = 0;
  331. geometryIndex = 0;
  332. indexCount = geometries[geometryIndex].indices.length;
  333. }
  334. const length = instances.length;
  335. for (let i = 0; i < length; ++i) {
  336. const instance = instances[i];
  337. const geometry = instance[geometryName];
  338. if (!defaultValue.defined(geometry)) {
  339. continue;
  340. }
  341. const count = geometry.indices.length;
  342. if (offset + count > indexCount) {
  343. offset = 0;
  344. indexCount = geometries[++geometryIndex].indices.length;
  345. }
  346. pickOffsets.push({
  347. index: geometryIndex,
  348. offset: offset,
  349. count: count,
  350. });
  351. offset += count;
  352. }
  353. }
  354. function createInstancePickOffsets(instances, geometries) {
  355. const pickOffsets = [];
  356. createPickOffsets(instances, "geometry", geometries, pickOffsets);
  357. createPickOffsets(
  358. instances,
  359. "westHemisphereGeometry",
  360. geometries,
  361. pickOffsets
  362. );
  363. createPickOffsets(
  364. instances,
  365. "eastHemisphereGeometry",
  366. geometries,
  367. pickOffsets
  368. );
  369. return pickOffsets;
  370. }
  371. /**
  372. * @private
  373. */
  374. const PrimitivePipeline = {};
  375. /**
  376. * @private
  377. */
  378. PrimitivePipeline.combineGeometry = function (parameters) {
  379. let geometries;
  380. let attributeLocations;
  381. const instances = parameters.instances;
  382. const length = instances.length;
  383. let pickOffsets;
  384. let offsetInstanceExtend;
  385. let hasOffset = false;
  386. if (length > 0) {
  387. geometries = geometryPipeline(parameters);
  388. if (geometries.length > 0) {
  389. attributeLocations = GeometryPipeline.GeometryPipeline.createAttributeLocations(
  390. geometries[0]
  391. );
  392. if (parameters.createPickOffsets) {
  393. pickOffsets = createInstancePickOffsets(instances, geometries);
  394. }
  395. }
  396. if (
  397. defaultValue.defined(instances[0].attributes) &&
  398. defaultValue.defined(instances[0].attributes.offset)
  399. ) {
  400. offsetInstanceExtend = new Array(length);
  401. hasOffset = true;
  402. }
  403. }
  404. const boundingSpheres = new Array(length);
  405. const boundingSpheresCV = new Array(length);
  406. for (let i = 0; i < length; ++i) {
  407. const instance = instances[i];
  408. const geometry = instance.geometry;
  409. if (defaultValue.defined(geometry)) {
  410. boundingSpheres[i] = geometry.boundingSphere;
  411. boundingSpheresCV[i] = geometry.boundingSphereCV;
  412. if (hasOffset) {
  413. offsetInstanceExtend[i] = instance.geometry.offsetAttribute;
  414. }
  415. }
  416. const eastHemisphereGeometry = instance.eastHemisphereGeometry;
  417. const westHemisphereGeometry = instance.westHemisphereGeometry;
  418. if (defaultValue.defined(eastHemisphereGeometry) && defaultValue.defined(westHemisphereGeometry)) {
  419. if (
  420. defaultValue.defined(eastHemisphereGeometry.boundingSphere) &&
  421. defaultValue.defined(westHemisphereGeometry.boundingSphere)
  422. ) {
  423. boundingSpheres[i] = Transforms.BoundingSphere.union(
  424. eastHemisphereGeometry.boundingSphere,
  425. westHemisphereGeometry.boundingSphere
  426. );
  427. }
  428. if (
  429. defaultValue.defined(eastHemisphereGeometry.boundingSphereCV) &&
  430. defaultValue.defined(westHemisphereGeometry.boundingSphereCV)
  431. ) {
  432. boundingSpheresCV[i] = Transforms.BoundingSphere.union(
  433. eastHemisphereGeometry.boundingSphereCV,
  434. westHemisphereGeometry.boundingSphereCV
  435. );
  436. }
  437. }
  438. }
  439. return {
  440. geometries: geometries,
  441. modelMatrix: parameters.modelMatrix,
  442. attributeLocations: attributeLocations,
  443. pickOffsets: pickOffsets,
  444. offsetInstanceExtend: offsetInstanceExtend,
  445. boundingSpheres: boundingSpheres,
  446. boundingSpheresCV: boundingSpheresCV,
  447. };
  448. };
  449. function transferGeometry(geometry, transferableObjects) {
  450. const attributes = geometry.attributes;
  451. for (const name in attributes) {
  452. if (attributes.hasOwnProperty(name)) {
  453. const attribute = attributes[name];
  454. if (defaultValue.defined(attribute) && defaultValue.defined(attribute.values)) {
  455. transferableObjects.push(attribute.values.buffer);
  456. }
  457. }
  458. }
  459. if (defaultValue.defined(geometry.indices)) {
  460. transferableObjects.push(geometry.indices.buffer);
  461. }
  462. }
  463. function transferGeometries(geometries, transferableObjects) {
  464. const length = geometries.length;
  465. for (let i = 0; i < length; ++i) {
  466. transferGeometry(geometries[i], transferableObjects);
  467. }
  468. }
  469. // This function was created by simplifying packCreateGeometryResults into a count-only operation.
  470. function countCreateGeometryResults(items) {
  471. let count = 1;
  472. const length = items.length;
  473. for (let i = 0; i < length; i++) {
  474. const geometry = items[i];
  475. ++count;
  476. if (!defaultValue.defined(geometry)) {
  477. continue;
  478. }
  479. const attributes = geometry.attributes;
  480. count +=
  481. 7 +
  482. 2 * Transforms.BoundingSphere.packedLength +
  483. (defaultValue.defined(geometry.indices) ? geometry.indices.length : 0);
  484. for (const property in attributes) {
  485. if (
  486. attributes.hasOwnProperty(property) &&
  487. defaultValue.defined(attributes[property])
  488. ) {
  489. const attribute = attributes[property];
  490. count += 5 + attribute.values.length;
  491. }
  492. }
  493. }
  494. return count;
  495. }
  496. /**
  497. * @private
  498. */
  499. PrimitivePipeline.packCreateGeometryResults = function (
  500. items,
  501. transferableObjects
  502. ) {
  503. const packedData = new Float64Array(countCreateGeometryResults(items));
  504. const stringTable = [];
  505. const stringHash = {};
  506. const length = items.length;
  507. let count = 0;
  508. packedData[count++] = length;
  509. for (let i = 0; i < length; i++) {
  510. const geometry = items[i];
  511. const validGeometry = defaultValue.defined(geometry);
  512. packedData[count++] = validGeometry ? 1.0 : 0.0;
  513. if (!validGeometry) {
  514. continue;
  515. }
  516. packedData[count++] = geometry.primitiveType;
  517. packedData[count++] = geometry.geometryType;
  518. packedData[count++] = defaultValue.defaultValue(geometry.offsetAttribute, -1);
  519. const validBoundingSphere = defaultValue.defined(geometry.boundingSphere) ? 1.0 : 0.0;
  520. packedData[count++] = validBoundingSphere;
  521. if (validBoundingSphere) {
  522. Transforms.BoundingSphere.pack(geometry.boundingSphere, packedData, count);
  523. }
  524. count += Transforms.BoundingSphere.packedLength;
  525. const validBoundingSphereCV = defaultValue.defined(geometry.boundingSphereCV)
  526. ? 1.0
  527. : 0.0;
  528. packedData[count++] = validBoundingSphereCV;
  529. if (validBoundingSphereCV) {
  530. Transforms.BoundingSphere.pack(geometry.boundingSphereCV, packedData, count);
  531. }
  532. count += Transforms.BoundingSphere.packedLength;
  533. const attributes = geometry.attributes;
  534. const attributesToWrite = [];
  535. for (const property in attributes) {
  536. if (
  537. attributes.hasOwnProperty(property) &&
  538. defaultValue.defined(attributes[property])
  539. ) {
  540. attributesToWrite.push(property);
  541. if (!defaultValue.defined(stringHash[property])) {
  542. stringHash[property] = stringTable.length;
  543. stringTable.push(property);
  544. }
  545. }
  546. }
  547. packedData[count++] = attributesToWrite.length;
  548. for (let q = 0; q < attributesToWrite.length; q++) {
  549. const name = attributesToWrite[q];
  550. const attribute = attributes[name];
  551. packedData[count++] = stringHash[name];
  552. packedData[count++] = attribute.componentDatatype;
  553. packedData[count++] = attribute.componentsPerAttribute;
  554. packedData[count++] = attribute.normalize ? 1 : 0;
  555. packedData[count++] = attribute.values.length;
  556. packedData.set(attribute.values, count);
  557. count += attribute.values.length;
  558. }
  559. const indicesLength = defaultValue.defined(geometry.indices)
  560. ? geometry.indices.length
  561. : 0;
  562. packedData[count++] = indicesLength;
  563. if (indicesLength > 0) {
  564. packedData.set(geometry.indices, count);
  565. count += indicesLength;
  566. }
  567. }
  568. transferableObjects.push(packedData.buffer);
  569. return {
  570. stringTable: stringTable,
  571. packedData: packedData,
  572. };
  573. };
  574. /**
  575. * @private
  576. */
  577. PrimitivePipeline.unpackCreateGeometryResults = function (
  578. createGeometryResult
  579. ) {
  580. const stringTable = createGeometryResult.stringTable;
  581. const packedGeometry = createGeometryResult.packedData;
  582. let i;
  583. const result = new Array(packedGeometry[0]);
  584. let resultIndex = 0;
  585. let packedGeometryIndex = 1;
  586. while (packedGeometryIndex < packedGeometry.length) {
  587. const valid = packedGeometry[packedGeometryIndex++] === 1.0;
  588. if (!valid) {
  589. result[resultIndex++] = undefined;
  590. continue;
  591. }
  592. const primitiveType = packedGeometry[packedGeometryIndex++];
  593. const geometryType = packedGeometry[packedGeometryIndex++];
  594. let offsetAttribute = packedGeometry[packedGeometryIndex++];
  595. if (offsetAttribute === -1) {
  596. offsetAttribute = undefined;
  597. }
  598. let boundingSphere;
  599. let boundingSphereCV;
  600. const validBoundingSphere = packedGeometry[packedGeometryIndex++] === 1.0;
  601. if (validBoundingSphere) {
  602. boundingSphere = Transforms.BoundingSphere.unpack(
  603. packedGeometry,
  604. packedGeometryIndex
  605. );
  606. }
  607. packedGeometryIndex += Transforms.BoundingSphere.packedLength;
  608. const validBoundingSphereCV = packedGeometry[packedGeometryIndex++] === 1.0;
  609. if (validBoundingSphereCV) {
  610. boundingSphereCV = Transforms.BoundingSphere.unpack(
  611. packedGeometry,
  612. packedGeometryIndex
  613. );
  614. }
  615. packedGeometryIndex += Transforms.BoundingSphere.packedLength;
  616. let length;
  617. let values;
  618. let componentsPerAttribute;
  619. const attributes = new GeometryAttributes.GeometryAttributes();
  620. const numAttributes = packedGeometry[packedGeometryIndex++];
  621. for (i = 0; i < numAttributes; i++) {
  622. const name = stringTable[packedGeometry[packedGeometryIndex++]];
  623. const componentDatatype = packedGeometry[packedGeometryIndex++];
  624. componentsPerAttribute = packedGeometry[packedGeometryIndex++];
  625. const normalize = packedGeometry[packedGeometryIndex++] !== 0;
  626. length = packedGeometry[packedGeometryIndex++];
  627. values = ComponentDatatype.ComponentDatatype.createTypedArray(componentDatatype, length);
  628. for (let valuesIndex = 0; valuesIndex < length; valuesIndex++) {
  629. values[valuesIndex] = packedGeometry[packedGeometryIndex++];
  630. }
  631. attributes[name] = new GeometryAttribute.GeometryAttribute({
  632. componentDatatype: componentDatatype,
  633. componentsPerAttribute: componentsPerAttribute,
  634. normalize: normalize,
  635. values: values,
  636. });
  637. }
  638. let indices;
  639. length = packedGeometry[packedGeometryIndex++];
  640. if (length > 0) {
  641. const numberOfVertices = values.length / componentsPerAttribute;
  642. indices = IndexDatatype.IndexDatatype.createTypedArray(numberOfVertices, length);
  643. for (i = 0; i < length; i++) {
  644. indices[i] = packedGeometry[packedGeometryIndex++];
  645. }
  646. }
  647. result[resultIndex++] = new GeometryAttribute.Geometry({
  648. primitiveType: primitiveType,
  649. geometryType: geometryType,
  650. boundingSphere: boundingSphere,
  651. boundingSphereCV: boundingSphereCV,
  652. indices: indices,
  653. attributes: attributes,
  654. offsetAttribute: offsetAttribute,
  655. });
  656. }
  657. return result;
  658. };
  659. function packInstancesForCombine(instances, transferableObjects) {
  660. const length = instances.length;
  661. const packedData = new Float64Array(1 + length * 19);
  662. let count = 0;
  663. packedData[count++] = length;
  664. for (let i = 0; i < length; i++) {
  665. const instance = instances[i];
  666. Matrix2.Matrix4.pack(instance.modelMatrix, packedData, count);
  667. count += Matrix2.Matrix4.packedLength;
  668. if (defaultValue.defined(instance.attributes) && defaultValue.defined(instance.attributes.offset)) {
  669. const values = instance.attributes.offset.value;
  670. packedData[count] = values[0];
  671. packedData[count + 1] = values[1];
  672. packedData[count + 2] = values[2];
  673. }
  674. count += 3;
  675. }
  676. transferableObjects.push(packedData.buffer);
  677. return packedData;
  678. }
  679. function unpackInstancesForCombine(data) {
  680. const packedInstances = data;
  681. const result = new Array(packedInstances[0]);
  682. let count = 0;
  683. let i = 1;
  684. while (i < packedInstances.length) {
  685. const modelMatrix = Matrix2.Matrix4.unpack(packedInstances, i);
  686. let attributes;
  687. i += Matrix2.Matrix4.packedLength;
  688. if (defaultValue.defined(packedInstances[i])) {
  689. attributes = {
  690. offset: new OffsetGeometryInstanceAttribute(
  691. packedInstances[i],
  692. packedInstances[i + 1],
  693. packedInstances[i + 2]
  694. ),
  695. };
  696. }
  697. i += 3;
  698. result[count++] = {
  699. modelMatrix: modelMatrix,
  700. attributes: attributes,
  701. };
  702. }
  703. return result;
  704. }
  705. /**
  706. * @private
  707. */
  708. PrimitivePipeline.packCombineGeometryParameters = function (
  709. parameters,
  710. transferableObjects
  711. ) {
  712. const createGeometryResults = parameters.createGeometryResults;
  713. const length = createGeometryResults.length;
  714. for (let i = 0; i < length; i++) {
  715. transferableObjects.push(createGeometryResults[i].packedData.buffer);
  716. }
  717. return {
  718. createGeometryResults: parameters.createGeometryResults,
  719. packedInstances: packInstancesForCombine(
  720. parameters.instances,
  721. transferableObjects
  722. ),
  723. ellipsoid: parameters.ellipsoid,
  724. isGeographic: parameters.projection instanceof Transforms.GeographicProjection,
  725. elementIndexUintSupported: parameters.elementIndexUintSupported,
  726. scene3DOnly: parameters.scene3DOnly,
  727. vertexCacheOptimize: parameters.vertexCacheOptimize,
  728. compressVertices: parameters.compressVertices,
  729. modelMatrix: parameters.modelMatrix,
  730. createPickOffsets: parameters.createPickOffsets,
  731. };
  732. };
  733. /**
  734. * @private
  735. */
  736. PrimitivePipeline.unpackCombineGeometryParameters = function (
  737. packedParameters
  738. ) {
  739. const instances = unpackInstancesForCombine(packedParameters.packedInstances);
  740. const createGeometryResults = packedParameters.createGeometryResults;
  741. const length = createGeometryResults.length;
  742. let instanceIndex = 0;
  743. for (let resultIndex = 0; resultIndex < length; resultIndex++) {
  744. const geometries = PrimitivePipeline.unpackCreateGeometryResults(
  745. createGeometryResults[resultIndex]
  746. );
  747. const geometriesLength = geometries.length;
  748. for (
  749. let geometryIndex = 0;
  750. geometryIndex < geometriesLength;
  751. geometryIndex++
  752. ) {
  753. const geometry = geometries[geometryIndex];
  754. const instance = instances[instanceIndex];
  755. instance.geometry = geometry;
  756. ++instanceIndex;
  757. }
  758. }
  759. const ellipsoid = Matrix2.Ellipsoid.clone(packedParameters.ellipsoid);
  760. const projection = packedParameters.isGeographic
  761. ? new Transforms.GeographicProjection(ellipsoid)
  762. : new WebMercatorProjection.WebMercatorProjection(ellipsoid);
  763. return {
  764. instances: instances,
  765. ellipsoid: ellipsoid,
  766. projection: projection,
  767. elementIndexUintSupported: packedParameters.elementIndexUintSupported,
  768. scene3DOnly: packedParameters.scene3DOnly,
  769. vertexCacheOptimize: packedParameters.vertexCacheOptimize,
  770. compressVertices: packedParameters.compressVertices,
  771. modelMatrix: Matrix2.Matrix4.clone(packedParameters.modelMatrix),
  772. createPickOffsets: packedParameters.createPickOffsets,
  773. };
  774. };
  775. function packBoundingSpheres(boundingSpheres) {
  776. const length = boundingSpheres.length;
  777. const bufferLength = 1 + (Transforms.BoundingSphere.packedLength + 1) * length;
  778. const buffer = new Float32Array(bufferLength);
  779. let bufferIndex = 0;
  780. buffer[bufferIndex++] = length;
  781. for (let i = 0; i < length; ++i) {
  782. const bs = boundingSpheres[i];
  783. if (!defaultValue.defined(bs)) {
  784. buffer[bufferIndex++] = 0.0;
  785. } else {
  786. buffer[bufferIndex++] = 1.0;
  787. Transforms.BoundingSphere.pack(boundingSpheres[i], buffer, bufferIndex);
  788. }
  789. bufferIndex += Transforms.BoundingSphere.packedLength;
  790. }
  791. return buffer;
  792. }
  793. function unpackBoundingSpheres(buffer) {
  794. const result = new Array(buffer[0]);
  795. let count = 0;
  796. let i = 1;
  797. while (i < buffer.length) {
  798. if (buffer[i++] === 1.0) {
  799. result[count] = Transforms.BoundingSphere.unpack(buffer, i);
  800. }
  801. ++count;
  802. i += Transforms.BoundingSphere.packedLength;
  803. }
  804. return result;
  805. }
  806. /**
  807. * @private
  808. */
  809. PrimitivePipeline.packCombineGeometryResults = function (
  810. results,
  811. transferableObjects
  812. ) {
  813. if (defaultValue.defined(results.geometries)) {
  814. transferGeometries(results.geometries, transferableObjects);
  815. }
  816. const packedBoundingSpheres = packBoundingSpheres(results.boundingSpheres);
  817. const packedBoundingSpheresCV = packBoundingSpheres(
  818. results.boundingSpheresCV
  819. );
  820. transferableObjects.push(
  821. packedBoundingSpheres.buffer,
  822. packedBoundingSpheresCV.buffer
  823. );
  824. return {
  825. geometries: results.geometries,
  826. attributeLocations: results.attributeLocations,
  827. modelMatrix: results.modelMatrix,
  828. pickOffsets: results.pickOffsets,
  829. offsetInstanceExtend: results.offsetInstanceExtend,
  830. boundingSpheres: packedBoundingSpheres,
  831. boundingSpheresCV: packedBoundingSpheresCV,
  832. };
  833. };
  834. /**
  835. * @private
  836. */
  837. PrimitivePipeline.unpackCombineGeometryResults = function (packedResult) {
  838. return {
  839. geometries: packedResult.geometries,
  840. attributeLocations: packedResult.attributeLocations,
  841. modelMatrix: packedResult.modelMatrix,
  842. pickOffsets: packedResult.pickOffsets,
  843. offsetInstanceExtend: packedResult.offsetInstanceExtend,
  844. boundingSpheres: unpackBoundingSpheres(packedResult.boundingSpheres),
  845. boundingSpheresCV: unpackBoundingSpheres(packedResult.boundingSpheresCV),
  846. };
  847. };
  848. exports.PrimitivePipeline = PrimitivePipeline;
  849. }));