PrimitivePipeline-a17c18d8.js 35 KB

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