PrimitivePipeline-fc1a47ff.js 30 KB

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