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

BufferPrimitive.js 8.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. // @ts-check
  2. import assert from "../Core/assert.js";
  3. /** @import BufferPrimitiveCollection from './BufferPrimitiveCollection.js'; */
  4. /** @import BufferPrimitiveMaterial from "./BufferPrimitiveMaterial.js"; */
  5. /**
  6. * View bound to the underlying buffer data of a {@link BufferPrimitiveCollection}. Abstract.
  7. *
  8. * <p>BufferPrimitive instances are intended to be reused when iterating over large collections,
  9. * and temporarily bound to a primitive index while performing read/write operations on that primitive,
  10. * before being rebound to the next primitive, using the
  11. * {@link https://en.wikipedia.org/wiki/Flyweight_pattern|flyweight pattern}.</p>
  12. *
  13. * @see BufferPrimitiveCollection
  14. * @see BufferPrimitiveMaterial
  15. * @see BufferPoint
  16. * @see BufferPolyline
  17. * @see BufferPolygon
  18. *
  19. * @abstract
  20. * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
  21. */
  22. class BufferPrimitive {
  23. /**
  24. * Collecton containing the primitive(s) for which this instance currently
  25. * provides a view.
  26. *
  27. * @type {BufferPrimitiveCollection<BufferPrimitive>}
  28. * @ignore
  29. */
  30. _collection = null;
  31. /**
  32. * Index of the primitive for which this instance currently provides a view.
  33. *
  34. * @type {number}
  35. * @ignore
  36. */
  37. _index = -1;
  38. /**
  39. * Byte offset, into the collection's primitive buffer, of the primitive for
  40. * which this instance currently provides a view.
  41. *
  42. * @type {number}
  43. * @ignore
  44. */
  45. _byteOffset = -1;
  46. /**
  47. * Binary layout for this primitive type in collection's primitive buffer.
  48. * Each `Layout.MY_KEY_U32` entry is an offset in bytes, relative to the
  49. * start offset of the primitive, with the suffix indicating the data type
  50. * stored at that offset.
  51. *
  52. * The final entry, `__BYTE_LENGTH`, is not a pointer into a buffer — its
  53. * literal value is the total byte length of one primitive in the primitive
  54. * buffer, exclusive of other buffers.
  55. *
  56. * @ignore
  57. */
  58. static Layout = {
  59. /**
  60. * Feature ID associated with the primitive; not required to be unique.
  61. * @type {number}
  62. * @ignore
  63. */
  64. FEATURE_ID_U32: 0,
  65. /**
  66. * Boolean (0 or 1) flag indicating whether primitive is shown.
  67. * @type {number}
  68. * @ignore
  69. */
  70. SHOW_U8: 4,
  71. /**
  72. * Boolean (0 or 1) flag indicating whether primitive is dirty.
  73. * @type {number}
  74. * @ignore
  75. */
  76. DIRTY_U8: 5,
  77. /**
  78. * Pick ID (uint32) of primitive.
  79. * @type {number}
  80. * @ignore
  81. */
  82. PICK_ID_U32: 8,
  83. /**
  84. * Byte length of one primitive in the primitive buffer, exclusive of
  85. * other buffers. Literal value, not a pointer.
  86. * @type {number}
  87. * @ignore
  88. */
  89. __BYTE_LENGTH: 12,
  90. };
  91. /////////////////////////////////////////////////////////////////////////////
  92. // LIFECYCLE
  93. /**
  94. * Copies data from source primitive to result. If the result primitive is not
  95. * new (the last primitive in the collection) then source and result primitives
  96. * must have the same vertex counts.
  97. *
  98. * @param {BufferPrimitive} primitive
  99. * @param {BufferPrimitive} result
  100. * @returns {BufferPrimitive}
  101. */
  102. static clone(primitive, result) {
  103. const SrcMaterialClass = primitive._collection._getMaterialClass();
  104. //>>includeStart('debug', pragmas.debug);
  105. const DstMaterialClass = result._collection._getMaterialClass();
  106. assert(SrcMaterialClass === DstMaterialClass, "Incompatible materials");
  107. //>>includeEnd('debug');
  108. result.featureId = primitive.featureId;
  109. result.show = primitive.show;
  110. result.setMaterial(primitive.getMaterial(new SrcMaterialClass()));
  111. return result;
  112. }
  113. /**
  114. * Returns true if this primitive's memory footprint is resizable. Only the
  115. * newest (most recently created) primitive in a collection can be resized,
  116. * to guarantee fast and stable performance.
  117. *
  118. * @returns {boolean}
  119. * @protected
  120. * @ignore
  121. */
  122. _isResizable() {
  123. return this._index === this._collection.primitiveCount - 1;
  124. }
  125. /////////////////////////////////////////////////////////////////////////////
  126. // ACCESSORS
  127. /**
  128. * Feature ID associated with the primitive; not required to be unique.
  129. * @type {number}
  130. */
  131. get featureId() {
  132. return this._getUint32(BufferPrimitive.Layout.FEATURE_ID_U32);
  133. }
  134. set featureId(featureId) {
  135. this._setUint32(BufferPrimitive.Layout.FEATURE_ID_U32, featureId);
  136. }
  137. /**
  138. * Whether primitive is shown.
  139. * @type {boolean}
  140. */
  141. get show() {
  142. return this._getUint8(BufferPrimitive.Layout.SHOW_U8) === 1;
  143. }
  144. set show(show) {
  145. this._setUint8(BufferPrimitive.Layout.SHOW_U8, show ? 1 : 0);
  146. }
  147. /**
  148. * @param {BufferPrimitiveMaterial} result
  149. * @returns {BufferPrimitiveMaterial}
  150. */
  151. getMaterial(result) {
  152. const collection = this._collection;
  153. const MaterialClass = collection._getMaterialClass();
  154. return MaterialClass.unpack(
  155. collection._materialView,
  156. this._index * MaterialClass.packedLength,
  157. result,
  158. );
  159. }
  160. /**
  161. * @param {BufferPrimitiveMaterial} material
  162. */
  163. setMaterial(material) {
  164. const collection = this._collection;
  165. const MaterialClass = collection._getMaterialClass();
  166. MaterialClass.pack(
  167. material,
  168. collection._materialView,
  169. this._index * MaterialClass.packedLength,
  170. );
  171. this._dirty = true;
  172. return material;
  173. }
  174. /**
  175. * Whether the primitive requires an update on next render. Renderers should
  176. * _not_ iterate over all primitives each frame, but must instead inspect
  177. * only the dirty range of the parent collection. This flag is managed
  178. * automatically, by primitive setters and collection renderers.
  179. *
  180. * @type {boolean}
  181. * @ignore
  182. *
  183. * @see BufferPrimitiveCollection#_dirtyOffset
  184. * @see BufferPrimitiveCollection#_dirtyCount
  185. */
  186. get _dirty() {
  187. return this._getUint8(BufferPrimitive.Layout.DIRTY_U8) === 1;
  188. }
  189. set _dirty(dirty) {
  190. // Avoid `._setUint8()` here, which would infinitely loop `._dirty = true`.
  191. this._collection._primitiveView.setUint8(
  192. this._byteOffset + BufferPrimitive.Layout.DIRTY_U8,
  193. dirty ? 1 : 0,
  194. );
  195. // A 'dirty' primitive is responsible for notifying the collection. Applying
  196. // updates and marking the primitive 'clean' will be handled by the collection,
  197. // so we don't notify the collection here in that case.
  198. if (dirty) {
  199. this._collection._makeDirty(this._index);
  200. }
  201. }
  202. /**
  203. * Pick ID (uint32) of primitive.
  204. * @type {number}
  205. * @ignore
  206. */
  207. get _pickId() {
  208. return this._getUint32(BufferPrimitive.Layout.PICK_ID_U32);
  209. }
  210. set _pickId(pickId) {
  211. this._setUint32(BufferPrimitive.Layout.PICK_ID_U32, pickId);
  212. }
  213. /////////////////////////////////////////////////////////////////////////////
  214. // BUFFER ACCESSORS
  215. /**
  216. * @param {number} itemByteOffset
  217. * @returns {number}
  218. * @ignore
  219. */
  220. _getUint8(itemByteOffset) {
  221. return this._collection._primitiveView.getUint8(
  222. this._byteOffset + itemByteOffset,
  223. );
  224. }
  225. /**
  226. * @param {number} itemByteOffset
  227. * @param {number} itemValue
  228. * @ignore
  229. */
  230. _setUint8(itemByteOffset, itemValue) {
  231. this._collection._primitiveView.setUint8(
  232. this._byteOffset + itemByteOffset,
  233. itemValue,
  234. );
  235. this._dirty = true;
  236. }
  237. /**
  238. * @param {number} itemByteOffset
  239. * @returns {number}
  240. * @ignore
  241. */
  242. _getUint32(itemByteOffset) {
  243. return this._collection._primitiveView.getUint32(
  244. this._byteOffset + itemByteOffset,
  245. true,
  246. );
  247. }
  248. /**
  249. * @param {number} itemByteOffset
  250. * @param {number} itemValue
  251. * @ignore
  252. */
  253. _setUint32(itemByteOffset, itemValue) {
  254. this._collection._primitiveView.setUint32(
  255. this._byteOffset + itemByteOffset,
  256. itemValue,
  257. true,
  258. );
  259. this._dirty = true;
  260. }
  261. /**
  262. * @param {number} itemByteOffset
  263. * @returns {number}
  264. * @ignore
  265. */
  266. _getFloat32(itemByteOffset) {
  267. return this._collection._primitiveView.getFloat32(
  268. this._byteOffset + itemByteOffset,
  269. true,
  270. );
  271. }
  272. /**
  273. * @param {number} itemByteOffset
  274. * @param {number} itemValue
  275. * @ignore
  276. */
  277. _setFloat32(itemByteOffset, itemValue) {
  278. this._collection._primitiveView.setFloat32(
  279. this._byteOffset + itemByteOffset,
  280. itemValue,
  281. true,
  282. );
  283. this._dirty = true;
  284. }
  285. /////////////////////////////////////////////////////////////////////////////
  286. // DEBUG
  287. /**
  288. * Returns a JSON-serializable object representing the primitive. This encoding
  289. * is not memory-efficient, and should generally be used for debugging and
  290. * testing.
  291. *
  292. * @returns {Object} JSON-serializable object.
  293. */
  294. toJSON() {
  295. const collection = this._collection;
  296. const MaterialClass = collection._getMaterialClass();
  297. return {
  298. featureId: this.featureId,
  299. show: this.show,
  300. dirty: this._dirty,
  301. material: this.getMaterial(new MaterialClass()).toJSON(),
  302. };
  303. }
  304. }
  305. export default BufferPrimitive;