StaticGeometryPerMaterialBatch.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*global define*/
  2. define([
  3. '../Core/AssociativeArray',
  4. '../Core/defined',
  5. '../Core/ShowGeometryInstanceAttribute',
  6. '../Scene/Primitive',
  7. './MaterialProperty'
  8. ], function(
  9. AssociativeArray,
  10. defined,
  11. ShowGeometryInstanceAttribute,
  12. Primitive,
  13. MaterialProperty) {
  14. "use strict";
  15. var Batch = function(primitives, appearanceType, materialProperty, closed) {
  16. this.primitives = primitives;
  17. this.appearanceType = appearanceType;
  18. this.materialProperty = materialProperty;
  19. this.closed = closed;
  20. this.updaters = new AssociativeArray();
  21. this.createPrimitive = true;
  22. this.primitive = undefined;
  23. this.oldPrimitive = undefined;
  24. this.geometry = new AssociativeArray();
  25. this.material = undefined;
  26. this.updatersWithAttributes = new AssociativeArray();
  27. this.attributes = new AssociativeArray();
  28. this.invalidated = false;
  29. this.removeMaterialSubscription = materialProperty.definitionChanged.addEventListener(Batch.prototype.onMaterialChanged, this);
  30. };
  31. Batch.prototype.onMaterialChanged = function() {
  32. this.invalidated = true;
  33. };
  34. Batch.prototype.isMaterial = function(updater) {
  35. var material = this.materialProperty;
  36. var updaterMaterial = updater.fillMaterialProperty;
  37. if (updaterMaterial === material) {
  38. return true;
  39. }
  40. if (defined(material)) {
  41. return material.equals(updaterMaterial);
  42. }
  43. return false;
  44. };
  45. Batch.prototype.add = function(time, updater) {
  46. var id = updater.entity.id;
  47. this.updaters.set(id, updater);
  48. this.geometry.set(id, updater.createFillGeometryInstance(time));
  49. if (!updater.hasConstantFill || !updater.fillMaterialProperty.isConstant) {
  50. this.updatersWithAttributes.set(id, updater);
  51. }
  52. this.createPrimitive = true;
  53. };
  54. Batch.prototype.remove = function(updater) {
  55. var id = updater.entity.id;
  56. this.createPrimitive = this.updaters.remove(id);
  57. this.geometry.remove(id);
  58. this.updatersWithAttributes.remove(id);
  59. return this.createPrimitive;
  60. };
  61. Batch.prototype.update = function(time) {
  62. var show = true;
  63. var isUpdated = true;
  64. var primitive = this.primitive;
  65. var primitives = this.primitives;
  66. var geometries = this.geometry.values;
  67. if (this.createPrimitive) {
  68. if (defined(primitive)) {
  69. if (primitive.ready) {
  70. this.oldPrimitive = primitive;
  71. } else {
  72. primitives.remove(primitive);
  73. }
  74. show = false;
  75. }
  76. if (geometries.length > 0) {
  77. this.material = MaterialProperty.getValue(time, this.materialProperty, this.material);
  78. primitive = new Primitive({
  79. asynchronous : true,
  80. geometryInstances : geometries,
  81. appearance : new this.appearanceType({
  82. material : this.material,
  83. translucent : this.material.isTranslucent(),
  84. closed : this.closed
  85. })
  86. });
  87. primitive.show = show;
  88. primitives.add(primitive);
  89. isUpdated = false;
  90. }
  91. this.primitive = primitive;
  92. this.createPrimitive = false;
  93. } else if (defined(primitive) && primitive.ready) {
  94. if (defined(this.oldPrimitive)) {
  95. primitives.remove(this.oldPrimitive);
  96. this.oldPrimitive = undefined;
  97. primitive.show = true;
  98. }
  99. this.material = MaterialProperty.getValue(time, this.materialProperty, this.material);
  100. this.primitive.appearance.material = this.material;
  101. var updatersWithAttributes = this.updatersWithAttributes.values;
  102. var length = updatersWithAttributes.length;
  103. for (var i = 0; i < length; i++) {
  104. var updater = updatersWithAttributes[i];
  105. var instance = this.geometry.get(updater.entity.id);
  106. var attributes = this.attributes.get(instance.id.id);
  107. if (!defined(attributes)) {
  108. attributes = primitive.getGeometryInstanceAttributes(instance.id);
  109. this.attributes.set(instance.id.id, attributes);
  110. }
  111. if (!updater.hasConstantFill) {
  112. show = updater.isFilled(time);
  113. if (show !== attributes._lastShow) {
  114. attributes._lastShow = show;
  115. attributes.show = ShowGeometryInstanceAttribute.toValue(show, attributes.show);
  116. }
  117. }
  118. }
  119. } else if (defined(primitive) && !primitive.ready) {
  120. isUpdated = false;
  121. }
  122. return isUpdated;
  123. };
  124. Batch.prototype.destroy = function(time) {
  125. var primitive = this.primitive;
  126. var primitives = this.primitives;
  127. if (defined(primitive)) {
  128. primitives.remove(primitive);
  129. }
  130. this.removeMaterialSubscription();
  131. };
  132. /**
  133. * @private
  134. */
  135. var StaticGeometryPerMaterialBatch = function(primitives, appearanceType, closed) {
  136. this._items = [];
  137. this._primitives = primitives;
  138. this._appearanceType = appearanceType;
  139. this._closed = closed;
  140. };
  141. StaticGeometryPerMaterialBatch.prototype.add = function(time, updater) {
  142. var items = this._items;
  143. var length = items.length;
  144. for (var i = 0; i < length; i++) {
  145. var item = items[i];
  146. if (item.isMaterial(updater)) {
  147. item.add(time, updater);
  148. return;
  149. }
  150. }
  151. var batch = new Batch(this._primitives, this._appearanceType, updater.fillMaterialProperty, this._closed);
  152. batch.add(time, updater);
  153. items.push(batch);
  154. };
  155. StaticGeometryPerMaterialBatch.prototype.remove = function(updater) {
  156. var items = this._items;
  157. var length = items.length;
  158. for (var i = length - 1; i >= 0; i--) {
  159. var item = items[i];
  160. if (item.remove(updater)) {
  161. if (item.updaters.length === 0) {
  162. items.splice(i, 1);
  163. item.destroy();
  164. }
  165. break;
  166. }
  167. }
  168. };
  169. StaticGeometryPerMaterialBatch.prototype.update = function(time) {
  170. var i;
  171. var items = this._items;
  172. var length = items.length;
  173. for (i = length - 1; i >= 0; i--) {
  174. var item = items[i];
  175. if (item.invalidated) {
  176. items.splice(i, 1);
  177. var updaters = item.updaters.values;
  178. var updatersLength = updaters.length;
  179. for (var h = 0; h < updatersLength; h++) {
  180. this.add(time, updaters[h]);
  181. }
  182. item.destroy();
  183. }
  184. }
  185. var isUpdated = true;
  186. for (i = 0; i < length; i++) {
  187. isUpdated = items[i].update(time) && isUpdated;
  188. }
  189. return isUpdated;
  190. };
  191. StaticGeometryPerMaterialBatch.prototype.removeAllPrimitives = function() {
  192. var items = this._items;
  193. var length = items.length;
  194. for (var i = 0; i < length; i++) {
  195. items[i].destroy();
  196. }
  197. this._items.length = 0;
  198. };
  199. return StaticGeometryPerMaterialBatch;
  200. });