Vector3DTileClampedPolylines.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. import ApproximateTerrainHeights from "../Core/ApproximateTerrainHeights.js";
  2. import Cartesian2 from "../Core/Cartesian2.js";
  3. import Cartesian3 from "../Core/Cartesian3.js";
  4. import Color from "../Core/Color.js";
  5. import ComponentDatatype from "../Core/ComponentDatatype.js";
  6. import defaultValue from "../Core/defaultValue.js";
  7. import defined from "../Core/defined.js";
  8. import destroyObject from "../Core/destroyObject.js";
  9. import Ellipsoid from "../Core/Ellipsoid.js";
  10. import FeatureDetection from "../Core/FeatureDetection.js";
  11. import IndexDatatype from "../Core/IndexDatatype.js";
  12. import OrientedBoundingBox from "../Core/OrientedBoundingBox.js";
  13. import Matrix4 from "../Core/Matrix4.js";
  14. import Rectangle from "../Core/Rectangle.js";
  15. import TaskProcessor from "../Core/TaskProcessor.js";
  16. import Buffer from "../Renderer/Buffer.js";
  17. import BufferUsage from "../Renderer/BufferUsage.js";
  18. import DrawCommand from "../Renderer/DrawCommand.js";
  19. import Pass from "../Renderer/Pass.js";
  20. import RenderState from "../Renderer/RenderState.js";
  21. import ShaderProgram from "../Renderer/ShaderProgram.js";
  22. import ShaderSource from "../Renderer/ShaderSource.js";
  23. import VertexArray from "../Renderer/VertexArray.js";
  24. import PolylineCommon from "../Shaders/PolylineCommon.js";
  25. import Vector3DTileClampedPolylinesVS from "../Shaders/Vector3DTileClampedPolylinesVS.js";
  26. import Vector3DTileClampedPolylinesFS from "../Shaders/Vector3DTileClampedPolylinesFS.js";
  27. import BlendingState from "./BlendingState.js";
  28. import Cesium3DTileFeature from "./Cesium3DTileFeature.js";
  29. import ClassificationType from "./ClassificationType.js";
  30. import CullFace from "./CullFace.js";
  31. import StencilConstants from "./StencilConstants.js";
  32. import StencilFunction from "./StencilFunction.js";
  33. import StencilOperation from "./StencilOperation.js";
  34. import Vector3DTilePolylines from "./Vector3DTilePolylines.js";
  35. /**
  36. * Creates a batch of polylines as volumes with shader-adjustable width.
  37. *
  38. * @alias Vector3DTileClampedPolylines
  39. * @constructor
  40. *
  41. * @param {object} options An object with following properties:
  42. * @param {Uint16Array} options.positions The positions of the polylines
  43. * @param {Uint32Array} options.counts The number or positions in the each polyline.
  44. * @param {Uint16Array} options.widths The width of each polyline.
  45. * @param {number} options.minimumHeight The minimum height of the tile's region.
  46. * @param {number} options.maximumHeight The maximum height of the tile's region.
  47. * @param {Rectangle} options.rectangle The rectangle containing the tile.
  48. * @param {Cartesian3} [options.center=Cartesian3.ZERO] The RTC center.
  49. * @param {Cesium3DTileBatchTable} options.batchTable The batch table for the tile containing the batched polylines.
  50. * @param {Uint16Array} options.batchIds The batch ids for each polyline.
  51. * @param {ClassificationType} options.classificationType The classification type.
  52. * @param {boolean} options.keepDecodedPositions Whether to keep decoded positions in memory.
  53. *
  54. * @private
  55. */
  56. function Vector3DTileClampedPolylines(options) {
  57. // these arrays hold data from the tile payload
  58. // and are all released after the first update.
  59. this._positions = options.positions;
  60. this._widths = options.widths;
  61. this._counts = options.counts;
  62. this._batchIds = options.batchIds;
  63. this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84);
  64. this._minimumHeight = options.minimumHeight;
  65. this._maximumHeight = options.maximumHeight;
  66. this._center = options.center;
  67. this._rectangle = options.rectangle;
  68. this._batchTable = options.batchTable;
  69. this._va = undefined;
  70. this._sp = undefined;
  71. this._rs = undefined;
  72. this._uniformMap = undefined;
  73. this._command = undefined;
  74. this._transferrableBatchIds = undefined;
  75. this._packedBuffer = undefined;
  76. this._minimumMaximumVectorHeights = new Cartesian2(
  77. ApproximateTerrainHeights._defaultMinTerrainHeight,
  78. ApproximateTerrainHeights._defaultMaxTerrainHeight
  79. );
  80. this._boundingVolume = OrientedBoundingBox.fromRectangle(
  81. options.rectangle,
  82. ApproximateTerrainHeights._defaultMinTerrainHeight,
  83. ApproximateTerrainHeights._defaultMaxTerrainHeight,
  84. this._ellipsoid
  85. );
  86. this._classificationType = options.classificationType;
  87. this._keepDecodedPositions = options.keepDecodedPositions;
  88. this._decodedPositions = undefined;
  89. this._decodedPositionOffsets = undefined;
  90. // Fat vertices - all information for each volume packed to a vec3 and 5 vec4s
  91. this._startEllipsoidNormals = undefined;
  92. this._endEllipsoidNormals = undefined;
  93. this._startPositionAndHeights = undefined;
  94. this._startFaceNormalAndVertexCornerIds = undefined;
  95. this._endPositionAndHeights = undefined;
  96. this._endFaceNormalAndHalfWidths = undefined;
  97. this._vertexBatchIds = undefined;
  98. this._indices = undefined;
  99. this._constantColor = Color.clone(Color.WHITE);
  100. this._highlightColor = this._constantColor;
  101. this._trianglesLength = 0;
  102. this._geometryByteLength = 0;
  103. this._ready = false;
  104. this._promise = undefined;
  105. this._error = undefined;
  106. }
  107. Object.defineProperties(Vector3DTileClampedPolylines.prototype, {
  108. /**
  109. * Gets the number of triangles.
  110. *
  111. * @memberof Vector3DTileClampedPolylines.prototype
  112. *
  113. * @type {number}
  114. * @readonly
  115. */
  116. trianglesLength: {
  117. get: function () {
  118. return this._trianglesLength;
  119. },
  120. },
  121. /**
  122. * Gets the geometry memory in bytes.
  123. *
  124. * @memberof Vector3DTileClampedPolylines.prototype
  125. *
  126. * @type {number}
  127. * @readonly
  128. */
  129. geometryByteLength: {
  130. get: function () {
  131. return this._geometryByteLength;
  132. },
  133. },
  134. /**
  135. * Returns true when the primitive is ready to render.
  136. * @memberof Vector3DTileClampedPolylines.prototype
  137. * @type {boolean}
  138. * @readonly
  139. */
  140. ready: {
  141. get: function () {
  142. return this._ready;
  143. },
  144. },
  145. });
  146. function updateMinimumMaximumHeights(polylines, rectangle, ellipsoid) {
  147. const result = ApproximateTerrainHeights.getMinimumMaximumHeights(
  148. rectangle,
  149. ellipsoid
  150. );
  151. const min = result.minimumTerrainHeight;
  152. const max = result.maximumTerrainHeight;
  153. const minimumMaximumVectorHeights = polylines._minimumMaximumVectorHeights;
  154. minimumMaximumVectorHeights.x = min;
  155. minimumMaximumVectorHeights.y = max;
  156. const obb = polylines._boundingVolume;
  157. const rect = polylines._rectangle;
  158. OrientedBoundingBox.fromRectangle(rect, min, max, ellipsoid, obb);
  159. }
  160. function packBuffer(polylines) {
  161. const rectangle = polylines._rectangle;
  162. const minimumHeight = polylines._minimumHeight;
  163. const maximumHeight = polylines._maximumHeight;
  164. const ellipsoid = polylines._ellipsoid;
  165. const center = polylines._center;
  166. const packedLength =
  167. 2 +
  168. Rectangle.packedLength +
  169. Ellipsoid.packedLength +
  170. Cartesian3.packedLength;
  171. const packedBuffer = new Float64Array(packedLength);
  172. let offset = 0;
  173. packedBuffer[offset++] = minimumHeight;
  174. packedBuffer[offset++] = maximumHeight;
  175. Rectangle.pack(rectangle, packedBuffer, offset);
  176. offset += Rectangle.packedLength;
  177. Ellipsoid.pack(ellipsoid, packedBuffer, offset);
  178. offset += Ellipsoid.packedLength;
  179. Cartesian3.pack(center, packedBuffer, offset);
  180. return packedBuffer;
  181. }
  182. const createVerticesTaskProcessor = new TaskProcessor(
  183. "createVectorTileClampedPolylines"
  184. );
  185. const attributeLocations = {
  186. startEllipsoidNormal: 0,
  187. endEllipsoidNormal: 1,
  188. startPositionAndHeight: 2,
  189. endPositionAndHeight: 3,
  190. startFaceNormalAndVertexCorner: 4,
  191. endFaceNormalAndHalfWidth: 5,
  192. a_batchId: 6,
  193. };
  194. function createVertexArray(polylines, context) {
  195. if (defined(polylines._va)) {
  196. return;
  197. }
  198. let positions = polylines._positions;
  199. let widths = polylines._widths;
  200. let counts = polylines._counts;
  201. let batchIds = polylines._transferrableBatchIds;
  202. let packedBuffer = polylines._packedBuffer;
  203. if (!defined(packedBuffer)) {
  204. // Copy because they may be the views on the same buffer.
  205. positions = polylines._positions = positions.slice();
  206. widths = polylines._widths = widths.slice();
  207. counts = polylines._counts = counts.slice();
  208. batchIds = polylines._transferrableBatchIds = polylines._batchIds.slice();
  209. packedBuffer = polylines._packedBuffer = packBuffer(polylines);
  210. }
  211. const transferrableObjects = [
  212. positions.buffer,
  213. widths.buffer,
  214. counts.buffer,
  215. batchIds.buffer,
  216. packedBuffer.buffer,
  217. ];
  218. const parameters = {
  219. positions: positions.buffer,
  220. widths: widths.buffer,
  221. counts: counts.buffer,
  222. batchIds: batchIds.buffer,
  223. packedBuffer: packedBuffer.buffer,
  224. keepDecodedPositions: polylines._keepDecodedPositions,
  225. };
  226. const verticesPromise = createVerticesTaskProcessor.scheduleTask(
  227. parameters,
  228. transferrableObjects
  229. );
  230. if (!defined(verticesPromise)) {
  231. // Postponed
  232. return;
  233. }
  234. return verticesPromise
  235. .then(function (result) {
  236. if (polylines.isDestroyed()) {
  237. return;
  238. }
  239. if (polylines._keepDecodedPositions) {
  240. polylines._decodedPositions = new Float64Array(result.decodedPositions);
  241. polylines._decodedPositionOffsets = new Uint32Array(
  242. result.decodedPositionOffsets
  243. );
  244. }
  245. polylines._startEllipsoidNormals = new Float32Array(
  246. result.startEllipsoidNormals
  247. );
  248. polylines._endEllipsoidNormals = new Float32Array(
  249. result.endEllipsoidNormals
  250. );
  251. polylines._startPositionAndHeights = new Float32Array(
  252. result.startPositionAndHeights
  253. );
  254. polylines._startFaceNormalAndVertexCornerIds = new Float32Array(
  255. result.startFaceNormalAndVertexCornerIds
  256. );
  257. polylines._endPositionAndHeights = new Float32Array(
  258. result.endPositionAndHeights
  259. );
  260. polylines._endFaceNormalAndHalfWidths = new Float32Array(
  261. result.endFaceNormalAndHalfWidths
  262. );
  263. polylines._vertexBatchIds = new Uint16Array(result.vertexBatchIds);
  264. const indexDatatype = result.indexDatatype;
  265. polylines._indices =
  266. indexDatatype === IndexDatatype.UNSIGNED_SHORT
  267. ? new Uint16Array(result.indices)
  268. : new Uint32Array(result.indices);
  269. finishVertexArray(polylines, context);
  270. polylines._ready = true;
  271. })
  272. .catch((error) => {
  273. if (polylines.isDestroyed()) {
  274. return;
  275. }
  276. // Throw the error next frame
  277. polylines._error = error;
  278. });
  279. }
  280. function finishVertexArray(polylines, context) {
  281. if (!defined(polylines._va)) {
  282. const startEllipsoidNormals = polylines._startEllipsoidNormals;
  283. const endEllipsoidNormals = polylines._endEllipsoidNormals;
  284. const startPositionAndHeights = polylines._startPositionAndHeights;
  285. const endPositionAndHeights = polylines._endPositionAndHeights;
  286. const startFaceNormalAndVertexCornerIds =
  287. polylines._startFaceNormalAndVertexCornerIds;
  288. const endFaceNormalAndHalfWidths = polylines._endFaceNormalAndHalfWidths;
  289. const batchIdAttribute = polylines._vertexBatchIds;
  290. const indices = polylines._indices;
  291. let byteLength =
  292. startEllipsoidNormals.byteLength + endEllipsoidNormals.byteLength;
  293. byteLength +=
  294. startPositionAndHeights.byteLength + endPositionAndHeights.byteLength;
  295. byteLength +=
  296. startFaceNormalAndVertexCornerIds.byteLength +
  297. endFaceNormalAndHalfWidths.byteLength;
  298. byteLength += batchIdAttribute.byteLength + indices.byteLength;
  299. polylines._trianglesLength = indices.length / 3;
  300. polylines._geometryByteLength = byteLength;
  301. const startEllipsoidNormalsBuffer = Buffer.createVertexBuffer({
  302. context: context,
  303. typedArray: startEllipsoidNormals,
  304. usage: BufferUsage.STATIC_DRAW,
  305. });
  306. const endEllipsoidNormalsBuffer = Buffer.createVertexBuffer({
  307. context: context,
  308. typedArray: endEllipsoidNormals,
  309. usage: BufferUsage.STATIC_DRAW,
  310. });
  311. const startPositionAndHeightsBuffer = Buffer.createVertexBuffer({
  312. context: context,
  313. typedArray: startPositionAndHeights,
  314. usage: BufferUsage.STATIC_DRAW,
  315. });
  316. const endPositionAndHeightsBuffer = Buffer.createVertexBuffer({
  317. context: context,
  318. typedArray: endPositionAndHeights,
  319. usage: BufferUsage.STATIC_DRAW,
  320. });
  321. const startFaceNormalAndVertexCornerIdsBuffer = Buffer.createVertexBuffer({
  322. context: context,
  323. typedArray: startFaceNormalAndVertexCornerIds,
  324. usage: BufferUsage.STATIC_DRAW,
  325. });
  326. const endFaceNormalAndHalfWidthsBuffer = Buffer.createVertexBuffer({
  327. context: context,
  328. typedArray: endFaceNormalAndHalfWidths,
  329. usage: BufferUsage.STATIC_DRAW,
  330. });
  331. const batchIdAttributeBuffer = Buffer.createVertexBuffer({
  332. context: context,
  333. typedArray: batchIdAttribute,
  334. usage: BufferUsage.STATIC_DRAW,
  335. });
  336. const indexBuffer = Buffer.createIndexBuffer({
  337. context: context,
  338. typedArray: indices,
  339. usage: BufferUsage.STATIC_DRAW,
  340. indexDatatype:
  341. indices.BYTES_PER_ELEMENT === 2
  342. ? IndexDatatype.UNSIGNED_SHORT
  343. : IndexDatatype.UNSIGNED_INT,
  344. });
  345. const vertexAttributes = [
  346. {
  347. index: attributeLocations.startEllipsoidNormal,
  348. vertexBuffer: startEllipsoidNormalsBuffer,
  349. componentDatatype: ComponentDatatype.FLOAT,
  350. componentsPerAttribute: 3,
  351. },
  352. {
  353. index: attributeLocations.endEllipsoidNormal,
  354. vertexBuffer: endEllipsoidNormalsBuffer,
  355. componentDatatype: ComponentDatatype.FLOAT,
  356. componentsPerAttribute: 3,
  357. },
  358. {
  359. index: attributeLocations.startPositionAndHeight,
  360. vertexBuffer: startPositionAndHeightsBuffer,
  361. componentDatatype: ComponentDatatype.FLOAT,
  362. componentsPerAttribute: 4,
  363. },
  364. {
  365. index: attributeLocations.endPositionAndHeight,
  366. vertexBuffer: endPositionAndHeightsBuffer,
  367. componentDatatype: ComponentDatatype.FLOAT,
  368. componentsPerAttribute: 4,
  369. },
  370. {
  371. index: attributeLocations.startFaceNormalAndVertexCorner,
  372. vertexBuffer: startFaceNormalAndVertexCornerIdsBuffer,
  373. componentDatatype: ComponentDatatype.FLOAT,
  374. componentsPerAttribute: 4,
  375. },
  376. {
  377. index: attributeLocations.endFaceNormalAndHalfWidth,
  378. vertexBuffer: endFaceNormalAndHalfWidthsBuffer,
  379. componentDatatype: ComponentDatatype.FLOAT,
  380. componentsPerAttribute: 4,
  381. },
  382. {
  383. index: attributeLocations.a_batchId,
  384. vertexBuffer: batchIdAttributeBuffer,
  385. componentDatatype: ComponentDatatype.UNSIGNED_SHORT,
  386. componentsPerAttribute: 1,
  387. },
  388. ];
  389. polylines._va = new VertexArray({
  390. context: context,
  391. attributes: vertexAttributes,
  392. indexBuffer: indexBuffer,
  393. });
  394. polylines._positions = undefined;
  395. polylines._widths = undefined;
  396. polylines._counts = undefined;
  397. polylines._ellipsoid = undefined;
  398. polylines._minimumHeight = undefined;
  399. polylines._maximumHeight = undefined;
  400. polylines._rectangle = undefined;
  401. polylines._transferrableBatchIds = undefined;
  402. polylines._packedBuffer = undefined;
  403. polylines._startEllipsoidNormals = undefined;
  404. polylines._endEllipsoidNormals = undefined;
  405. polylines._startPositionAndHeights = undefined;
  406. polylines._startFaceNormalAndVertexCornerIds = undefined;
  407. polylines._endPositionAndHeights = undefined;
  408. polylines._endFaceNormalAndHalfWidths = undefined;
  409. polylines._vertexBatchIds = undefined;
  410. polylines._indices = undefined;
  411. }
  412. }
  413. const modifiedModelViewScratch = new Matrix4();
  414. const rtcScratch = new Cartesian3();
  415. function createUniformMap(primitive, context) {
  416. if (defined(primitive._uniformMap)) {
  417. return;
  418. }
  419. primitive._uniformMap = {
  420. u_modifiedModelView: function () {
  421. const viewMatrix = context.uniformState.view;
  422. Matrix4.clone(viewMatrix, modifiedModelViewScratch);
  423. Matrix4.multiplyByPoint(
  424. modifiedModelViewScratch,
  425. primitive._center,
  426. rtcScratch
  427. );
  428. Matrix4.setTranslation(
  429. modifiedModelViewScratch,
  430. rtcScratch,
  431. modifiedModelViewScratch
  432. );
  433. return modifiedModelViewScratch;
  434. },
  435. u_highlightColor: function () {
  436. return primitive._highlightColor;
  437. },
  438. u_minimumMaximumVectorHeights: function () {
  439. return primitive._minimumMaximumVectorHeights;
  440. },
  441. };
  442. }
  443. function getRenderState(mask3DTiles) {
  444. /**
  445. * Cull front faces of each volume (relative to camera) to prevent
  446. * classification drawing from both the front and back faces, double-draw.
  447. * The geometry is "inverted" (inside-out winding order for the indices) but
  448. * the vertex shader seems to re-invert so that the triangles face "out" again.
  449. * So cull FRONT faces.
  450. */
  451. return RenderState.fromCache({
  452. cull: {
  453. enabled: true,
  454. face: CullFace.FRONT,
  455. },
  456. blending: BlendingState.PRE_MULTIPLIED_ALPHA_BLEND,
  457. depthMask: false,
  458. stencilTest: {
  459. enabled: mask3DTiles,
  460. frontFunction: StencilFunction.EQUAL,
  461. frontOperation: {
  462. fail: StencilOperation.KEEP,
  463. zFail: StencilOperation.KEEP,
  464. zPass: StencilOperation.KEEP,
  465. },
  466. backFunction: StencilFunction.EQUAL,
  467. backOperation: {
  468. fail: StencilOperation.KEEP,
  469. zFail: StencilOperation.KEEP,
  470. zPass: StencilOperation.KEEP,
  471. },
  472. reference: StencilConstants.CESIUM_3D_TILE_MASK,
  473. mask: StencilConstants.CESIUM_3D_TILE_MASK,
  474. },
  475. });
  476. }
  477. function createRenderStates(primitive) {
  478. if (defined(primitive._rs)) {
  479. return;
  480. }
  481. primitive._rs = getRenderState(false);
  482. primitive._rs3DTiles = getRenderState(true);
  483. }
  484. function createShaders(primitive, context) {
  485. if (defined(primitive._sp)) {
  486. return;
  487. }
  488. const batchTable = primitive._batchTable;
  489. const vsSource = batchTable.getVertexShaderCallback(
  490. false,
  491. "a_batchId",
  492. undefined
  493. )(Vector3DTileClampedPolylinesVS);
  494. const fsSource = batchTable.getFragmentShaderCallback(
  495. false,
  496. undefined,
  497. true
  498. )(Vector3DTileClampedPolylinesFS);
  499. const vs = new ShaderSource({
  500. defines: [
  501. "VECTOR_TILE",
  502. !FeatureDetection.isInternetExplorer() ? "CLIP_POLYLINE" : "",
  503. ],
  504. sources: [PolylineCommon, vsSource],
  505. });
  506. const fs = new ShaderSource({
  507. defines: ["VECTOR_TILE"],
  508. sources: [fsSource],
  509. });
  510. primitive._sp = ShaderProgram.fromCache({
  511. context: context,
  512. vertexShaderSource: vs,
  513. fragmentShaderSource: fs,
  514. attributeLocations: attributeLocations,
  515. });
  516. }
  517. function queueCommands(primitive, frameState) {
  518. let command = primitive._command;
  519. if (!defined(primitive._command)) {
  520. const uniformMap = primitive._batchTable.getUniformMapCallback()(
  521. primitive._uniformMap
  522. );
  523. command = primitive._command = new DrawCommand({
  524. owner: primitive,
  525. vertexArray: primitive._va,
  526. renderState: primitive._rs,
  527. shaderProgram: primitive._sp,
  528. uniformMap: uniformMap,
  529. boundingVolume: primitive._boundingVolume,
  530. pass: Pass.TERRAIN_CLASSIFICATION,
  531. pickId: primitive._batchTable.getPickId(),
  532. });
  533. const derivedTilesetCommand = DrawCommand.shallowClone(
  534. command,
  535. command.derivedCommands.tileset
  536. );
  537. derivedTilesetCommand.renderState = primitive._rs3DTiles;
  538. derivedTilesetCommand.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION;
  539. command.derivedCommands.tileset = derivedTilesetCommand;
  540. }
  541. const classificationType = primitive._classificationType;
  542. if (
  543. classificationType === ClassificationType.TERRAIN ||
  544. classificationType === ClassificationType.BOTH
  545. ) {
  546. frameState.commandList.push(command);
  547. }
  548. if (
  549. classificationType === ClassificationType.CESIUM_3D_TILE ||
  550. classificationType === ClassificationType.BOTH
  551. ) {
  552. frameState.commandList.push(command.derivedCommands.tileset);
  553. }
  554. }
  555. /**
  556. * Get the polyline positions for the given feature.
  557. *
  558. * @param {number} batchId The batch ID of the feature.
  559. */
  560. Vector3DTileClampedPolylines.prototype.getPositions = function (batchId) {
  561. return Vector3DTilePolylines.getPolylinePositions(this, batchId);
  562. };
  563. /**
  564. * Creates features for each polyline and places it at the batch id index of features.
  565. *
  566. * @param {Vector3DTileContent} content The vector tile content.
  567. * @param {Cesium3DTileFeature[]} features An array of features where the polygon features will be placed.
  568. */
  569. Vector3DTileClampedPolylines.prototype.createFeatures = function (
  570. content,
  571. features
  572. ) {
  573. const batchIds = this._batchIds;
  574. const length = batchIds.length;
  575. for (let i = 0; i < length; ++i) {
  576. const batchId = batchIds[i];
  577. features[batchId] = new Cesium3DTileFeature(content, batchId);
  578. }
  579. };
  580. /**
  581. * Colors the entire tile when enabled is true. The resulting color will be (polyline batch table color * color).
  582. *
  583. * @param {boolean} enabled Whether to enable debug coloring.
  584. * @param {Color} color The debug color.
  585. */
  586. Vector3DTileClampedPolylines.prototype.applyDebugSettings = function (
  587. enabled,
  588. color
  589. ) {
  590. this._highlightColor = enabled ? color : this._constantColor;
  591. };
  592. function clearStyle(polygons, features) {
  593. const batchIds = polygons._batchIds;
  594. const length = batchIds.length;
  595. for (let i = 0; i < length; ++i) {
  596. const batchId = batchIds[i];
  597. const feature = features[batchId];
  598. feature.show = true;
  599. feature.color = Color.WHITE;
  600. }
  601. }
  602. const scratchColor = new Color();
  603. const DEFAULT_COLOR_VALUE = Color.WHITE;
  604. const DEFAULT_SHOW_VALUE = true;
  605. /**
  606. * Apply a style to the content.
  607. *
  608. * @param {Cesium3DTileStyle} style The style.
  609. * @param {Cesium3DTileFeature[]} features The dictionary of features.
  610. */
  611. Vector3DTileClampedPolylines.prototype.applyStyle = function (style, features) {
  612. if (!defined(style)) {
  613. clearStyle(this, features);
  614. return;
  615. }
  616. const batchIds = this._batchIds;
  617. const length = batchIds.length;
  618. for (let i = 0; i < length; ++i) {
  619. const batchId = batchIds[i];
  620. const feature = features[batchId];
  621. feature.color = defined(style.color)
  622. ? style.color.evaluateColor(feature, scratchColor)
  623. : DEFAULT_COLOR_VALUE;
  624. feature.show = defined(style.show)
  625. ? style.show.evaluate(feature)
  626. : DEFAULT_SHOW_VALUE;
  627. }
  628. };
  629. function initialize(polylines) {
  630. return ApproximateTerrainHeights.initialize()
  631. .then(function () {
  632. updateMinimumMaximumHeights(
  633. polylines,
  634. polylines._rectangle,
  635. polylines._ellipsoid
  636. );
  637. })
  638. .catch((error) => {
  639. if (polylines.isDestroyed()) {
  640. return;
  641. }
  642. // Throw the error next frame
  643. polylines._error = error;
  644. });
  645. }
  646. /**
  647. * Updates the batches and queues the commands for rendering.
  648. *
  649. * @param {FrameState} frameState The current frame state.
  650. */
  651. Vector3DTileClampedPolylines.prototype.update = function (frameState) {
  652. const context = frameState.context;
  653. if (!this._ready) {
  654. if (!defined(this._promise)) {
  655. this._promise = initialize(this).then(createVertexArray(this, context));
  656. }
  657. if (defined(this._error)) {
  658. const error = this._error;
  659. this._error = undefined;
  660. throw error;
  661. }
  662. return;
  663. }
  664. createUniformMap(this, context);
  665. createShaders(this, context);
  666. createRenderStates(this);
  667. const passes = frameState.passes;
  668. if (passes.render || passes.pick) {
  669. queueCommands(this, frameState);
  670. }
  671. };
  672. /**
  673. * Returns true if this object was destroyed; otherwise, false.
  674. * <p>
  675. * If this object was destroyed, it should not be used; calling any function other than
  676. * <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
  677. * </p>
  678. *
  679. * @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>.
  680. */
  681. Vector3DTileClampedPolylines.prototype.isDestroyed = function () {
  682. return false;
  683. };
  684. /**
  685. * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic
  686. * release of WebGL resources, instead of relying on the garbage collector to destroy this object.
  687. * <p>
  688. * Once an object is destroyed, it should not be used; calling any function other than
  689. * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore,
  690. * assign the return value (<code>undefined</code>) to the object as done in the example.
  691. * </p>
  692. *
  693. * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
  694. */
  695. Vector3DTileClampedPolylines.prototype.destroy = function () {
  696. this._va = this._va && this._va.destroy();
  697. this._sp = this._sp && this._sp.destroy();
  698. return destroyObject(this);
  699. };
  700. export default Vector3DTileClampedPolylines;