智慧水务管理系统 - 精河县供水工程综合管理平台

EllipsoidGeometryUpdater.js 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. import Cartesian3 from "../Core/Cartesian3.js";
  2. import Check from "../Core/Check.js";
  3. import Color from "../Core/Color.js";
  4. import ColorGeometryInstanceAttribute from "../Core/ColorGeometryInstanceAttribute.js";
  5. import defined from "../Core/defined.js";
  6. import DistanceDisplayCondition from "../Core/DistanceDisplayCondition.js";
  7. import DistanceDisplayConditionGeometryInstanceAttribute from "../Core/DistanceDisplayConditionGeometryInstanceAttribute.js";
  8. import EllipsoidGeometry from "../Core/EllipsoidGeometry.js";
  9. import EllipsoidOutlineGeometry from "../Core/EllipsoidOutlineGeometry.js";
  10. import GeometryInstance from "../Core/GeometryInstance.js";
  11. import GeometryOffsetAttribute from "../Core/GeometryOffsetAttribute.js";
  12. import Iso8601 from "../Core/Iso8601.js";
  13. import Matrix4 from "../Core/Matrix4.js";
  14. import OffsetGeometryInstanceAttribute from "../Core/OffsetGeometryInstanceAttribute.js";
  15. import ShowGeometryInstanceAttribute from "../Core/ShowGeometryInstanceAttribute.js";
  16. import HeightReference from "../Scene/HeightReference.js";
  17. import MaterialAppearance from "../Scene/MaterialAppearance.js";
  18. import PerInstanceColorAppearance from "../Scene/PerInstanceColorAppearance.js";
  19. import Primitive from "../Scene/Primitive.js";
  20. import SceneMode from "../Scene/SceneMode.js";
  21. import ColorMaterialProperty from "./ColorMaterialProperty.js";
  22. import DynamicGeometryUpdater from "./DynamicGeometryUpdater.js";
  23. import GeometryUpdater from "./GeometryUpdater.js";
  24. import heightReferenceOnEntityPropertyChanged from "./heightReferenceOnEntityPropertyChanged.js";
  25. import MaterialProperty from "./MaterialProperty.js";
  26. import Property from "./Property.js";
  27. const defaultMaterial = new ColorMaterialProperty(Color.WHITE);
  28. const defaultOffset = Cartesian3.ZERO;
  29. const offsetScratch = new Cartesian3();
  30. const radiiScratch = new Cartesian3();
  31. const innerRadiiScratch = new Cartesian3();
  32. const scratchColor = new Color();
  33. const unitSphere = new Cartesian3(1, 1, 1);
  34. function EllipsoidGeometryOptions(entity) {
  35. this.id = entity;
  36. this.vertexFormat = undefined;
  37. this.radii = undefined;
  38. this.innerRadii = undefined;
  39. this.minimumClock = undefined;
  40. this.maximumClock = undefined;
  41. this.minimumCone = undefined;
  42. this.maximumCone = undefined;
  43. this.stackPartitions = undefined;
  44. this.slicePartitions = undefined;
  45. this.subdivisions = undefined;
  46. this.offsetAttribute = undefined;
  47. }
  48. /**
  49. * A {@link GeometryUpdater} for ellipsoids.
  50. * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}.
  51. * @alias EllipsoidGeometryUpdater
  52. * @constructor
  53. *
  54. * @param {Entity} entity The entity containing the geometry to be visualized.
  55. * @param {Scene} scene The scene where visualization is taking place.
  56. */
  57. function EllipsoidGeometryUpdater(entity, scene) {
  58. GeometryUpdater.call(this, {
  59. entity: entity,
  60. scene: scene,
  61. geometryOptions: new EllipsoidGeometryOptions(entity),
  62. geometryPropertyName: "ellipsoid",
  63. observedPropertyNames: [
  64. "availability",
  65. "position",
  66. "orientation",
  67. "ellipsoid",
  68. ],
  69. });
  70. this._onEntityPropertyChanged(
  71. entity,
  72. "ellipsoid",
  73. entity.ellipsoid,
  74. undefined,
  75. );
  76. }
  77. if (defined(Object.create)) {
  78. EllipsoidGeometryUpdater.prototype = Object.create(GeometryUpdater.prototype);
  79. EllipsoidGeometryUpdater.prototype.constructor = EllipsoidGeometryUpdater;
  80. }
  81. Object.defineProperties(EllipsoidGeometryUpdater.prototype, {
  82. /**
  83. * Gets the terrain offset property
  84. * @type {TerrainOffsetProperty}
  85. * @memberof EllipsoidGeometryUpdater.prototype
  86. * @readonly
  87. * @private
  88. */
  89. terrainOffsetProperty: {
  90. get: function () {
  91. return this._terrainOffsetProperty;
  92. },
  93. },
  94. });
  95. /**
  96. * Creates the geometry instance which represents the fill of the geometry.
  97. *
  98. * @param {JulianDate} time The time to use when retrieving initial attribute values.
  99. * @param {boolean} [skipModelMatrix=false] Whether to compute a model matrix for the geometry instance
  100. * @param {Matrix4} [modelMatrixResult] Used to store the result of the model matrix calculation
  101. * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry.
  102. *
  103. * @exception {DeveloperError} This instance does not represent a filled geometry.
  104. */
  105. EllipsoidGeometryUpdater.prototype.createFillGeometryInstance = function (
  106. time,
  107. skipModelMatrix,
  108. modelMatrixResult,
  109. ) {
  110. //>>includeStart('debug', pragmas.debug);
  111. Check.defined("time", time);
  112. //>>includeEnd('debug');
  113. const entity = this._entity;
  114. const isAvailable = entity.isAvailable(time);
  115. let color;
  116. const show = new ShowGeometryInstanceAttribute(
  117. isAvailable &&
  118. entity.isShowing &&
  119. this._showProperty.getValue(time) &&
  120. this._fillProperty.getValue(time),
  121. );
  122. const distanceDisplayCondition =
  123. this._distanceDisplayConditionProperty.getValue(time);
  124. const distanceDisplayConditionAttribute =
  125. DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(
  126. distanceDisplayCondition,
  127. );
  128. const attributes = {
  129. show: show,
  130. distanceDisplayCondition: distanceDisplayConditionAttribute,
  131. color: undefined,
  132. offset: undefined,
  133. };
  134. if (this._materialProperty instanceof ColorMaterialProperty) {
  135. let currentColor;
  136. if (
  137. defined(this._materialProperty.color) &&
  138. (this._materialProperty.color.isConstant || isAvailable)
  139. ) {
  140. currentColor = this._materialProperty.color.getValue(time, scratchColor);
  141. }
  142. if (!defined(currentColor)) {
  143. currentColor = Color.WHITE;
  144. }
  145. color = ColorGeometryInstanceAttribute.fromColor(currentColor);
  146. attributes.color = color;
  147. }
  148. if (defined(this._options.offsetAttribute)) {
  149. attributes.offset = OffsetGeometryInstanceAttribute.fromCartesian3(
  150. Property.getValueOrDefault(
  151. this._terrainOffsetProperty,
  152. time,
  153. defaultOffset,
  154. offsetScratch,
  155. ),
  156. );
  157. }
  158. return new GeometryInstance({
  159. id: entity,
  160. geometry: new EllipsoidGeometry(this._options),
  161. modelMatrix: skipModelMatrix
  162. ? undefined
  163. : entity.computeModelMatrixForHeightReference(
  164. time,
  165. entity.ellipsoid.heightReference,
  166. this._options.radii.z * 0.5,
  167. this._scene.ellipsoid,
  168. modelMatrixResult,
  169. ),
  170. attributes: attributes,
  171. });
  172. };
  173. /**
  174. * Creates the geometry instance which represents the outline of the geometry.
  175. *
  176. * @param {JulianDate} time The time to use when retrieving initial attribute values.
  177. * @param {boolean} [skipModelMatrix=false] Whether to compute a model matrix for the geometry instance
  178. * @param {Matrix4} [modelMatrixResult] Used to store the result of the model matrix calculation
  179. * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry.
  180. *
  181. * @exception {DeveloperError} This instance does not represent an outlined geometry.
  182. */
  183. EllipsoidGeometryUpdater.prototype.createOutlineGeometryInstance = function (
  184. time,
  185. skipModelMatrix,
  186. modelMatrixResult,
  187. ) {
  188. //>>includeStart('debug', pragmas.debug);
  189. Check.defined("time", time);
  190. //>>includeEnd('debug');
  191. const entity = this._entity;
  192. const isAvailable = entity.isAvailable(time);
  193. const outlineColor = Property.getValueOrDefault(
  194. this._outlineColorProperty,
  195. time,
  196. Color.BLACK,
  197. scratchColor,
  198. );
  199. const distanceDisplayCondition =
  200. this._distanceDisplayConditionProperty.getValue(time);
  201. const attributes = {
  202. show: new ShowGeometryInstanceAttribute(
  203. isAvailable &&
  204. entity.isShowing &&
  205. this._showProperty.getValue(time) &&
  206. this._showOutlineProperty.getValue(time),
  207. ),
  208. color: ColorGeometryInstanceAttribute.fromColor(outlineColor),
  209. distanceDisplayCondition:
  210. DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(
  211. distanceDisplayCondition,
  212. ),
  213. offset: undefined,
  214. };
  215. if (defined(this._options.offsetAttribute)) {
  216. attributes.offset = OffsetGeometryInstanceAttribute.fromCartesian3(
  217. Property.getValueOrDefault(
  218. this._terrainOffsetProperty,
  219. time,
  220. defaultOffset,
  221. offsetScratch,
  222. ),
  223. );
  224. }
  225. return new GeometryInstance({
  226. id: entity,
  227. geometry: new EllipsoidOutlineGeometry(this._options),
  228. modelMatrix: skipModelMatrix
  229. ? undefined
  230. : entity.computeModelMatrixForHeightReference(
  231. time,
  232. entity.ellipsoid.heightReference,
  233. this._options.radii.z * 0.5,
  234. this._scene.ellipsoid,
  235. modelMatrixResult,
  236. ),
  237. attributes: attributes,
  238. });
  239. };
  240. EllipsoidGeometryUpdater.prototype._computeCenter = function (time, result) {
  241. return Property.getValueOrUndefined(this._entity.position, time, result);
  242. };
  243. EllipsoidGeometryUpdater.prototype._isHidden = function (entity, ellipsoid) {
  244. return (
  245. !defined(entity.position) ||
  246. !defined(ellipsoid.radii) ||
  247. GeometryUpdater.prototype._isHidden.call(this, entity, ellipsoid)
  248. );
  249. };
  250. EllipsoidGeometryUpdater.prototype._isDynamic = function (entity, ellipsoid) {
  251. return (
  252. !entity.position.isConstant || //
  253. !Property.isConstant(entity.orientation) || //
  254. !ellipsoid.radii.isConstant || //
  255. !Property.isConstant(ellipsoid.innerRadii) || //
  256. !Property.isConstant(ellipsoid.stackPartitions) || //
  257. !Property.isConstant(ellipsoid.slicePartitions) || //
  258. !Property.isConstant(ellipsoid.outlineWidth) || //
  259. !Property.isConstant(ellipsoid.minimumClock) || //
  260. !Property.isConstant(ellipsoid.maximumClock) || //
  261. !Property.isConstant(ellipsoid.minimumCone) || //
  262. !Property.isConstant(ellipsoid.maximumCone) || //
  263. !Property.isConstant(ellipsoid.subdivisions)
  264. );
  265. };
  266. EllipsoidGeometryUpdater.prototype._setStaticOptions = function (
  267. entity,
  268. ellipsoid,
  269. ) {
  270. const heightReference = Property.getValueOrDefault(
  271. ellipsoid.heightReference,
  272. Iso8601.MINIMUM_VALUE,
  273. HeightReference.NONE,
  274. );
  275. const options = this._options;
  276. options.vertexFormat =
  277. this._materialProperty instanceof ColorMaterialProperty
  278. ? PerInstanceColorAppearance.VERTEX_FORMAT
  279. : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat;
  280. options.radii = ellipsoid.radii.getValue(
  281. Iso8601.MINIMUM_VALUE,
  282. options.radii,
  283. );
  284. options.innerRadii = Property.getValueOrUndefined(
  285. ellipsoid.innerRadii,
  286. options.radii,
  287. );
  288. options.minimumClock = Property.getValueOrUndefined(
  289. ellipsoid.minimumClock,
  290. Iso8601.MINIMUM_VALUE,
  291. );
  292. options.maximumClock = Property.getValueOrUndefined(
  293. ellipsoid.maximumClock,
  294. Iso8601.MINIMUM_VALUE,
  295. );
  296. options.minimumCone = Property.getValueOrUndefined(
  297. ellipsoid.minimumCone,
  298. Iso8601.MINIMUM_VALUE,
  299. );
  300. options.maximumCone = Property.getValueOrUndefined(
  301. ellipsoid.maximumCone,
  302. Iso8601.MINIMUM_VALUE,
  303. );
  304. options.stackPartitions = Property.getValueOrUndefined(
  305. ellipsoid.stackPartitions,
  306. Iso8601.MINIMUM_VALUE,
  307. );
  308. options.slicePartitions = Property.getValueOrUndefined(
  309. ellipsoid.slicePartitions,
  310. Iso8601.MINIMUM_VALUE,
  311. );
  312. options.subdivisions = Property.getValueOrUndefined(
  313. ellipsoid.subdivisions,
  314. Iso8601.MINIMUM_VALUE,
  315. );
  316. options.offsetAttribute =
  317. heightReference !== HeightReference.NONE
  318. ? GeometryOffsetAttribute.ALL
  319. : undefined;
  320. };
  321. EllipsoidGeometryUpdater.prototype._onEntityPropertyChanged =
  322. heightReferenceOnEntityPropertyChanged;
  323. EllipsoidGeometryUpdater.DynamicGeometryUpdater =
  324. DynamicEllipsoidGeometryUpdater;
  325. /**
  326. * @private
  327. */
  328. function DynamicEllipsoidGeometryUpdater(
  329. geometryUpdater,
  330. primitives,
  331. groundPrimitives,
  332. ) {
  333. DynamicGeometryUpdater.call(
  334. this,
  335. geometryUpdater,
  336. primitives,
  337. groundPrimitives,
  338. );
  339. this._scene = geometryUpdater._scene;
  340. this._modelMatrix = new Matrix4();
  341. this._attributes = undefined;
  342. this._outlineAttributes = undefined;
  343. this._lastSceneMode = undefined;
  344. this._lastShow = undefined;
  345. this._lastOutlineShow = undefined;
  346. this._lastOutlineWidth = undefined;
  347. this._lastOutlineColor = undefined;
  348. this._lastOffset = new Cartesian3();
  349. this._material = {};
  350. }
  351. if (defined(Object.create)) {
  352. DynamicEllipsoidGeometryUpdater.prototype = Object.create(
  353. DynamicGeometryUpdater.prototype,
  354. );
  355. DynamicEllipsoidGeometryUpdater.prototype.constructor =
  356. DynamicEllipsoidGeometryUpdater;
  357. }
  358. DynamicEllipsoidGeometryUpdater.prototype.update = function (time) {
  359. //>>includeStart('debug', pragmas.debug);
  360. Check.defined("time", time);
  361. //>>includeEnd('debug');
  362. const entity = this._entity;
  363. const ellipsoid = entity.ellipsoid;
  364. if (
  365. !entity.isShowing ||
  366. !entity.isAvailable(time) ||
  367. !Property.getValueOrDefault(ellipsoid.show, time, true)
  368. ) {
  369. if (defined(this._primitive)) {
  370. this._primitive.show = false;
  371. }
  372. if (defined(this._outlinePrimitive)) {
  373. this._outlinePrimitive.show = false;
  374. }
  375. return;
  376. }
  377. const radii = Property.getValueOrUndefined(
  378. ellipsoid.radii,
  379. time,
  380. radiiScratch,
  381. );
  382. let modelMatrix = defined(radii)
  383. ? entity.computeModelMatrixForHeightReference(
  384. time,
  385. ellipsoid.heightReference,
  386. radii.z * 0.5,
  387. this._scene.ellipsoid,
  388. this._modelMatrix,
  389. )
  390. : undefined;
  391. if (!defined(modelMatrix) || !defined(radii)) {
  392. if (defined(this._primitive)) {
  393. this._primitive.show = false;
  394. }
  395. if (defined(this._outlinePrimitive)) {
  396. this._outlinePrimitive.show = false;
  397. }
  398. return;
  399. }
  400. //Compute attributes and material.
  401. const showFill = Property.getValueOrDefault(ellipsoid.fill, time, true);
  402. const showOutline = Property.getValueOrDefault(
  403. ellipsoid.outline,
  404. time,
  405. false,
  406. );
  407. const outlineColor = Property.getValueOrClonedDefault(
  408. ellipsoid.outlineColor,
  409. time,
  410. Color.BLACK,
  411. scratchColor,
  412. );
  413. const material = MaterialProperty.getValue(
  414. time,
  415. ellipsoid.material ?? defaultMaterial,
  416. this._material,
  417. );
  418. // Check properties that could trigger a primitive rebuild.
  419. const innerRadii = Property.getValueOrUndefined(
  420. ellipsoid.innerRadii,
  421. time,
  422. innerRadiiScratch,
  423. );
  424. const minimumClock = Property.getValueOrUndefined(
  425. ellipsoid.minimumClock,
  426. time,
  427. );
  428. const maximumClock = Property.getValueOrUndefined(
  429. ellipsoid.maximumClock,
  430. time,
  431. );
  432. const minimumCone = Property.getValueOrUndefined(ellipsoid.minimumCone, time);
  433. const maximumCone = Property.getValueOrUndefined(ellipsoid.maximumCone, time);
  434. const stackPartitions = Property.getValueOrUndefined(
  435. ellipsoid.stackPartitions,
  436. time,
  437. );
  438. const slicePartitions = Property.getValueOrUndefined(
  439. ellipsoid.slicePartitions,
  440. time,
  441. );
  442. const subdivisions = Property.getValueOrUndefined(
  443. ellipsoid.subdivisions,
  444. time,
  445. );
  446. const outlineWidth = Property.getValueOrDefault(
  447. ellipsoid.outlineWidth,
  448. time,
  449. 1.0,
  450. );
  451. const heightReference = Property.getValueOrDefault(
  452. ellipsoid.heightReference,
  453. time,
  454. HeightReference.NONE,
  455. );
  456. const offsetAttribute =
  457. heightReference !== HeightReference.NONE
  458. ? GeometryOffsetAttribute.ALL
  459. : undefined;
  460. //In 3D we use a fast path by modifying Primitive.modelMatrix instead of regenerating the primitive every frame.
  461. //Also check for height reference because this method doesn't work when the height is relative to terrain.
  462. const sceneMode = this._scene.mode;
  463. const in3D =
  464. sceneMode === SceneMode.SCENE3D && heightReference === HeightReference.NONE;
  465. const options = this._options;
  466. const shadows = this._geometryUpdater.shadowsProperty.getValue(time);
  467. const distanceDisplayConditionProperty =
  468. this._geometryUpdater.distanceDisplayConditionProperty;
  469. const distanceDisplayCondition =
  470. distanceDisplayConditionProperty.getValue(time);
  471. const offset = Property.getValueOrDefault(
  472. this._geometryUpdater.terrainOffsetProperty,
  473. time,
  474. defaultOffset,
  475. offsetScratch,
  476. );
  477. //We only rebuild the primitive if something other than the radii has changed
  478. //For the radii, we use unit sphere and then deform it with a scale matrix.
  479. const rebuildPrimitives =
  480. !in3D ||
  481. this._lastSceneMode !== sceneMode ||
  482. !defined(this._primitive) || //
  483. options.stackPartitions !== stackPartitions ||
  484. options.slicePartitions !== slicePartitions || //
  485. (defined(innerRadii) &&
  486. !Cartesian3.equals(options.innerRadii !== innerRadii)) ||
  487. options.minimumClock !== minimumClock || //
  488. options.maximumClock !== maximumClock ||
  489. options.minimumCone !== minimumCone || //
  490. options.maximumCone !== maximumCone ||
  491. options.subdivisions !== subdivisions || //
  492. this._lastOutlineWidth !== outlineWidth ||
  493. options.offsetAttribute !== offsetAttribute;
  494. if (rebuildPrimitives) {
  495. const primitives = this._primitives;
  496. primitives.removeAndDestroy(this._primitive);
  497. primitives.removeAndDestroy(this._outlinePrimitive);
  498. this._primitive = undefined;
  499. this._outlinePrimitive = undefined;
  500. this._lastSceneMode = sceneMode;
  501. this._lastOutlineWidth = outlineWidth;
  502. options.stackPartitions = stackPartitions;
  503. options.slicePartitions = slicePartitions;
  504. options.subdivisions = subdivisions;
  505. options.offsetAttribute = offsetAttribute;
  506. options.radii = Cartesian3.clone(in3D ? unitSphere : radii, options.radii);
  507. if (defined(innerRadii)) {
  508. if (in3D) {
  509. options.innerRadii = Cartesian3.fromElements(
  510. innerRadii.x / radii.x,
  511. innerRadii.y / radii.y,
  512. innerRadii.z / radii.z,
  513. options.innerRadii,
  514. );
  515. } else {
  516. options.innerRadii = Cartesian3.clone(innerRadii, options.innerRadii);
  517. }
  518. } else {
  519. options.innerRadii = undefined;
  520. }
  521. options.minimumClock = minimumClock;
  522. options.maximumClock = maximumClock;
  523. options.minimumCone = minimumCone;
  524. options.maximumCone = maximumCone;
  525. const appearance = new MaterialAppearance({
  526. material: material,
  527. translucent: material.isTranslucent(),
  528. closed: true,
  529. });
  530. options.vertexFormat = appearance.vertexFormat;
  531. const fillInstance = this._geometryUpdater.createFillGeometryInstance(
  532. time,
  533. in3D,
  534. this._modelMatrix,
  535. );
  536. this._primitive = primitives.add(
  537. new Primitive({
  538. geometryInstances: fillInstance,
  539. appearance: appearance,
  540. asynchronous: false,
  541. shadows: shadows,
  542. }),
  543. );
  544. const outlineInstance = this._geometryUpdater.createOutlineGeometryInstance(
  545. time,
  546. in3D,
  547. this._modelMatrix,
  548. );
  549. this._outlinePrimitive = primitives.add(
  550. new Primitive({
  551. geometryInstances: outlineInstance,
  552. appearance: new PerInstanceColorAppearance({
  553. flat: true,
  554. translucent: outlineInstance.attributes.color.value[3] !== 255,
  555. renderState: {
  556. lineWidth:
  557. this._geometryUpdater._scene.clampLineWidth(outlineWidth),
  558. },
  559. }),
  560. asynchronous: false,
  561. shadows: shadows,
  562. }),
  563. );
  564. this._lastShow = showFill;
  565. this._lastOutlineShow = showOutline;
  566. this._lastOutlineColor = Color.clone(outlineColor, this._lastOutlineColor);
  567. this._lastDistanceDisplayCondition = distanceDisplayCondition;
  568. this._lastOffset = Cartesian3.clone(offset, this._lastOffset);
  569. } else if (this._primitive.ready) {
  570. //Update attributes only.
  571. const primitive = this._primitive;
  572. const outlinePrimitive = this._outlinePrimitive;
  573. primitive.show = true;
  574. outlinePrimitive.show = true;
  575. primitive.appearance.material = material;
  576. let attributes = this._attributes;
  577. if (!defined(attributes)) {
  578. attributes = primitive.getGeometryInstanceAttributes(entity);
  579. this._attributes = attributes;
  580. }
  581. if (showFill !== this._lastShow) {
  582. attributes.show = ShowGeometryInstanceAttribute.toValue(
  583. showFill,
  584. attributes.show,
  585. );
  586. this._lastShow = showFill;
  587. }
  588. let outlineAttributes = this._outlineAttributes;
  589. if (!defined(outlineAttributes)) {
  590. outlineAttributes =
  591. outlinePrimitive.getGeometryInstanceAttributes(entity);
  592. this._outlineAttributes = outlineAttributes;
  593. }
  594. if (showOutline !== this._lastOutlineShow) {
  595. outlineAttributes.show = ShowGeometryInstanceAttribute.toValue(
  596. showOutline,
  597. outlineAttributes.show,
  598. );
  599. this._lastOutlineShow = showOutline;
  600. }
  601. if (!Color.equals(outlineColor, this._lastOutlineColor)) {
  602. outlineAttributes.color = ColorGeometryInstanceAttribute.toValue(
  603. outlineColor,
  604. outlineAttributes.color,
  605. );
  606. Color.clone(outlineColor, this._lastOutlineColor);
  607. }
  608. if (
  609. !DistanceDisplayCondition.equals(
  610. distanceDisplayCondition,
  611. this._lastDistanceDisplayCondition,
  612. )
  613. ) {
  614. attributes.distanceDisplayCondition =
  615. DistanceDisplayConditionGeometryInstanceAttribute.toValue(
  616. distanceDisplayCondition,
  617. attributes.distanceDisplayCondition,
  618. );
  619. outlineAttributes.distanceDisplayCondition =
  620. DistanceDisplayConditionGeometryInstanceAttribute.toValue(
  621. distanceDisplayCondition,
  622. outlineAttributes.distanceDisplayCondition,
  623. );
  624. DistanceDisplayCondition.clone(
  625. distanceDisplayCondition,
  626. this._lastDistanceDisplayCondition,
  627. );
  628. }
  629. if (!Cartesian3.equals(offset, this._lastOffset)) {
  630. attributes.offset = OffsetGeometryInstanceAttribute.toValue(
  631. offset,
  632. attributes.offset,
  633. );
  634. outlineAttributes.offset = OffsetGeometryInstanceAttribute.toValue(
  635. offset,
  636. attributes.offset,
  637. );
  638. Cartesian3.clone(offset, this._lastOffset);
  639. }
  640. }
  641. if (in3D) {
  642. //Since we are scaling a unit sphere, we can't let any of the values go to zero.
  643. //Instead we clamp them to a small value. To the naked eye, this produces the same results
  644. //that you get passing EllipsoidGeometry a radii with a zero component.
  645. radii.x = Math.max(radii.x, 0.001);
  646. radii.y = Math.max(radii.y, 0.001);
  647. radii.z = Math.max(radii.z, 0.001);
  648. modelMatrix = Matrix4.multiplyByScale(modelMatrix, radii, modelMatrix);
  649. this._primitive.modelMatrix = modelMatrix;
  650. this._outlinePrimitive.modelMatrix = modelMatrix;
  651. }
  652. };
  653. export default EllipsoidGeometryUpdater;