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

BufferPolygonCollection.js 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. // @ts-check
  2. import defined from "../Core/defined.js";
  3. import BufferPrimitiveCollection from "./BufferPrimitiveCollection.js";
  4. import BufferPolygon from "./BufferPolygon.js";
  5. import Frozen from "../Core/Frozen.js";
  6. import assert from "../Core/assert.js";
  7. import IndexDatatype from "../Core/IndexDatatype.js";
  8. import renderPolygons from "./renderBufferPolygonCollection.js";
  9. import BufferPolygonMaterial from "./BufferPolygonMaterial.js";
  10. /** @import BlendOption from "./BlendOption.js"; */
  11. /** @import BoundingSphere from "../Core/BoundingSphere.js"; */
  12. /** @import { TypedArray } from "../Core/globalTypes.js"; */
  13. /** @import Matrix4 from "../Core/Matrix4.js"; */
  14. /** @import FrameState from "./FrameState.js" */
  15. /** @import ComponentDatatype from "../Core/ComponentDatatype.js"; */
  16. const { ERR_CAPACITY } = BufferPrimitiveCollection.Error;
  17. /**
  18. * @typedef {object} BufferPolygonOptions
  19. * @property {Matrix4} [modelMatrix=Matrix4.IDENTITY] Transforms geometry from model to world coordinates.
  20. * @property {boolean} [show=true]
  21. * @property {BufferPolygonMaterial} [material=BufferPolygonMaterial.DEFAULT_MATERIAL]
  22. * @property {number} [featureId]
  23. * @property {object} [pickObject]
  24. * @property {TypedArray} [positions]
  25. * @property {TypedArray} [holes]
  26. * @property {TypedArray} [triangles]
  27. * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
  28. */
  29. /**
  30. * Collection of polygons held in ArrayBuffer storage for performance and memory optimization.
  31. *
  32. * <p>Default buffer memory allocation is arbitrary, and collections cannot be resized,
  33. * so specific per-buffer capacities should be provided in the collection
  34. * constructor when available.</p>
  35. *
  36. * @example
  37. * import earcut from "earcut";
  38. *
  39. * const collection = new BufferPolygonCollection({
  40. * primitiveCountMax: 1024,
  41. * vertexCountMax: 4096,
  42. * holeCountMax: 1024,
  43. * triangleCountMax: 2048,
  44. * });
  45. *
  46. * const polygon = new BufferPolygon();
  47. * const positions = [ ... ];
  48. * const holes = [ ... ];
  49. * const material = new BufferPolygonMaterial({color: Color.WHITE});
  50. *
  51. * // Create a new polygon, temporarily bound to 'polygon' local variable.
  52. * collection.add({
  53. * positions: new Float64Array(positions),
  54. * holes: new Uint32Array(holes),
  55. * triangles: new Uint32Array(earcut(positions, holes, 3)),
  56. * material
  57. * }, polygon);
  58. *
  59. * // Iterate over all polygons in collection, temporarily binding 'polygon'
  60. * // local variable to each, and updating polygon material.
  61. * for (let i = 0; i < collection.primitiveCount; i++) {
  62. * collection.get(i, polygon);
  63. * polygon.setMaterial(material);
  64. * }
  65. *
  66. * @see BufferPolygon
  67. * @see BufferPolygonMaterial
  68. * @see BufferPrimitiveCollection
  69. * @extends BufferPrimitiveCollection<BufferPolygon>
  70. * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
  71. */
  72. class BufferPolygonCollection extends BufferPrimitiveCollection {
  73. /**
  74. * @param {object} options
  75. * @param {number} [options.primitiveCountMax=BufferPrimitiveCollection.DEFAULT_CAPACITY]
  76. * @param {number} [options.vertexCountMax=BufferPrimitiveCollection.DEFAULT_CAPACITY]
  77. * @param {number} [options.holeCountMax=BufferPrimitiveCollection.DEFAULT_CAPACITY]
  78. * @param {number} [options.triangleCountMax=BufferPrimitiveCollection.DEFAULT_CAPACITY]
  79. * @param {ComponentDatatype} [options.positionDatatype=ComponentDatatype.DOUBLE]
  80. * @param {boolean} [options.positionNormalized=false]
  81. * @param {boolean} [options.show=true]
  82. * @param {boolean} [options.allowPicking=true] When <code>true</code>, primitives are pickable with {@link Scene#pick}. When <code>false</code>, memory and initialization cost are lower.
  83. * @param {BoundingSphere} [options.boundingVolume] Bounding volume, in world space, for the collection. When
  84. * unspecified, a bounding volume is computed automatically and updated when primitive positions change. When
  85. * specified, users are responsible for updating bounding volume as needed. Pre-computing the bounding volume
  86. * manually, and updating it only as needed, will improve performance for larger dynamic collections.
  87. * @param {boolean} [options.debugShowBoundingVolume=false]
  88. * @param {BlendOption} [options.blendOption=BlendOption.TRANSLUCENT]
  89. */
  90. constructor(options = Frozen.EMPTY_OBJECT) {
  91. super(options);
  92. /**
  93. * @type {number}
  94. * @ignore
  95. */
  96. this._holeCount = 0;
  97. /**
  98. * @type {number}
  99. * @protected
  100. * @ignore
  101. */
  102. this._holeCountMax =
  103. options.holeCountMax ?? BufferPrimitiveCollection.DEFAULT_CAPACITY;
  104. /**
  105. * @type {TypedArray}
  106. * @ignore
  107. */
  108. this._holeIndexView = null;
  109. /**
  110. * @type {number}
  111. * @ignore
  112. */
  113. this._triangleCount = 0;
  114. /**
  115. * @type {number}
  116. * @protected
  117. * @ignore
  118. */
  119. this._triangleCountMax =
  120. options.triangleCountMax ?? BufferPrimitiveCollection.DEFAULT_CAPACITY;
  121. /**
  122. * @type {TypedArray}
  123. * @ignore
  124. */
  125. this._triangleIndexView = null;
  126. this._allocateHoleIndexBuffer();
  127. this._allocateTriangleIndexBuffer();
  128. }
  129. _getCollectionClass() {
  130. return BufferPolygonCollection;
  131. }
  132. _getPrimitiveClass() {
  133. return BufferPolygon;
  134. }
  135. _getMaterialClass() {
  136. return BufferPolygonMaterial;
  137. }
  138. /////////////////////////////////////////////////////////////////////////////
  139. // COLLECTION LIFECYCLE
  140. /**
  141. * @private
  142. * @ignore
  143. */
  144. _allocateHoleIndexBuffer() {
  145. // @ts-expect-error Requires https://github.com/CesiumGS/cesium/pull/13203.
  146. this._holeIndexView = IndexDatatype.createTypedArray(
  147. this._positionCountMax,
  148. this._holeCountMax,
  149. );
  150. }
  151. /**
  152. * @private
  153. * @ignore
  154. */
  155. _allocateTriangleIndexBuffer() {
  156. // @ts-expect-error Requires https://github.com/CesiumGS/cesium/pull/13203.
  157. this._triangleIndexView = IndexDatatype.createTypedArray(
  158. this._positionCountMax,
  159. this._triangleCountMax * 3,
  160. );
  161. }
  162. /**
  163. * Duplicates the contents of this collection into the result collection.
  164. * Result collection is not resized, and must contain enough space for all
  165. * primitives in the source collection. Existing polygons in the result
  166. * collection will be overwritten.
  167. *
  168. * <p>Useful when allocating more space for a collection that has reached its
  169. * capacity, and efficiently transferring polygons to the new collection.</p>
  170. *
  171. * @example
  172. * const result = new BufferPolygonCollection({ ... }); // allocate larger 'result' collection
  173. * BufferPolygonCollection.clone(collection, result); // copy polygons from 'collection' into 'result'
  174. *
  175. * @param {BufferPolygonCollection} collection
  176. * @param {BufferPolygonCollection} result
  177. * @returns {BufferPolygonCollection}
  178. */
  179. static clone(collection, result) {
  180. super.clone(collection, result);
  181. //>>includeStart('debug', pragmas.debug);
  182. assert(collection.holeCount <= result.holeCountMax, ERR_CAPACITY);
  183. assert(collection.triangleCount <= result.triangleCountMax, ERR_CAPACITY);
  184. //>>includeEnd('debug');
  185. this._copySubArray(
  186. collection._holeIndexView,
  187. result._holeIndexView,
  188. collection.holeCount,
  189. );
  190. this._copySubArray(
  191. collection._triangleIndexView,
  192. result._triangleIndexView,
  193. collection._triangleCount * 3,
  194. );
  195. result._holeCount = collection._holeCount;
  196. result._triangleCount = collection._triangleCount;
  197. return result;
  198. }
  199. /**
  200. * @param {BufferPolygonCollection} collection
  201. * @returns {BufferPolygonCollection}
  202. * @override
  203. * @ignore
  204. */
  205. static _cloneEmpty(collection) {
  206. return new BufferPolygonCollection({
  207. primitiveCountMax: collection.primitiveCountMax,
  208. vertexCountMax: collection.vertexCountMax,
  209. holeCountMax: collection.holeCountMax,
  210. triangleCountMax: collection.triangleCountMax,
  211. positionDatatype: collection.positionDatatype,
  212. positionNormalized: collection.positionNormalized,
  213. });
  214. }
  215. /**
  216. * @param {BufferPolygonCollection} src
  217. * @param {BufferPolygonCollection} dst
  218. * @override
  219. * @ignore
  220. */
  221. static _replaceBuffers(src, dst) {
  222. super._replaceBuffers(src, dst);
  223. dst._holeIndexView = src._holeIndexView;
  224. dst._triangleIndexView = src._triangleIndexView;
  225. }
  226. /////////////////////////////////////////////////////////////////////////////
  227. // PRIMITIVE LIFECYCLE
  228. /**
  229. * Adds a new polygon to the collection, with the specified options. A
  230. * {@link BufferPolygon} instance is linked to the new polygon, using
  231. * the 'result' argument if given, or a new instance if not. For repeated
  232. * calls, prefer to reuse a single BufferPolygon instance rather than
  233. * allocating a new instance on each call.
  234. *
  235. * @param {BufferPolygonOptions} options
  236. * @param {BufferPolygon} result
  237. * @returns {BufferPolygon}
  238. * @override
  239. */
  240. add(options, result = new BufferPolygon()) {
  241. super.add(options, result);
  242. const vertexOffset = this._positionCount;
  243. result._setUint32(BufferPolygon.Layout.POSITION_OFFSET_U32, vertexOffset);
  244. result._setUint32(BufferPolygon.Layout.POSITION_COUNT_U32, 0);
  245. const holeOffset = this._holeCount;
  246. result._setUint32(BufferPolygon.Layout.HOLE_OFFSET_U32, holeOffset);
  247. result._setUint32(BufferPolygon.Layout.HOLE_COUNT_U32, 0);
  248. const triangleOffset = this._triangleCount;
  249. result._setUint32(BufferPolygon.Layout.TRIANGLE_OFFSET_U32, triangleOffset);
  250. result._setUint32(BufferPolygon.Layout.TRIANGLE_COUNT_U32, 0);
  251. if (defined(options.positions)) {
  252. result.setPositions(options.positions);
  253. }
  254. if (defined(options.holes)) {
  255. result.setHoles(options.holes);
  256. }
  257. if (defined(options.triangles)) {
  258. result.setTriangles(options.triangles);
  259. }
  260. return result;
  261. }
  262. /////////////////////////////////////////////////////////////////////////////
  263. // RENDER
  264. /**
  265. * @param {FrameState} frameState
  266. * @ignore
  267. */
  268. update(frameState) {
  269. super.update(frameState);
  270. const passes = frameState.passes;
  271. if (this.show && (passes.render || passes.pick)) {
  272. this._renderContext = renderPolygons(
  273. this,
  274. frameState,
  275. this._renderContext,
  276. );
  277. }
  278. }
  279. /////////////////////////////////////////////////////////////////////////////
  280. // ACCESSORS
  281. /**
  282. * Total byte length of buffers owned by this collection. Includes any unused
  283. * space allocated by {@link primitiveCountMax}, even if no polygons have
  284. * yet been added in that space.
  285. *
  286. * @type {number}
  287. * @readonly
  288. * @override
  289. */
  290. get byteLength() {
  291. return (
  292. super.byteLength +
  293. this._holeIndexView.byteLength +
  294. this._triangleIndexView.byteLength
  295. );
  296. }
  297. /**
  298. * Number of holes in collection. Must be <= {@link holeCountMax}.
  299. *
  300. * @type {number}
  301. * @readonly
  302. */
  303. get holeCount() {
  304. return this._holeCount;
  305. }
  306. /**
  307. * Maximum number of holes in collection. Must be >= {@link holeCount}.
  308. *
  309. * @type {number}
  310. * @readonly
  311. * @default {@link BufferPrimitiveCollection.DEFAULT_CAPACITY}
  312. */
  313. get holeCountMax() {
  314. return this._holeCountMax;
  315. }
  316. /**
  317. * Number of triangles in collection. Must be <= {@link triangleCountMax}.
  318. *
  319. * @type {number}
  320. * @readonly
  321. */
  322. get triangleCount() {
  323. return this._triangleCount;
  324. }
  325. /**
  326. * Maximum number of triangles in collection. Must be >= {@link triangleCount}.
  327. *
  328. * @type {number}
  329. * @readonly
  330. * @default {@link BufferPrimitiveCollection.DEFAULT_CAPACITY}
  331. */
  332. get triangleCountMax() {
  333. return this._triangleCountMax;
  334. }
  335. }
  336. export default BufferPolygonCollection;