PolylineGeometryUpdater.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  1. import ArcType from "../Core/ArcType.js";
  2. import BoundingSphere from "../Core/BoundingSphere.js";
  3. import Check from "../Core/Check.js";
  4. import Color from "../Core/Color.js";
  5. import ColorGeometryInstanceAttribute from "../Core/ColorGeometryInstanceAttribute.js";
  6. import defaultValue from "../Core/defaultValue.js";
  7. import defined from "../Core/defined.js";
  8. import destroyObject from "../Core/destroyObject.js";
  9. import DeveloperError from "../Core/DeveloperError.js";
  10. import DistanceDisplayCondition from "../Core/DistanceDisplayCondition.js";
  11. import DistanceDisplayConditionGeometryInstanceAttribute from "../Core/DistanceDisplayConditionGeometryInstanceAttribute.js";
  12. import Event from "../Core/Event.js";
  13. import GeometryInstance from "../Core/GeometryInstance.js";
  14. import GroundPolylineGeometry from "../Core/GroundPolylineGeometry.js";
  15. import Iso8601 from "../Core/Iso8601.js";
  16. import oneTimeWarning from "../Core/oneTimeWarning.js";
  17. import PolylineGeometry from "../Core/PolylineGeometry.js";
  18. import PolylinePipeline from "../Core/PolylinePipeline.js";
  19. import ShowGeometryInstanceAttribute from "../Core/ShowGeometryInstanceAttribute.js";
  20. import Entity from "../DataSources/Entity.js";
  21. import ClassificationType from "../Scene/ClassificationType.js";
  22. import GroundPolylinePrimitive from "../Scene/GroundPolylinePrimitive.js";
  23. import PolylineCollection from "../Scene/PolylineCollection.js";
  24. import PolylineColorAppearance from "../Scene/PolylineColorAppearance.js";
  25. import PolylineMaterialAppearance from "../Scene/PolylineMaterialAppearance.js";
  26. import ShadowMode from "../Scene/ShadowMode.js";
  27. import BoundingSphereState from "./BoundingSphereState.js";
  28. import ColorMaterialProperty from "./ColorMaterialProperty.js";
  29. import ConstantProperty from "./ConstantProperty.js";
  30. import MaterialProperty from "./MaterialProperty.js";
  31. import Property from "./Property.js";
  32. const defaultZIndex = new ConstantProperty(0);
  33. //We use this object to create one polyline collection per-scene.
  34. const polylineCollections = {};
  35. const scratchColor = new Color();
  36. const defaultMaterial = new ColorMaterialProperty(Color.WHITE);
  37. const defaultShow = new ConstantProperty(true);
  38. const defaultShadows = new ConstantProperty(ShadowMode.DISABLED);
  39. const defaultDistanceDisplayCondition = new ConstantProperty(
  40. new DistanceDisplayCondition()
  41. );
  42. const defaultClassificationType = new ConstantProperty(ClassificationType.BOTH);
  43. function GeometryOptions() {
  44. this.vertexFormat = undefined;
  45. this.positions = undefined;
  46. this.width = undefined;
  47. this.arcType = undefined;
  48. this.granularity = undefined;
  49. }
  50. function GroundGeometryOptions() {
  51. this.positions = undefined;
  52. this.width = undefined;
  53. this.arcType = undefined;
  54. this.granularity = undefined;
  55. }
  56. /**
  57. * A {@link GeometryUpdater} for polylines.
  58. * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}.
  59. * @alias PolylineGeometryUpdater
  60. * @constructor
  61. *
  62. * @param {Entity} entity The entity containing the geometry to be visualized.
  63. * @param {Scene} scene The scene where visualization is taking place.
  64. */
  65. function PolylineGeometryUpdater(entity, scene) {
  66. //>>includeStart('debug', pragmas.debug);
  67. if (!defined(entity)) {
  68. throw new DeveloperError("entity is required");
  69. }
  70. if (!defined(scene)) {
  71. throw new DeveloperError("scene is required");
  72. }
  73. //>>includeEnd('debug');
  74. this._entity = entity;
  75. this._scene = scene;
  76. this._entitySubscription = entity.definitionChanged.addEventListener(
  77. PolylineGeometryUpdater.prototype._onEntityPropertyChanged,
  78. this
  79. );
  80. this._fillEnabled = false;
  81. this._dynamic = false;
  82. this._geometryChanged = new Event();
  83. this._showProperty = undefined;
  84. this._materialProperty = undefined;
  85. this._shadowsProperty = undefined;
  86. this._distanceDisplayConditionProperty = undefined;
  87. this._classificationTypeProperty = undefined;
  88. this._depthFailMaterialProperty = undefined;
  89. this._geometryOptions = new GeometryOptions();
  90. this._groundGeometryOptions = new GroundGeometryOptions();
  91. this._id = `polyline-${entity.id}`;
  92. this._clampToGround = false;
  93. this._supportsPolylinesOnTerrain = Entity.supportsPolylinesOnTerrain(scene);
  94. this._zIndex = 0;
  95. this._onEntityPropertyChanged(entity, "polyline", entity.polyline, undefined);
  96. }
  97. Object.defineProperties(PolylineGeometryUpdater.prototype, {
  98. /**
  99. * Gets the unique ID associated with this updater
  100. * @memberof PolylineGeometryUpdater.prototype
  101. * @type {String}
  102. * @readonly
  103. */
  104. id: {
  105. get: function () {
  106. return this._id;
  107. },
  108. },
  109. /**
  110. * Gets the entity associated with this geometry.
  111. * @memberof PolylineGeometryUpdater.prototype
  112. *
  113. * @type {Entity}
  114. * @readonly
  115. */
  116. entity: {
  117. get: function () {
  118. return this._entity;
  119. },
  120. },
  121. /**
  122. * Gets a value indicating if the geometry has a fill component.
  123. * @memberof PolylineGeometryUpdater.prototype
  124. *
  125. * @type {Boolean}
  126. * @readonly
  127. */
  128. fillEnabled: {
  129. get: function () {
  130. return this._fillEnabled;
  131. },
  132. },
  133. /**
  134. * Gets a value indicating if fill visibility varies with simulation time.
  135. * @memberof PolylineGeometryUpdater.prototype
  136. *
  137. * @type {Boolean}
  138. * @readonly
  139. */
  140. hasConstantFill: {
  141. get: function () {
  142. return (
  143. !this._fillEnabled ||
  144. (!defined(this._entity.availability) &&
  145. Property.isConstant(this._showProperty))
  146. );
  147. },
  148. },
  149. /**
  150. * Gets the material property used to fill the geometry.
  151. * @memberof PolylineGeometryUpdater.prototype
  152. *
  153. * @type {MaterialProperty}
  154. * @readonly
  155. */
  156. fillMaterialProperty: {
  157. get: function () {
  158. return this._materialProperty;
  159. },
  160. },
  161. /**
  162. * Gets the material property used to fill the geometry when it fails the depth test.
  163. * @memberof PolylineGeometryUpdater.prototype
  164. *
  165. * @type {MaterialProperty}
  166. * @readonly
  167. */
  168. depthFailMaterialProperty: {
  169. get: function () {
  170. return this._depthFailMaterialProperty;
  171. },
  172. },
  173. /**
  174. * Gets a value indicating if the geometry has an outline component.
  175. * @memberof PolylineGeometryUpdater.prototype
  176. *
  177. * @type {Boolean}
  178. * @readonly
  179. */
  180. outlineEnabled: {
  181. value: false,
  182. },
  183. /**
  184. * Gets a value indicating if outline visibility varies with simulation time.
  185. * @memberof PolylineGeometryUpdater.prototype
  186. *
  187. * @type {Boolean}
  188. * @readonly
  189. */
  190. hasConstantOutline: {
  191. value: true,
  192. },
  193. /**
  194. * Gets the {@link Color} property for the geometry outline.
  195. * @memberof PolylineGeometryUpdater.prototype
  196. *
  197. * @type {Property}
  198. * @readonly
  199. */
  200. outlineColorProperty: {
  201. value: undefined,
  202. },
  203. /**
  204. * Gets the property specifying whether the geometry
  205. * casts or receives shadows from light sources.
  206. * @memberof PolylineGeometryUpdater.prototype
  207. *
  208. * @type {Property}
  209. * @readonly
  210. */
  211. shadowsProperty: {
  212. get: function () {
  213. return this._shadowsProperty;
  214. },
  215. },
  216. /**
  217. * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed.
  218. * @memberof PolylineGeometryUpdater.prototype
  219. *
  220. * @type {Property}
  221. * @readonly
  222. */
  223. distanceDisplayConditionProperty: {
  224. get: function () {
  225. return this._distanceDisplayConditionProperty;
  226. },
  227. },
  228. /**
  229. * Gets or sets the {@link ClassificationType} Property specifying if this geometry will classify terrain, 3D Tiles, or both when on the ground.
  230. * @memberof PolylineGeometryUpdater.prototype
  231. *
  232. * @type {Property}
  233. * @readonly
  234. */
  235. classificationTypeProperty: {
  236. get: function () {
  237. return this._classificationTypeProperty;
  238. },
  239. },
  240. /**
  241. * Gets a value indicating if the geometry is time-varying.
  242. * If true, all visualization is delegated to the {@link DynamicGeometryUpdater}
  243. * returned by GeometryUpdater#createDynamicUpdater.
  244. * @memberof PolylineGeometryUpdater.prototype
  245. *
  246. * @type {Boolean}
  247. * @readonly
  248. */
  249. isDynamic: {
  250. get: function () {
  251. return this._dynamic;
  252. },
  253. },
  254. /**
  255. * Gets a value indicating if the geometry is closed.
  256. * This property is only valid for static geometry.
  257. * @memberof PolylineGeometryUpdater.prototype
  258. *
  259. * @type {Boolean}
  260. * @readonly
  261. */
  262. isClosed: {
  263. value: false,
  264. },
  265. /**
  266. * Gets an event that is raised whenever the public properties
  267. * of this updater change.
  268. * @memberof PolylineGeometryUpdater.prototype
  269. *
  270. * @type {Boolean}
  271. * @readonly
  272. */
  273. geometryChanged: {
  274. get: function () {
  275. return this._geometryChanged;
  276. },
  277. },
  278. /**
  279. * Gets a value indicating if the path of the line.
  280. * @memberof PolylineGeometryUpdater.prototype
  281. *
  282. * @type {ArcType}
  283. * @readonly
  284. */
  285. arcType: {
  286. get: function () {
  287. return this._arcType;
  288. },
  289. },
  290. /**
  291. * Gets a value indicating if the geometry is clamped to the ground.
  292. * Returns false if polylines on terrain is not supported.
  293. * @memberof PolylineGeometryUpdater.prototype
  294. *
  295. * @type {Boolean}
  296. * @readonly
  297. */
  298. clampToGround: {
  299. get: function () {
  300. return this._clampToGround && this._supportsPolylinesOnTerrain;
  301. },
  302. },
  303. /**
  304. * Gets the zindex
  305. * @type {Number}
  306. * @memberof PolylineGeometryUpdater.prototype
  307. * @readonly
  308. */
  309. zIndex: {
  310. get: function () {
  311. return this._zIndex;
  312. },
  313. },
  314. });
  315. /**
  316. * Checks if the geometry is outlined at the provided time.
  317. *
  318. * @param {JulianDate} time The time for which to retrieve visibility.
  319. * @returns {Boolean} true if geometry is outlined at the provided time, false otherwise.
  320. */
  321. PolylineGeometryUpdater.prototype.isOutlineVisible = function (time) {
  322. return false;
  323. };
  324. /**
  325. * Checks if the geometry is filled at the provided time.
  326. *
  327. * @param {JulianDate} time The time for which to retrieve visibility.
  328. * @returns {Boolean} true if geometry is filled at the provided time, false otherwise.
  329. */
  330. PolylineGeometryUpdater.prototype.isFilled = function (time) {
  331. const entity = this._entity;
  332. const visible =
  333. this._fillEnabled &&
  334. entity.isAvailable(time) &&
  335. this._showProperty.getValue(time);
  336. return defaultValue(visible, false);
  337. };
  338. /**
  339. * Creates the geometry instance which represents the fill of the geometry.
  340. *
  341. * @param {JulianDate} time The time to use when retrieving initial attribute values.
  342. * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry.
  343. *
  344. * @exception {DeveloperError} This instance does not represent a filled geometry.
  345. */
  346. PolylineGeometryUpdater.prototype.createFillGeometryInstance = function (time) {
  347. //>>includeStart('debug', pragmas.debug);
  348. if (!defined(time)) {
  349. throw new DeveloperError("time is required.");
  350. }
  351. if (!this._fillEnabled) {
  352. throw new DeveloperError(
  353. "This instance does not represent a filled geometry."
  354. );
  355. }
  356. //>>includeEnd('debug');
  357. const entity = this._entity;
  358. const isAvailable = entity.isAvailable(time);
  359. const show = new ShowGeometryInstanceAttribute(
  360. isAvailable && entity.isShowing && this._showProperty.getValue(time)
  361. );
  362. const distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(
  363. time
  364. );
  365. const distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(
  366. distanceDisplayCondition
  367. );
  368. const attributes = {
  369. show: show,
  370. distanceDisplayCondition: distanceDisplayConditionAttribute,
  371. };
  372. let currentColor;
  373. if (this._materialProperty instanceof ColorMaterialProperty) {
  374. if (
  375. defined(this._materialProperty.color) &&
  376. (this._materialProperty.color.isConstant || isAvailable)
  377. ) {
  378. currentColor = this._materialProperty.color.getValue(time, scratchColor);
  379. }
  380. if (!defined(currentColor)) {
  381. currentColor = Color.WHITE;
  382. }
  383. attributes.color = ColorGeometryInstanceAttribute.fromColor(currentColor);
  384. }
  385. if (this.clampToGround) {
  386. return new GeometryInstance({
  387. id: entity,
  388. geometry: new GroundPolylineGeometry(this._groundGeometryOptions),
  389. attributes: attributes,
  390. });
  391. }
  392. if (
  393. defined(this._depthFailMaterialProperty) &&
  394. this._depthFailMaterialProperty instanceof ColorMaterialProperty
  395. ) {
  396. if (
  397. defined(this._depthFailMaterialProperty.color) &&
  398. (this._depthFailMaterialProperty.color.isConstant || isAvailable)
  399. ) {
  400. currentColor = this._depthFailMaterialProperty.color.getValue(
  401. time,
  402. scratchColor
  403. );
  404. }
  405. if (!defined(currentColor)) {
  406. currentColor = Color.WHITE;
  407. }
  408. attributes.depthFailColor = ColorGeometryInstanceAttribute.fromColor(
  409. currentColor
  410. );
  411. }
  412. return new GeometryInstance({
  413. id: entity,
  414. geometry: new PolylineGeometry(this._geometryOptions),
  415. attributes: attributes,
  416. });
  417. };
  418. /**
  419. * Creates the geometry instance which represents the outline of the geometry.
  420. *
  421. * @param {JulianDate} time The time to use when retrieving initial attribute values.
  422. * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry.
  423. *
  424. * @exception {DeveloperError} This instance does not represent an outlined geometry.
  425. */
  426. PolylineGeometryUpdater.prototype.createOutlineGeometryInstance = function (
  427. time
  428. ) {
  429. //>>includeStart('debug', pragmas.debug);
  430. throw new DeveloperError(
  431. "This instance does not represent an outlined geometry."
  432. );
  433. //>>includeEnd('debug');
  434. };
  435. /**
  436. * Returns true if this object was destroyed; otherwise, false.
  437. *
  438. * @returns {Boolean} True if this object was destroyed; otherwise, false.
  439. */
  440. PolylineGeometryUpdater.prototype.isDestroyed = function () {
  441. return false;
  442. };
  443. /**
  444. * Destroys and resources used by the object. Once an object is destroyed, it should not be used.
  445. *
  446. * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
  447. */
  448. PolylineGeometryUpdater.prototype.destroy = function () {
  449. this._entitySubscription();
  450. destroyObject(this);
  451. };
  452. PolylineGeometryUpdater.prototype._onEntityPropertyChanged = function (
  453. entity,
  454. propertyName,
  455. newValue,
  456. oldValue
  457. ) {
  458. if (!(propertyName === "availability" || propertyName === "polyline")) {
  459. return;
  460. }
  461. const polyline = this._entity.polyline;
  462. if (!defined(polyline)) {
  463. if (this._fillEnabled) {
  464. this._fillEnabled = false;
  465. this._geometryChanged.raiseEvent(this);
  466. }
  467. return;
  468. }
  469. const positionsProperty = polyline.positions;
  470. const show = polyline.show;
  471. if (
  472. (defined(show) &&
  473. show.isConstant &&
  474. !show.getValue(Iso8601.MINIMUM_VALUE)) || //
  475. !defined(positionsProperty)
  476. ) {
  477. if (this._fillEnabled) {
  478. this._fillEnabled = false;
  479. this._geometryChanged.raiseEvent(this);
  480. }
  481. return;
  482. }
  483. const zIndex = polyline.zIndex;
  484. const material = defaultValue(polyline.material, defaultMaterial);
  485. const isColorMaterial = material instanceof ColorMaterialProperty;
  486. this._materialProperty = material;
  487. this._depthFailMaterialProperty = polyline.depthFailMaterial;
  488. this._showProperty = defaultValue(show, defaultShow);
  489. this._shadowsProperty = defaultValue(polyline.shadows, defaultShadows);
  490. this._distanceDisplayConditionProperty = defaultValue(
  491. polyline.distanceDisplayCondition,
  492. defaultDistanceDisplayCondition
  493. );
  494. this._classificationTypeProperty = defaultValue(
  495. polyline.classificationType,
  496. defaultClassificationType
  497. );
  498. this._fillEnabled = true;
  499. this._zIndex = defaultValue(zIndex, defaultZIndex);
  500. const width = polyline.width;
  501. const arcType = polyline.arcType;
  502. const clampToGround = polyline.clampToGround;
  503. const granularity = polyline.granularity;
  504. if (
  505. !positionsProperty.isConstant ||
  506. !Property.isConstant(width) ||
  507. !Property.isConstant(arcType) ||
  508. !Property.isConstant(granularity) ||
  509. !Property.isConstant(clampToGround) ||
  510. !Property.isConstant(zIndex)
  511. ) {
  512. if (!this._dynamic) {
  513. this._dynamic = true;
  514. this._geometryChanged.raiseEvent(this);
  515. }
  516. } else {
  517. const geometryOptions = this._geometryOptions;
  518. const positions = positionsProperty.getValue(
  519. Iso8601.MINIMUM_VALUE,
  520. geometryOptions.positions
  521. );
  522. //Because of the way we currently handle reference properties,
  523. //we can't automatically assume the positions are always valid.
  524. if (!defined(positions) || positions.length < 2) {
  525. if (this._fillEnabled) {
  526. this._fillEnabled = false;
  527. this._geometryChanged.raiseEvent(this);
  528. }
  529. return;
  530. }
  531. let vertexFormat;
  532. if (
  533. isColorMaterial &&
  534. (!defined(this._depthFailMaterialProperty) ||
  535. this._depthFailMaterialProperty instanceof ColorMaterialProperty)
  536. ) {
  537. vertexFormat = PolylineColorAppearance.VERTEX_FORMAT;
  538. } else {
  539. vertexFormat = PolylineMaterialAppearance.VERTEX_FORMAT;
  540. }
  541. geometryOptions.vertexFormat = vertexFormat;
  542. geometryOptions.positions = positions;
  543. geometryOptions.width = defined(width)
  544. ? width.getValue(Iso8601.MINIMUM_VALUE)
  545. : undefined;
  546. geometryOptions.arcType = defined(arcType)
  547. ? arcType.getValue(Iso8601.MINIMUM_VALUE)
  548. : undefined;
  549. geometryOptions.granularity = defined(granularity)
  550. ? granularity.getValue(Iso8601.MINIMUM_VALUE)
  551. : undefined;
  552. const groundGeometryOptions = this._groundGeometryOptions;
  553. groundGeometryOptions.positions = positions;
  554. groundGeometryOptions.width = geometryOptions.width;
  555. groundGeometryOptions.arcType = geometryOptions.arcType;
  556. groundGeometryOptions.granularity = geometryOptions.granularity;
  557. this._clampToGround = defined(clampToGround)
  558. ? clampToGround.getValue(Iso8601.MINIMUM_VALUE)
  559. : false;
  560. if (!this._clampToGround && defined(zIndex)) {
  561. oneTimeWarning(
  562. "Entity polylines must have clampToGround: true when using zIndex. zIndex will be ignored."
  563. );
  564. }
  565. this._dynamic = false;
  566. this._geometryChanged.raiseEvent(this);
  567. }
  568. };
  569. /**
  570. * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true.
  571. *
  572. * @param {PrimitiveCollection} primitives The primitive collection to use.
  573. * @param {PrimitiveCollection|OrderedGroundPrimitiveCollection} groundPrimitives The primitive collection to use for ordered ground primitives.
  574. * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame.
  575. *
  576. * @exception {DeveloperError} This instance does not represent dynamic geometry.
  577. * @private
  578. */
  579. PolylineGeometryUpdater.prototype.createDynamicUpdater = function (
  580. primitives,
  581. groundPrimitives
  582. ) {
  583. //>>includeStart('debug', pragmas.debug);
  584. Check.defined("primitives", primitives);
  585. Check.defined("groundPrimitives", groundPrimitives);
  586. if (!this._dynamic) {
  587. throw new DeveloperError(
  588. "This instance does not represent dynamic geometry."
  589. );
  590. }
  591. //>>includeEnd('debug');
  592. return new DynamicGeometryUpdater(primitives, groundPrimitives, this);
  593. };
  594. /**
  595. * @private
  596. */
  597. const generateCartesianArcOptions = {
  598. positions: undefined,
  599. granularity: undefined,
  600. height: undefined,
  601. ellipsoid: undefined,
  602. };
  603. function DynamicGeometryUpdater(primitives, groundPrimitives, geometryUpdater) {
  604. this._line = undefined;
  605. this._primitives = primitives;
  606. this._groundPrimitives = groundPrimitives;
  607. this._groundPolylinePrimitive = undefined;
  608. this._material = undefined;
  609. this._geometryUpdater = geometryUpdater;
  610. this._positions = [];
  611. }
  612. function getLine(dynamicGeometryUpdater) {
  613. if (defined(dynamicGeometryUpdater._line)) {
  614. return dynamicGeometryUpdater._line;
  615. }
  616. const sceneId = dynamicGeometryUpdater._geometryUpdater._scene.id;
  617. let polylineCollection = polylineCollections[sceneId];
  618. const primitives = dynamicGeometryUpdater._primitives;
  619. if (!defined(polylineCollection) || polylineCollection.isDestroyed()) {
  620. polylineCollection = new PolylineCollection();
  621. polylineCollections[sceneId] = polylineCollection;
  622. primitives.add(polylineCollection);
  623. } else if (!primitives.contains(polylineCollection)) {
  624. primitives.add(polylineCollection);
  625. }
  626. const line = polylineCollection.add();
  627. line.id = dynamicGeometryUpdater._geometryUpdater._entity;
  628. dynamicGeometryUpdater._line = line;
  629. return line;
  630. }
  631. DynamicGeometryUpdater.prototype.update = function (time) {
  632. const geometryUpdater = this._geometryUpdater;
  633. const entity = geometryUpdater._entity;
  634. const polyline = entity.polyline;
  635. const positionsProperty = polyline.positions;
  636. let positions = Property.getValueOrUndefined(
  637. positionsProperty,
  638. time,
  639. this._positions
  640. );
  641. // Synchronize with geometryUpdater for GroundPolylinePrimitive
  642. geometryUpdater._clampToGround = Property.getValueOrDefault(
  643. polyline._clampToGround,
  644. time,
  645. false
  646. );
  647. geometryUpdater._groundGeometryOptions.positions = positions;
  648. geometryUpdater._groundGeometryOptions.width = Property.getValueOrDefault(
  649. polyline._width,
  650. time,
  651. 1
  652. );
  653. geometryUpdater._groundGeometryOptions.arcType = Property.getValueOrDefault(
  654. polyline._arcType,
  655. time,
  656. ArcType.GEODESIC
  657. );
  658. geometryUpdater._groundGeometryOptions.granularity = Property.getValueOrDefault(
  659. polyline._granularity,
  660. time,
  661. 9999
  662. );
  663. const groundPrimitives = this._groundPrimitives;
  664. if (defined(this._groundPolylinePrimitive)) {
  665. groundPrimitives.remove(this._groundPolylinePrimitive); // destroys by default
  666. this._groundPolylinePrimitive = undefined;
  667. }
  668. if (geometryUpdater.clampToGround) {
  669. if (
  670. !entity.isShowing ||
  671. !entity.isAvailable(time) ||
  672. !Property.getValueOrDefault(polyline._show, time, true)
  673. ) {
  674. return;
  675. }
  676. if (!defined(positions) || positions.length < 2) {
  677. return;
  678. }
  679. const fillMaterialProperty = geometryUpdater.fillMaterialProperty;
  680. let appearance;
  681. if (fillMaterialProperty instanceof ColorMaterialProperty) {
  682. appearance = new PolylineColorAppearance();
  683. } else {
  684. const material = MaterialProperty.getValue(
  685. time,
  686. fillMaterialProperty,
  687. this._material
  688. );
  689. appearance = new PolylineMaterialAppearance({
  690. material: material,
  691. translucent: material.isTranslucent(),
  692. });
  693. this._material = material;
  694. }
  695. this._groundPolylinePrimitive = groundPrimitives.add(
  696. new GroundPolylinePrimitive({
  697. geometryInstances: geometryUpdater.createFillGeometryInstance(time),
  698. appearance: appearance,
  699. classificationType: geometryUpdater.classificationTypeProperty.getValue(
  700. time
  701. ),
  702. asynchronous: false,
  703. }),
  704. Property.getValueOrUndefined(geometryUpdater.zIndex, time)
  705. );
  706. // Hide the polyline in the collection, if any
  707. if (defined(this._line)) {
  708. this._line.show = false;
  709. }
  710. return;
  711. }
  712. const line = getLine(this);
  713. if (
  714. !entity.isShowing ||
  715. !entity.isAvailable(time) ||
  716. !Property.getValueOrDefault(polyline._show, time, true)
  717. ) {
  718. line.show = false;
  719. return;
  720. }
  721. if (!defined(positions) || positions.length < 2) {
  722. line.show = false;
  723. return;
  724. }
  725. let arcType = ArcType.GEODESIC;
  726. arcType = Property.getValueOrDefault(polyline._arcType, time, arcType);
  727. const globe = geometryUpdater._scene.globe;
  728. if (arcType !== ArcType.NONE && defined(globe)) {
  729. generateCartesianArcOptions.ellipsoid = globe.ellipsoid;
  730. generateCartesianArcOptions.positions = positions;
  731. generateCartesianArcOptions.granularity = Property.getValueOrUndefined(
  732. polyline._granularity,
  733. time
  734. );
  735. generateCartesianArcOptions.height = PolylinePipeline.extractHeights(
  736. positions,
  737. globe.ellipsoid
  738. );
  739. if (arcType === ArcType.GEODESIC) {
  740. positions = PolylinePipeline.generateCartesianArc(
  741. generateCartesianArcOptions
  742. );
  743. } else {
  744. positions = PolylinePipeline.generateCartesianRhumbArc(
  745. generateCartesianArcOptions
  746. );
  747. }
  748. }
  749. line.show = true;
  750. line.positions = positions.slice();
  751. line.material = MaterialProperty.getValue(
  752. time,
  753. geometryUpdater.fillMaterialProperty,
  754. line.material
  755. );
  756. line.width = Property.getValueOrDefault(polyline._width, time, 1);
  757. line.distanceDisplayCondition = Property.getValueOrUndefined(
  758. polyline._distanceDisplayCondition,
  759. time,
  760. line.distanceDisplayCondition
  761. );
  762. };
  763. DynamicGeometryUpdater.prototype.getBoundingSphere = function (result) {
  764. //>>includeStart('debug', pragmas.debug);
  765. Check.defined("result", result);
  766. //>>includeEnd('debug');
  767. if (!this._geometryUpdater.clampToGround) {
  768. const line = getLine(this);
  769. if (line.show && line.positions.length > 0) {
  770. BoundingSphere.fromPoints(line.positions, result);
  771. return BoundingSphereState.DONE;
  772. }
  773. } else {
  774. const groundPolylinePrimitive = this._groundPolylinePrimitive;
  775. if (
  776. defined(groundPolylinePrimitive) &&
  777. groundPolylinePrimitive.show &&
  778. groundPolylinePrimitive.ready
  779. ) {
  780. const attributes = groundPolylinePrimitive.getGeometryInstanceAttributes(
  781. this._geometryUpdater._entity
  782. );
  783. if (defined(attributes) && defined(attributes.boundingSphere)) {
  784. BoundingSphere.clone(attributes.boundingSphere, result);
  785. return BoundingSphereState.DONE;
  786. }
  787. }
  788. if (defined(groundPolylinePrimitive) && !groundPolylinePrimitive.ready) {
  789. return BoundingSphereState.PENDING;
  790. }
  791. return BoundingSphereState.DONE;
  792. }
  793. return BoundingSphereState.FAILED;
  794. };
  795. DynamicGeometryUpdater.prototype.isDestroyed = function () {
  796. return false;
  797. };
  798. DynamicGeometryUpdater.prototype.destroy = function () {
  799. const geometryUpdater = this._geometryUpdater;
  800. const sceneId = geometryUpdater._scene.id;
  801. const polylineCollection = polylineCollections[sceneId];
  802. if (defined(polylineCollection)) {
  803. polylineCollection.remove(this._line);
  804. if (polylineCollection.length === 0) {
  805. this._primitives.removeAndDestroy(polylineCollection);
  806. delete polylineCollections[sceneId];
  807. }
  808. }
  809. if (defined(this._groundPolylinePrimitive)) {
  810. this._groundPrimitives.remove(this._groundPolylinePrimitive);
  811. }
  812. destroyObject(this);
  813. };
  814. export default PolylineGeometryUpdater;