EllipsoidGeometryUpdater.js 27 KB

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