PrimitivePipeline-be008fb1.js 31 KB

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