智慧水务管理系统 - 精河县供水工程综合管理平台

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