PrimitivePipeline-c9b56b34.js 33 KB

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