BillboardVisualizer.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*global define*/
  2. define([
  3. '../Core/AssociativeArray',
  4. '../Core/Cartesian2',
  5. '../Core/Cartesian3',
  6. '../Core/Color',
  7. '../Core/defined',
  8. '../Core/destroyObject',
  9. '../Core/DeveloperError',
  10. '../Core/NearFarScalar',
  11. '../Scene/BillboardCollection',
  12. '../Scene/HorizontalOrigin',
  13. '../Scene/VerticalOrigin',
  14. './Property'
  15. ], function(
  16. AssociativeArray,
  17. Cartesian2,
  18. Cartesian3,
  19. Color,
  20. defined,
  21. destroyObject,
  22. DeveloperError,
  23. NearFarScalar,
  24. BillboardCollection,
  25. HorizontalOrigin,
  26. VerticalOrigin,
  27. Property) {
  28. "use strict";
  29. var defaultColor = Color.WHITE;
  30. var defaultEyeOffset = Cartesian3.ZERO;
  31. var defaultPixelOffset = Cartesian2.ZERO;
  32. var defaultScale = 1.0;
  33. var defaultRotation = 0.0;
  34. var defaultAlignedAxis = Cartesian3.ZERO;
  35. var defaultHorizontalOrigin = HorizontalOrigin.CENTER;
  36. var defaultVerticalOrigin = VerticalOrigin.CENTER;
  37. var position = new Cartesian3();
  38. var color = new Color();
  39. var eyeOffset = new Cartesian3();
  40. var pixelOffset = new Cartesian2();
  41. var scaleByDistance = new NearFarScalar();
  42. var translucencyByDistance = new NearFarScalar();
  43. var pixelOffsetScaleByDistance = new NearFarScalar();
  44. var EntityData = function(entity) {
  45. this.entity = entity;
  46. this.billboard = undefined;
  47. };
  48. /**
  49. * A {@link Visualizer} which maps {@link Entity#billboard} to a {@link Billboard}.
  50. * @alias BillboardVisualizer
  51. * @constructor
  52. *
  53. * @param {Scene} scene The scene the primitives will be rendered in.
  54. * @param {EntityCollection} entityCollection The entityCollection to visualize.
  55. */
  56. var BillboardVisualizer = function(scene, entityCollection) {
  57. //>>includeStart('debug', pragmas.debug);
  58. if (!defined(scene)) {
  59. throw new DeveloperError('scene is required.');
  60. }
  61. if (!defined(entityCollection)) {
  62. throw new DeveloperError('entityCollection is required.');
  63. }
  64. //>>includeEnd('debug');
  65. entityCollection.collectionChanged.addEventListener(BillboardVisualizer.prototype._onCollectionChanged, this);
  66. this._scene = scene;
  67. this._unusedIndexes = [];
  68. this._billboardCollection = undefined;
  69. this._entityCollection = entityCollection;
  70. this._items = new AssociativeArray();
  71. this._onCollectionChanged(entityCollection, entityCollection.entities, [], []);
  72. };
  73. /**
  74. * Updates the primitives created by this visualizer to match their
  75. * Entity counterpart at the given time.
  76. *
  77. * @param {JulianDate} time The time to update to.
  78. * @returns {Boolean} This function always returns true.
  79. */
  80. BillboardVisualizer.prototype.update = function(time) {
  81. //>>includeStart('debug', pragmas.debug);
  82. if (!defined(time)) {
  83. throw new DeveloperError('time is required.');
  84. }
  85. //>>includeEnd('debug');
  86. var items = this._items.values;
  87. var unusedIndexes = this._unusedIndexes;
  88. for (var i = 0, len = items.length; i < len; i++) {
  89. var item = items[i];
  90. var entity = item.entity;
  91. var billboardGraphics = entity._billboard;
  92. var textureValue;
  93. var billboard = item.billboard;
  94. var show = entity.isAvailable(time) && Property.getValueOrDefault(billboardGraphics._show, time, true);
  95. if (show) {
  96. position = Property.getValueOrUndefined(entity._position, time, position);
  97. textureValue = Property.getValueOrUndefined(billboardGraphics._image, time);
  98. show = defined(position) && defined(textureValue);
  99. }
  100. if (!show) {
  101. //don't bother creating or updating anything else
  102. returnBillboard(item, unusedIndexes);
  103. continue;
  104. }
  105. if (!defined(billboard)) {
  106. var billboardCollection = this._billboardCollection;
  107. if (!defined(billboardCollection)) {
  108. billboardCollection = new BillboardCollection();
  109. this._billboardCollection = billboardCollection;
  110. this._scene.primitives.add(billboardCollection);
  111. }
  112. var length = unusedIndexes.length;
  113. if (length > 0) {
  114. billboard = billboardCollection.get(unusedIndexes.pop());
  115. } else {
  116. billboard = billboardCollection.add();
  117. }
  118. billboard.id = entity;
  119. billboard.image = undefined;
  120. item.billboard = billboard;
  121. }
  122. billboard.show = show;
  123. billboard.image = textureValue;
  124. billboard.position = position;
  125. billboard.color = Property.getValueOrDefault(billboardGraphics._color, time, defaultColor, color);
  126. billboard.eyeOffset = Property.getValueOrDefault(billboardGraphics._eyeOffset, time, defaultEyeOffset, eyeOffset);
  127. billboard.pixelOffset = Property.getValueOrDefault(billboardGraphics._pixelOffset, time, defaultPixelOffset, pixelOffset);
  128. billboard.scale = Property.getValueOrDefault(billboardGraphics._scale, time, defaultScale);
  129. billboard.rotation = Property.getValueOrDefault(billboardGraphics._rotation, time, defaultRotation);
  130. billboard.alignedAxis = Property.getValueOrDefault(billboardGraphics._alignedAxis, time, defaultAlignedAxis);
  131. billboard.horizontalOrigin = Property.getValueOrDefault(billboardGraphics._horizontalOrigin, time, defaultHorizontalOrigin);
  132. billboard.verticalOrigin = Property.getValueOrDefault(billboardGraphics._verticalOrigin, time, defaultVerticalOrigin);
  133. billboard.width = Property.getValueOrUndefined(billboardGraphics._width, time);
  134. billboard.height = Property.getValueOrUndefined(billboardGraphics._height, time);
  135. billboard.scaleByDistance = Property.getValueOrUndefined(billboardGraphics._scaleByDistance, time, scaleByDistance);
  136. billboard.translucencyByDistance = Property.getValueOrUndefined(billboardGraphics._translucencyByDistance, time, translucencyByDistance);
  137. billboard.pixelOffsetScaleByDistance = Property.getValueOrUndefined(billboardGraphics._pixelOffsetScaleByDistance, time, pixelOffsetScaleByDistance);
  138. }
  139. return true;
  140. };
  141. /**
  142. * Returns true if this object was destroyed; otherwise, false.
  143. *
  144. * @returns {Boolean} True if this object was destroyed; otherwise, false.
  145. */
  146. BillboardVisualizer.prototype.isDestroyed = function() {
  147. return false;
  148. };
  149. /**
  150. * Removes and destroys all primitives created by this instance.
  151. */
  152. BillboardVisualizer.prototype.destroy = function() {
  153. this._entityCollection.collectionChanged.removeEventListener(BillboardVisualizer.prototype._onCollectionChanged, this);
  154. if (defined(this._billboardCollection)) {
  155. this._scene.primitives.remove(this._billboardCollection);
  156. }
  157. return destroyObject(this);
  158. };
  159. BillboardVisualizer.prototype._onCollectionChanged = function(entityCollection, added, removed, changed) {
  160. var i;
  161. var entity;
  162. var unusedIndexes = this._unusedIndexes;
  163. var items = this._items;
  164. for (i = added.length - 1; i > -1; i--) {
  165. entity = added[i];
  166. if (defined(entity._billboard) && defined(entity._position)) {
  167. items.set(entity.id, new EntityData(entity));
  168. }
  169. }
  170. for (i = changed.length - 1; i > -1; i--) {
  171. entity = changed[i];
  172. if (defined(entity._billboard) && defined(entity._position)) {
  173. if (!items.contains(entity.id)) {
  174. items.set(entity.id, new EntityData(entity));
  175. }
  176. } else {
  177. returnBillboard(items.get(entity.id), unusedIndexes);
  178. items.remove(entity.id);
  179. }
  180. }
  181. for (i = removed.length - 1; i > -1; i--) {
  182. entity = removed[i];
  183. returnBillboard(items.get(entity.id), unusedIndexes);
  184. items.remove(entity.id);
  185. }
  186. };
  187. function returnBillboard(item, unusedIndexes) {
  188. if (defined(item)) {
  189. var billboard = item.billboard;
  190. if (defined(billboard)) {
  191. item.billboard = undefined;
  192. billboard.show = false;
  193. billboard.image = undefined;
  194. unusedIndexes.push(billboard._index);
  195. }
  196. }
  197. }
  198. return BillboardVisualizer;
  199. });