| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- // @ts-check
-
- import defined from "../Core/defined.js";
- import BufferPrimitiveCollection from "./BufferPrimitiveCollection.js";
- import BufferPolygon from "./BufferPolygon.js";
- import Frozen from "../Core/Frozen.js";
- import assert from "../Core/assert.js";
- import IndexDatatype from "../Core/IndexDatatype.js";
- import renderPolygons from "./renderBufferPolygonCollection.js";
- import BufferPolygonMaterial from "./BufferPolygonMaterial.js";
-
- /** @import BlendOption from "./BlendOption.js"; */
- /** @import BoundingSphere from "../Core/BoundingSphere.js"; */
- /** @import { TypedArray } from "../Core/globalTypes.js"; */
- /** @import Matrix4 from "../Core/Matrix4.js"; */
- /** @import FrameState from "./FrameState.js" */
- /** @import ComponentDatatype from "../Core/ComponentDatatype.js"; */
-
- const { ERR_CAPACITY } = BufferPrimitiveCollection.Error;
-
- /**
- * @typedef {object} BufferPolygonOptions
- * @property {Matrix4} [modelMatrix=Matrix4.IDENTITY] Transforms geometry from model to world coordinates.
- * @property {boolean} [show=true]
- * @property {BufferPolygonMaterial} [material=BufferPolygonMaterial.DEFAULT_MATERIAL]
- * @property {number} [featureId]
- * @property {object} [pickObject]
- * @property {TypedArray} [positions]
- * @property {TypedArray} [holes]
- * @property {TypedArray} [triangles]
- * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
- */
-
- /**
- * Collection of polygons held in ArrayBuffer storage for performance and memory optimization.
- *
- * <p>Default buffer memory allocation is arbitrary, and collections cannot be resized,
- * so specific per-buffer capacities should be provided in the collection
- * constructor when available.</p>
- *
- * @example
- * import earcut from "earcut";
- *
- * const collection = new BufferPolygonCollection({
- * primitiveCountMax: 1024,
- * vertexCountMax: 4096,
- * holeCountMax: 1024,
- * triangleCountMax: 2048,
- * });
- *
- * const polygon = new BufferPolygon();
- * const positions = [ ... ];
- * const holes = [ ... ];
- * const material = new BufferPolygonMaterial({color: Color.WHITE});
- *
- * // Create a new polygon, temporarily bound to 'polygon' local variable.
- * collection.add({
- * positions: new Float64Array(positions),
- * holes: new Uint32Array(holes),
- * triangles: new Uint32Array(earcut(positions, holes, 3)),
- * material
- * }, polygon);
- *
- * // Iterate over all polygons in collection, temporarily binding 'polygon'
- * // local variable to each, and updating polygon material.
- * for (let i = 0; i < collection.primitiveCount; i++) {
- * collection.get(i, polygon);
- * polygon.setMaterial(material);
- * }
- *
- * @see BufferPolygon
- * @see BufferPolygonMaterial
- * @see BufferPrimitiveCollection
- * @extends BufferPrimitiveCollection<BufferPolygon>
- * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
- */
- class BufferPolygonCollection extends BufferPrimitiveCollection {
- /**
- * @param {object} options
- * @param {number} [options.primitiveCountMax=BufferPrimitiveCollection.DEFAULT_CAPACITY]
- * @param {number} [options.vertexCountMax=BufferPrimitiveCollection.DEFAULT_CAPACITY]
- * @param {number} [options.holeCountMax=BufferPrimitiveCollection.DEFAULT_CAPACITY]
- * @param {number} [options.triangleCountMax=BufferPrimitiveCollection.DEFAULT_CAPACITY]
- * @param {ComponentDatatype} [options.positionDatatype=ComponentDatatype.DOUBLE]
- * @param {boolean} [options.positionNormalized=false]
- * @param {boolean} [options.show=true]
- * @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.
- * @param {BoundingSphere} [options.boundingVolume] Bounding volume, in world space, for the collection. When
- * unspecified, a bounding volume is computed automatically and updated when primitive positions change. When
- * specified, users are responsible for updating bounding volume as needed. Pre-computing the bounding volume
- * manually, and updating it only as needed, will improve performance for larger dynamic collections.
- * @param {boolean} [options.debugShowBoundingVolume=false]
- * @param {BlendOption} [options.blendOption=BlendOption.TRANSLUCENT]
- */
- constructor(options = Frozen.EMPTY_OBJECT) {
- super(options);
-
- /**
- * @type {number}
- * @ignore
- */
- this._holeCount = 0;
-
- /**
- * @type {number}
- * @protected
- * @ignore
- */
- this._holeCountMax =
- options.holeCountMax ?? BufferPrimitiveCollection.DEFAULT_CAPACITY;
-
- /**
- * @type {TypedArray}
- * @ignore
- */
- this._holeIndexView = null;
-
- /**
- * @type {number}
- * @ignore
- */
- this._triangleCount = 0;
-
- /**
- * @type {number}
- * @protected
- * @ignore
- */
- this._triangleCountMax =
- options.triangleCountMax ?? BufferPrimitiveCollection.DEFAULT_CAPACITY;
-
- /**
- * @type {TypedArray}
- * @ignore
- */
- this._triangleIndexView = null;
-
- this._allocateHoleIndexBuffer();
- this._allocateTriangleIndexBuffer();
- }
-
- _getCollectionClass() {
- return BufferPolygonCollection;
- }
-
- _getPrimitiveClass() {
- return BufferPolygon;
- }
-
- _getMaterialClass() {
- return BufferPolygonMaterial;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // COLLECTION LIFECYCLE
-
- /**
- * @private
- * @ignore
- */
- _allocateHoleIndexBuffer() {
- // @ts-expect-error Requires https://github.com/CesiumGS/cesium/pull/13203.
- this._holeIndexView = IndexDatatype.createTypedArray(
- this._positionCountMax,
- this._holeCountMax,
- );
- }
-
- /**
- * @private
- * @ignore
- */
- _allocateTriangleIndexBuffer() {
- // @ts-expect-error Requires https://github.com/CesiumGS/cesium/pull/13203.
- this._triangleIndexView = IndexDatatype.createTypedArray(
- this._positionCountMax,
- this._triangleCountMax * 3,
- );
- }
-
- /**
- * Duplicates the contents of this collection into the result collection.
- * Result collection is not resized, and must contain enough space for all
- * primitives in the source collection. Existing polygons in the result
- * collection will be overwritten.
- *
- * <p>Useful when allocating more space for a collection that has reached its
- * capacity, and efficiently transferring polygons to the new collection.</p>
- *
- * @example
- * const result = new BufferPolygonCollection({ ... }); // allocate larger 'result' collection
- * BufferPolygonCollection.clone(collection, result); // copy polygons from 'collection' into 'result'
- *
- * @param {BufferPolygonCollection} collection
- * @param {BufferPolygonCollection} result
- * @returns {BufferPolygonCollection}
- */
- static clone(collection, result) {
- super.clone(collection, result);
-
- //>>includeStart('debug', pragmas.debug);
- assert(collection.holeCount <= result.holeCountMax, ERR_CAPACITY);
- assert(collection.triangleCount <= result.triangleCountMax, ERR_CAPACITY);
- //>>includeEnd('debug');
-
- this._copySubArray(
- collection._holeIndexView,
- result._holeIndexView,
- collection.holeCount,
- );
-
- this._copySubArray(
- collection._triangleIndexView,
- result._triangleIndexView,
- collection._triangleCount * 3,
- );
-
- result._holeCount = collection._holeCount;
- result._triangleCount = collection._triangleCount;
-
- return result;
- }
-
- /**
- * @param {BufferPolygonCollection} collection
- * @returns {BufferPolygonCollection}
- * @override
- * @ignore
- */
- static _cloneEmpty(collection) {
- return new BufferPolygonCollection({
- primitiveCountMax: collection.primitiveCountMax,
- vertexCountMax: collection.vertexCountMax,
- holeCountMax: collection.holeCountMax,
- triangleCountMax: collection.triangleCountMax,
- positionDatatype: collection.positionDatatype,
- positionNormalized: collection.positionNormalized,
- });
- }
-
- /**
- * @param {BufferPolygonCollection} src
- * @param {BufferPolygonCollection} dst
- * @override
- * @ignore
- */
- static _replaceBuffers(src, dst) {
- super._replaceBuffers(src, dst);
- dst._holeIndexView = src._holeIndexView;
- dst._triangleIndexView = src._triangleIndexView;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // PRIMITIVE LIFECYCLE
-
- /**
- * Adds a new polygon to the collection, with the specified options. A
- * {@link BufferPolygon} instance is linked to the new polygon, using
- * the 'result' argument if given, or a new instance if not. For repeated
- * calls, prefer to reuse a single BufferPolygon instance rather than
- * allocating a new instance on each call.
- *
- * @param {BufferPolygonOptions} options
- * @param {BufferPolygon} result
- * @returns {BufferPolygon}
- * @override
- */
- add(options, result = new BufferPolygon()) {
- super.add(options, result);
-
- const vertexOffset = this._positionCount;
- result._setUint32(BufferPolygon.Layout.POSITION_OFFSET_U32, vertexOffset);
- result._setUint32(BufferPolygon.Layout.POSITION_COUNT_U32, 0);
-
- const holeOffset = this._holeCount;
- result._setUint32(BufferPolygon.Layout.HOLE_OFFSET_U32, holeOffset);
- result._setUint32(BufferPolygon.Layout.HOLE_COUNT_U32, 0);
-
- const triangleOffset = this._triangleCount;
- result._setUint32(BufferPolygon.Layout.TRIANGLE_OFFSET_U32, triangleOffset);
- result._setUint32(BufferPolygon.Layout.TRIANGLE_COUNT_U32, 0);
-
- if (defined(options.positions)) {
- result.setPositions(options.positions);
- }
-
- if (defined(options.holes)) {
- result.setHoles(options.holes);
- }
-
- if (defined(options.triangles)) {
- result.setTriangles(options.triangles);
- }
-
- return result;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // RENDER
-
- /**
- * @param {FrameState} frameState
- * @ignore
- */
- update(frameState) {
- super.update(frameState);
-
- const passes = frameState.passes;
- if (this.show && (passes.render || passes.pick)) {
- this._renderContext = renderPolygons(
- this,
- frameState,
- this._renderContext,
- );
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // ACCESSORS
-
- /**
- * Total byte length of buffers owned by this collection. Includes any unused
- * space allocated by {@link primitiveCountMax}, even if no polygons have
- * yet been added in that space.
- *
- * @type {number}
- * @readonly
- * @override
- */
- get byteLength() {
- return (
- super.byteLength +
- this._holeIndexView.byteLength +
- this._triangleIndexView.byteLength
- );
- }
-
- /**
- * Number of holes in collection. Must be <= {@link holeCountMax}.
- *
- * @type {number}
- * @readonly
- */
- get holeCount() {
- return this._holeCount;
- }
-
- /**
- * Maximum number of holes in collection. Must be >= {@link holeCount}.
- *
- * @type {number}
- * @readonly
- * @default {@link BufferPrimitiveCollection.DEFAULT_CAPACITY}
- */
- get holeCountMax() {
- return this._holeCountMax;
- }
-
- /**
- * Number of triangles in collection. Must be <= {@link triangleCountMax}.
- *
- * @type {number}
- * @readonly
- */
- get triangleCount() {
- return this._triangleCount;
- }
-
- /**
- * Maximum number of triangles in collection. Must be >= {@link triangleCount}.
- *
- * @type {number}
- * @readonly
- * @default {@link BufferPrimitiveCollection.DEFAULT_CAPACITY}
- */
- get triangleCountMax() {
- return this._triangleCountMax;
- }
- }
- export default BufferPolygonCollection;
|