PrimitivePipeline-ed21cfbb.js 31 KB

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