Vector3DTileContent.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  1. import Cartesian3 from "../Core/Cartesian3.js";
  2. import defaultValue from "../Core/defaultValue.js";
  3. import defer from "../Core/defer.js";
  4. import defined from "../Core/defined.js";
  5. import destroyObject from "../Core/destroyObject.js";
  6. import DeveloperError from "../Core/DeveloperError.js";
  7. import Ellipsoid from "../Core/Ellipsoid.js";
  8. import getJsonFromTypedArray from "../Core/getJsonFromTypedArray.js";
  9. import ComponentDatatype from "../Core/ComponentDatatype.js";
  10. import CesiumMath from "../Core/Math.js";
  11. import Matrix4 from "../Core/Matrix4.js";
  12. import Rectangle from "../Core/Rectangle.js";
  13. import RuntimeError from "../Core/RuntimeError.js";
  14. import Cesium3DTileBatchTable from "./Cesium3DTileBatchTable.js";
  15. import Cesium3DTileFeatureTable from "./Cesium3DTileFeatureTable.js";
  16. import Vector3DTilePoints from "./Vector3DTilePoints.js";
  17. import Vector3DTilePolygons from "./Vector3DTilePolygons.js";
  18. import Vector3DTilePolylines from "./Vector3DTilePolylines.js";
  19. import Vector3DTileClampedPolylines from "./Vector3DTileClampedPolylines.js";
  20. import decodeVectorPolylinePositions from "../Core/decodeVectorPolylinePositions.js";
  21. /**
  22. * Represents the contents of a
  23. * {@link https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/VectorData|Vector}
  24. * tile in a {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification|3D Tiles} tileset.
  25. * <p>
  26. * Implements the {@link Cesium3DTileContent} interface.
  27. * </p>
  28. *
  29. * @alias Vector3DTileContent
  30. * @constructor
  31. *
  32. * @private
  33. */
  34. function Vector3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset) {
  35. this._tileset = tileset;
  36. this._tile = tile;
  37. this._resource = resource;
  38. this._polygons = undefined;
  39. this._polylines = undefined;
  40. this._points = undefined;
  41. this._contentReadyPromise = undefined;
  42. this._readyPromise = defer();
  43. this._metadata = undefined;
  44. this._batchTable = undefined;
  45. this._features = undefined;
  46. /**
  47. * Part of the {@link Cesium3DTileContent} interface.
  48. */
  49. this.featurePropertiesDirty = false;
  50. this._group = undefined;
  51. initialize(this, arrayBuffer, byteOffset);
  52. }
  53. Object.defineProperties(Vector3DTileContent.prototype, {
  54. featuresLength: {
  55. get: function () {
  56. return defined(this._batchTable) ? this._batchTable.featuresLength : 0;
  57. },
  58. },
  59. pointsLength: {
  60. get: function () {
  61. if (defined(this._points)) {
  62. return this._points.pointsLength;
  63. }
  64. return 0;
  65. },
  66. },
  67. trianglesLength: {
  68. get: function () {
  69. let trianglesLength = 0;
  70. if (defined(this._polygons)) {
  71. trianglesLength += this._polygons.trianglesLength;
  72. }
  73. if (defined(this._polylines)) {
  74. trianglesLength += this._polylines.trianglesLength;
  75. }
  76. return trianglesLength;
  77. },
  78. },
  79. geometryByteLength: {
  80. get: function () {
  81. let geometryByteLength = 0;
  82. if (defined(this._polygons)) {
  83. geometryByteLength += this._polygons.geometryByteLength;
  84. }
  85. if (defined(this._polylines)) {
  86. geometryByteLength += this._polylines.geometryByteLength;
  87. }
  88. return geometryByteLength;
  89. },
  90. },
  91. texturesByteLength: {
  92. get: function () {
  93. if (defined(this._points)) {
  94. return this._points.texturesByteLength;
  95. }
  96. return 0;
  97. },
  98. },
  99. batchTableByteLength: {
  100. get: function () {
  101. return defined(this._batchTable) ? this._batchTable.memorySizeInBytes : 0;
  102. },
  103. },
  104. innerContents: {
  105. get: function () {
  106. return undefined;
  107. },
  108. },
  109. readyPromise: {
  110. get: function () {
  111. return this._readyPromise.promise;
  112. },
  113. },
  114. tileset: {
  115. get: function () {
  116. return this._tileset;
  117. },
  118. },
  119. tile: {
  120. get: function () {
  121. return this._tile;
  122. },
  123. },
  124. url: {
  125. get: function () {
  126. return this._resource.getUrlComponent(true);
  127. },
  128. },
  129. metadata: {
  130. get: function () {
  131. return this._metadata;
  132. },
  133. set: function (value) {
  134. this._metadata = value;
  135. },
  136. },
  137. batchTable: {
  138. get: function () {
  139. return this._batchTable;
  140. },
  141. },
  142. group: {
  143. get: function () {
  144. return this._group;
  145. },
  146. set: function (value) {
  147. this._group = value;
  148. },
  149. },
  150. });
  151. function createColorChangedCallback(content) {
  152. return function (batchId, color) {
  153. if (defined(content._polygons)) {
  154. content._polygons.updateCommands(batchId, color);
  155. }
  156. };
  157. }
  158. function getBatchIds(featureTableJson, featureTableBinary) {
  159. let polygonBatchIds;
  160. let polylineBatchIds;
  161. let pointBatchIds;
  162. let i;
  163. const numberOfPolygons = defaultValue(featureTableJson.POLYGONS_LENGTH, 0);
  164. const numberOfPolylines = defaultValue(featureTableJson.POLYLINES_LENGTH, 0);
  165. const numberOfPoints = defaultValue(featureTableJson.POINTS_LENGTH, 0);
  166. if (numberOfPolygons > 0 && defined(featureTableJson.POLYGON_BATCH_IDS)) {
  167. const polygonBatchIdsByteOffset =
  168. featureTableBinary.byteOffset +
  169. featureTableJson.POLYGON_BATCH_IDS.byteOffset;
  170. polygonBatchIds = new Uint16Array(
  171. featureTableBinary.buffer,
  172. polygonBatchIdsByteOffset,
  173. numberOfPolygons
  174. );
  175. }
  176. if (numberOfPolylines > 0 && defined(featureTableJson.POLYLINE_BATCH_IDS)) {
  177. const polylineBatchIdsByteOffset =
  178. featureTableBinary.byteOffset +
  179. featureTableJson.POLYLINE_BATCH_IDS.byteOffset;
  180. polylineBatchIds = new Uint16Array(
  181. featureTableBinary.buffer,
  182. polylineBatchIdsByteOffset,
  183. numberOfPolylines
  184. );
  185. }
  186. if (numberOfPoints > 0 && defined(featureTableJson.POINT_BATCH_IDS)) {
  187. const pointBatchIdsByteOffset =
  188. featureTableBinary.byteOffset +
  189. featureTableJson.POINT_BATCH_IDS.byteOffset;
  190. pointBatchIds = new Uint16Array(
  191. featureTableBinary.buffer,
  192. pointBatchIdsByteOffset,
  193. numberOfPoints
  194. );
  195. }
  196. const atLeastOneDefined =
  197. defined(polygonBatchIds) ||
  198. defined(polylineBatchIds) ||
  199. defined(pointBatchIds);
  200. const atLeastOneUndefined =
  201. (numberOfPolygons > 0 && !defined(polygonBatchIds)) ||
  202. (numberOfPolylines > 0 && !defined(polylineBatchIds)) ||
  203. (numberOfPoints > 0 && !defined(pointBatchIds));
  204. if (atLeastOneDefined && atLeastOneUndefined) {
  205. throw new RuntimeError(
  206. "If one group of batch ids is defined, then all batch ids must be defined."
  207. );
  208. }
  209. const allUndefinedBatchIds =
  210. !defined(polygonBatchIds) &&
  211. !defined(polylineBatchIds) &&
  212. !defined(pointBatchIds);
  213. if (allUndefinedBatchIds) {
  214. let id = 0;
  215. if (!defined(polygonBatchIds) && numberOfPolygons > 0) {
  216. polygonBatchIds = new Uint16Array(numberOfPolygons);
  217. for (i = 0; i < numberOfPolygons; ++i) {
  218. polygonBatchIds[i] = id++;
  219. }
  220. }
  221. if (!defined(polylineBatchIds) && numberOfPolylines > 0) {
  222. polylineBatchIds = new Uint16Array(numberOfPolylines);
  223. for (i = 0; i < numberOfPolylines; ++i) {
  224. polylineBatchIds[i] = id++;
  225. }
  226. }
  227. if (!defined(pointBatchIds) && numberOfPoints > 0) {
  228. pointBatchIds = new Uint16Array(numberOfPoints);
  229. for (i = 0; i < numberOfPoints; ++i) {
  230. pointBatchIds[i] = id++;
  231. }
  232. }
  233. }
  234. return {
  235. polygons: polygonBatchIds,
  236. polylines: polylineBatchIds,
  237. points: pointBatchIds,
  238. };
  239. }
  240. const sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT;
  241. function createFloatingPolylines(options) {
  242. return new Vector3DTilePolylines(options);
  243. }
  244. function createClampedPolylines(options) {
  245. return new Vector3DTileClampedPolylines(options);
  246. }
  247. function initialize(content, arrayBuffer, byteOffset) {
  248. byteOffset = defaultValue(byteOffset, 0);
  249. const uint8Array = new Uint8Array(arrayBuffer);
  250. const view = new DataView(arrayBuffer);
  251. byteOffset += sizeOfUint32; // Skip magic number
  252. const version = view.getUint32(byteOffset, true);
  253. if (version !== 1) {
  254. throw new RuntimeError(
  255. `Only Vector tile version 1 is supported. Version ${version} is not.`
  256. );
  257. }
  258. byteOffset += sizeOfUint32;
  259. const byteLength = view.getUint32(byteOffset, true);
  260. byteOffset += sizeOfUint32;
  261. if (byteLength === 0) {
  262. content._readyPromise.resolve(content);
  263. return;
  264. }
  265. const featureTableJSONByteLength = view.getUint32(byteOffset, true);
  266. byteOffset += sizeOfUint32;
  267. if (featureTableJSONByteLength === 0) {
  268. throw new RuntimeError(
  269. "Feature table must have a byte length greater than zero"
  270. );
  271. }
  272. const featureTableBinaryByteLength = view.getUint32(byteOffset, true);
  273. byteOffset += sizeOfUint32;
  274. const batchTableJSONByteLength = view.getUint32(byteOffset, true);
  275. byteOffset += sizeOfUint32;
  276. const batchTableBinaryByteLength = view.getUint32(byteOffset, true);
  277. byteOffset += sizeOfUint32;
  278. const indicesByteLength = view.getUint32(byteOffset, true);
  279. byteOffset += sizeOfUint32;
  280. const positionByteLength = view.getUint32(byteOffset, true);
  281. byteOffset += sizeOfUint32;
  282. const polylinePositionByteLength = view.getUint32(byteOffset, true);
  283. byteOffset += sizeOfUint32;
  284. const pointsPositionByteLength = view.getUint32(byteOffset, true);
  285. byteOffset += sizeOfUint32;
  286. const featureTableJson = getJsonFromTypedArray(
  287. uint8Array,
  288. byteOffset,
  289. featureTableJSONByteLength
  290. );
  291. byteOffset += featureTableJSONByteLength;
  292. const featureTableBinary = new Uint8Array(
  293. arrayBuffer,
  294. byteOffset,
  295. featureTableBinaryByteLength
  296. );
  297. byteOffset += featureTableBinaryByteLength;
  298. let batchTableJson;
  299. let batchTableBinary;
  300. if (batchTableJSONByteLength > 0) {
  301. // PERFORMANCE_IDEA: is it possible to allocate this on-demand? Perhaps keep the
  302. // arraybuffer/string compressed in memory and then decompress it when it is first accessed.
  303. //
  304. // We could also make another request for it, but that would make the property set/get
  305. // API async, and would double the number of numbers in some cases.
  306. batchTableJson = getJsonFromTypedArray(
  307. uint8Array,
  308. byteOffset,
  309. batchTableJSONByteLength
  310. );
  311. byteOffset += batchTableJSONByteLength;
  312. if (batchTableBinaryByteLength > 0) {
  313. // Has a batch table binary
  314. batchTableBinary = new Uint8Array(
  315. arrayBuffer,
  316. byteOffset,
  317. batchTableBinaryByteLength
  318. );
  319. // Copy the batchTableBinary section and let the underlying ArrayBuffer be freed
  320. batchTableBinary = new Uint8Array(batchTableBinary);
  321. byteOffset += batchTableBinaryByteLength;
  322. }
  323. }
  324. const numberOfPolygons = defaultValue(featureTableJson.POLYGONS_LENGTH, 0);
  325. const numberOfPolylines = defaultValue(featureTableJson.POLYLINES_LENGTH, 0);
  326. const numberOfPoints = defaultValue(featureTableJson.POINTS_LENGTH, 0);
  327. const totalPrimitives = numberOfPolygons + numberOfPolylines + numberOfPoints;
  328. const batchTable = new Cesium3DTileBatchTable(
  329. content,
  330. totalPrimitives,
  331. batchTableJson,
  332. batchTableBinary,
  333. createColorChangedCallback(content)
  334. );
  335. content._batchTable = batchTable;
  336. if (totalPrimitives === 0) {
  337. return;
  338. }
  339. const featureTable = new Cesium3DTileFeatureTable(
  340. featureTableJson,
  341. featureTableBinary
  342. );
  343. const region = featureTable.getGlobalProperty("REGION");
  344. if (!defined(region)) {
  345. throw new RuntimeError(
  346. "Feature table global property: REGION must be defined"
  347. );
  348. }
  349. const rectangle = Rectangle.unpack(region);
  350. const minHeight = region[4];
  351. const maxHeight = region[5];
  352. const modelMatrix = content._tile.computedTransform;
  353. let center = featureTable.getGlobalProperty(
  354. "RTC_CENTER",
  355. ComponentDatatype.FLOAT,
  356. 3
  357. );
  358. if (defined(center)) {
  359. center = Cartesian3.unpack(center);
  360. Matrix4.multiplyByPoint(modelMatrix, center, center);
  361. } else {
  362. center = Rectangle.center(rectangle);
  363. center.height = CesiumMath.lerp(minHeight, maxHeight, 0.5);
  364. center = Ellipsoid.WGS84.cartographicToCartesian(center);
  365. }
  366. const batchIds = getBatchIds(featureTableJson, featureTableBinary);
  367. byteOffset += (4 - (byteOffset % 4)) % 4;
  368. if (numberOfPolygons > 0) {
  369. featureTable.featuresLength = numberOfPolygons;
  370. const polygonCounts = defaultValue(
  371. featureTable.getPropertyArray(
  372. "POLYGON_COUNTS",
  373. ComponentDatatype.UNSIGNED_INT,
  374. 1
  375. ),
  376. featureTable.getPropertyArray(
  377. "POLYGON_COUNT",
  378. ComponentDatatype.UNSIGNED_INT,
  379. 1
  380. ) // Workaround for old vector tilesets using the non-plural name
  381. );
  382. if (!defined(polygonCounts)) {
  383. throw new RuntimeError(
  384. "Feature table property: POLYGON_COUNTS must be defined when POLYGONS_LENGTH is greater than 0"
  385. );
  386. }
  387. const polygonIndexCounts = defaultValue(
  388. featureTable.getPropertyArray(
  389. "POLYGON_INDEX_COUNTS",
  390. ComponentDatatype.UNSIGNED_INT,
  391. 1
  392. ),
  393. featureTable.getPropertyArray(
  394. "POLYGON_INDEX_COUNT",
  395. ComponentDatatype.UNSIGNED_INT,
  396. 1
  397. ) // Workaround for old vector tilesets using the non-plural name
  398. );
  399. if (!defined(polygonIndexCounts)) {
  400. throw new RuntimeError(
  401. "Feature table property: POLYGON_INDEX_COUNTS must be defined when POLYGONS_LENGTH is greater than 0"
  402. );
  403. }
  404. // Use the counts array to determine how many position values we want. If we used the byte length then
  405. // zero padding values would be included and cause the delta zig-zag decoding to fail
  406. const numPolygonPositions = polygonCounts.reduce(function (total, count) {
  407. return total + count * 2;
  408. }, 0);
  409. const numPolygonIndices = polygonIndexCounts.reduce(function (
  410. total,
  411. count
  412. ) {
  413. return total + count;
  414. },
  415. 0);
  416. const indices = new Uint32Array(arrayBuffer, byteOffset, numPolygonIndices);
  417. byteOffset += indicesByteLength;
  418. const polygonPositions = new Uint16Array(
  419. arrayBuffer,
  420. byteOffset,
  421. numPolygonPositions
  422. );
  423. byteOffset += positionByteLength;
  424. let polygonMinimumHeights;
  425. let polygonMaximumHeights;
  426. if (
  427. defined(featureTableJson.POLYGON_MINIMUM_HEIGHTS) &&
  428. defined(featureTableJson.POLYGON_MAXIMUM_HEIGHTS)
  429. ) {
  430. polygonMinimumHeights = featureTable.getPropertyArray(
  431. "POLYGON_MINIMUM_HEIGHTS",
  432. ComponentDatatype.FLOAT,
  433. 1
  434. );
  435. polygonMaximumHeights = featureTable.getPropertyArray(
  436. "POLYGON_MAXIMUM_HEIGHTS",
  437. ComponentDatatype.FLOAT,
  438. 1
  439. );
  440. }
  441. content._polygons = new Vector3DTilePolygons({
  442. positions: polygonPositions,
  443. counts: polygonCounts,
  444. indexCounts: polygonIndexCounts,
  445. indices: indices,
  446. minimumHeight: minHeight,
  447. maximumHeight: maxHeight,
  448. polygonMinimumHeights: polygonMinimumHeights,
  449. polygonMaximumHeights: polygonMaximumHeights,
  450. center: center,
  451. rectangle: rectangle,
  452. boundingVolume: content.tile.boundingVolume.boundingVolume,
  453. batchTable: batchTable,
  454. batchIds: batchIds.polygons,
  455. modelMatrix: modelMatrix,
  456. });
  457. }
  458. if (numberOfPolylines > 0) {
  459. featureTable.featuresLength = numberOfPolylines;
  460. const polylineCounts = defaultValue(
  461. featureTable.getPropertyArray(
  462. "POLYLINE_COUNTS",
  463. ComponentDatatype.UNSIGNED_INT,
  464. 1
  465. ),
  466. featureTable.getPropertyArray(
  467. "POLYLINE_COUNT",
  468. ComponentDatatype.UNSIGNED_INT,
  469. 1
  470. ) // Workaround for old vector tilesets using the non-plural name
  471. );
  472. if (!defined(polylineCounts)) {
  473. throw new RuntimeError(
  474. "Feature table property: POLYLINE_COUNTS must be defined when POLYLINES_LENGTH is greater than 0"
  475. );
  476. }
  477. let widths = featureTable.getPropertyArray(
  478. "POLYLINE_WIDTHS",
  479. ComponentDatatype.UNSIGNED_SHORT,
  480. 1
  481. );
  482. if (!defined(widths)) {
  483. widths = new Uint16Array(numberOfPolylines);
  484. for (let i = 0; i < numberOfPolylines; ++i) {
  485. widths[i] = 2.0;
  486. }
  487. }
  488. // Use the counts array to determine how many position values we want. If we used the byte length then
  489. // zero padding values would be included and cause the delta zig-zag decoding to fail
  490. const numPolylinePositions = polylineCounts.reduce(function (total, count) {
  491. return total + count * 3;
  492. }, 0);
  493. const polylinePositions = new Uint16Array(
  494. arrayBuffer,
  495. byteOffset,
  496. numPolylinePositions
  497. );
  498. byteOffset += polylinePositionByteLength;
  499. const tileset = content._tileset;
  500. const examineVectorLinesFunction = tileset.examineVectorLinesFunction;
  501. if (defined(examineVectorLinesFunction)) {
  502. const decodedPositions = decodeVectorPolylinePositions(
  503. new Uint16Array(polylinePositions),
  504. rectangle,
  505. minHeight,
  506. maxHeight,
  507. Ellipsoid.WGS84
  508. );
  509. examineVectorLines(
  510. decodedPositions,
  511. polylineCounts,
  512. batchIds.polylines,
  513. batchTable,
  514. content.url,
  515. examineVectorLinesFunction
  516. );
  517. }
  518. let createPolylines = createFloatingPolylines;
  519. if (defined(tileset.classificationType)) {
  520. createPolylines = createClampedPolylines;
  521. }
  522. content._polylines = createPolylines({
  523. positions: polylinePositions,
  524. widths: widths,
  525. counts: polylineCounts,
  526. batchIds: batchIds.polylines,
  527. minimumHeight: minHeight,
  528. maximumHeight: maxHeight,
  529. center: center,
  530. rectangle: rectangle,
  531. boundingVolume: content.tile.boundingVolume.boundingVolume,
  532. batchTable: batchTable,
  533. classificationType: tileset.classificationType,
  534. keepDecodedPositions: tileset.vectorKeepDecodedPositions,
  535. });
  536. }
  537. if (numberOfPoints > 0) {
  538. const pointPositions = new Uint16Array(
  539. arrayBuffer,
  540. byteOffset,
  541. numberOfPoints * 3
  542. );
  543. byteOffset += pointsPositionByteLength;
  544. content._points = new Vector3DTilePoints({
  545. positions: pointPositions,
  546. batchIds: batchIds.points,
  547. minimumHeight: minHeight,
  548. maximumHeight: maxHeight,
  549. rectangle: rectangle,
  550. batchTable: batchTable,
  551. });
  552. }
  553. }
  554. function createFeatures(content) {
  555. const featuresLength = content.featuresLength;
  556. if (!defined(content._features) && featuresLength > 0) {
  557. const features = new Array(featuresLength);
  558. if (defined(content._polygons)) {
  559. content._polygons.createFeatures(content, features);
  560. }
  561. if (defined(content._polylines)) {
  562. content._polylines.createFeatures(content, features);
  563. }
  564. if (defined(content._points)) {
  565. content._points.createFeatures(content, features);
  566. }
  567. content._features = features;
  568. }
  569. }
  570. Vector3DTileContent.prototype.hasProperty = function (batchId, name) {
  571. return this._batchTable.hasProperty(batchId, name);
  572. };
  573. Vector3DTileContent.prototype.getFeature = function (batchId) {
  574. //>>includeStart('debug', pragmas.debug);
  575. const featuresLength = this.featuresLength;
  576. if (!defined(batchId) || batchId < 0 || batchId >= featuresLength) {
  577. throw new DeveloperError(
  578. `batchId is required and between zero and featuresLength - 1 (${
  579. featuresLength - 1
  580. }).`
  581. );
  582. }
  583. //>>includeEnd('debug');
  584. createFeatures(this);
  585. return this._features[batchId];
  586. };
  587. Vector3DTileContent.prototype.applyDebugSettings = function (enabled, color) {
  588. if (defined(this._polygons)) {
  589. this._polygons.applyDebugSettings(enabled, color);
  590. }
  591. if (defined(this._polylines)) {
  592. this._polylines.applyDebugSettings(enabled, color);
  593. }
  594. if (defined(this._points)) {
  595. this._points.applyDebugSettings(enabled, color);
  596. }
  597. };
  598. Vector3DTileContent.prototype.applyStyle = function (style) {
  599. createFeatures(this);
  600. if (defined(this._polygons)) {
  601. this._polygons.applyStyle(style, this._features);
  602. }
  603. if (defined(this._polylines)) {
  604. this._polylines.applyStyle(style, this._features);
  605. }
  606. if (defined(this._points)) {
  607. this._points.applyStyle(style, this._features);
  608. }
  609. };
  610. Vector3DTileContent.prototype.update = function (tileset, frameState) {
  611. let ready = true;
  612. if (defined(this._polygons)) {
  613. this._polygons.classificationType = this._tileset.classificationType;
  614. this._polygons.debugWireframe = this._tileset.debugWireframe;
  615. this._polygons.update(frameState);
  616. ready = ready && this._polygons._ready;
  617. }
  618. if (defined(this._polylines)) {
  619. this._polylines.update(frameState);
  620. ready = ready && this._polylines._ready;
  621. }
  622. if (defined(this._points)) {
  623. this._points.update(frameState);
  624. ready = ready && this._points._ready;
  625. }
  626. if (defined(this._batchTable) && ready) {
  627. this._batchTable.update(tileset, frameState);
  628. }
  629. if (!defined(this._contentReadyPromise)) {
  630. const pointsPromise = defined(this._points)
  631. ? this._points.readyPromise
  632. : undefined;
  633. const polygonPromise = defined(this._polygons)
  634. ? this._polygons.readyPromise
  635. : undefined;
  636. const polylinePromise = defined(this._polylines)
  637. ? this._polylines.readyPromise
  638. : undefined;
  639. const that = this;
  640. this._contentReadyPromise = Promise.all([
  641. pointsPromise,
  642. polygonPromise,
  643. polylinePromise,
  644. ])
  645. .then(function () {
  646. that._readyPromise.resolve(that);
  647. })
  648. .catch(function (error) {
  649. that._readyPromise.reject(error);
  650. });
  651. }
  652. };
  653. Vector3DTileContent.prototype.getPolylinePositions = function (batchId) {
  654. const polylines = this._polylines;
  655. if (!defined(polylines)) {
  656. return undefined;
  657. }
  658. return polylines.getPositions(batchId);
  659. };
  660. Vector3DTileContent.prototype.isDestroyed = function () {
  661. return false;
  662. };
  663. Vector3DTileContent.prototype.destroy = function () {
  664. this._polygons = this._polygons && this._polygons.destroy();
  665. this._polylines = this._polylines && this._polylines.destroy();
  666. this._points = this._points && this._points.destroy();
  667. this._batchTable = this._batchTable && this._batchTable.destroy();
  668. return destroyObject(this);
  669. };
  670. function examineVectorLines(
  671. positions,
  672. counts,
  673. batchIds,
  674. batchTable,
  675. url,
  676. callback
  677. ) {
  678. const countsLength = counts.length;
  679. let polylineStart = 0;
  680. for (let i = 0; i < countsLength; i++) {
  681. const count = counts[i] * 3;
  682. const linePositions = positions.slice(polylineStart, polylineStart + count);
  683. polylineStart += count;
  684. callback(linePositions, batchIds[i], url, batchTable);
  685. }
  686. }
  687. export default Vector3DTileContent;