| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- // @ts-check
-
- import assert from "../Core/assert.js";
-
- /** @import BufferPrimitiveCollection from './BufferPrimitiveCollection.js'; */
- /** @import BufferPrimitiveMaterial from "./BufferPrimitiveMaterial.js"; */
-
- /**
- * View bound to the underlying buffer data of a {@link BufferPrimitiveCollection}. Abstract.
- *
- * <p>BufferPrimitive instances are intended to be reused when iterating over large collections,
- * and temporarily bound to a primitive index while performing read/write operations on that primitive,
- * before being rebound to the next primitive, using the
- * {@link https://en.wikipedia.org/wiki/Flyweight_pattern|flyweight pattern}.</p>
- *
- * @see BufferPrimitiveCollection
- * @see BufferPrimitiveMaterial
- * @see BufferPoint
- * @see BufferPolyline
- * @see BufferPolygon
- *
- * @abstract
- * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
- */
- class BufferPrimitive {
- /**
- * Collecton containing the primitive(s) for which this instance currently
- * provides a view.
- *
- * @type {BufferPrimitiveCollection<BufferPrimitive>}
- * @ignore
- */
- _collection = null;
-
- /**
- * Index of the primitive for which this instance currently provides a view.
- *
- * @type {number}
- * @ignore
- */
- _index = -1;
-
- /**
- * Byte offset, into the collection's primitive buffer, of the primitive for
- * which this instance currently provides a view.
- *
- * @type {number}
- * @ignore
- */
- _byteOffset = -1;
-
- /**
- * Binary layout for this primitive type in collection's primitive buffer.
- * Each `Layout.MY_KEY_U32` entry is an offset in bytes, relative to the
- * start offset of the primitive, with the suffix indicating the data type
- * stored at that offset.
- *
- * The final entry, `__BYTE_LENGTH`, is not a pointer into a buffer — its
- * literal value is the total byte length of one primitive in the primitive
- * buffer, exclusive of other buffers.
- *
- * @ignore
- */
- static Layout = {
- /**
- * Feature ID associated with the primitive; not required to be unique.
- * @type {number}
- * @ignore
- */
- FEATURE_ID_U32: 0,
-
- /**
- * Boolean (0 or 1) flag indicating whether primitive is shown.
- * @type {number}
- * @ignore
- */
- SHOW_U8: 4,
-
- /**
- * Boolean (0 or 1) flag indicating whether primitive is dirty.
- * @type {number}
- * @ignore
- */
- DIRTY_U8: 5,
-
- /**
- * Pick ID (uint32) of primitive.
- * @type {number}
- * @ignore
- */
- PICK_ID_U32: 8,
-
- /**
- * Byte length of one primitive in the primitive buffer, exclusive of
- * other buffers. Literal value, not a pointer.
- * @type {number}
- * @ignore
- */
- __BYTE_LENGTH: 12,
- };
-
- /////////////////////////////////////////////////////////////////////////////
- // LIFECYCLE
-
- /**
- * Copies data from source primitive to result. If the result primitive is not
- * new (the last primitive in the collection) then source and result primitives
- * must have the same vertex counts.
- *
- * @param {BufferPrimitive} primitive
- * @param {BufferPrimitive} result
- * @returns {BufferPrimitive}
- */
- static clone(primitive, result) {
- const SrcMaterialClass = primitive._collection._getMaterialClass();
-
- //>>includeStart('debug', pragmas.debug);
- const DstMaterialClass = result._collection._getMaterialClass();
- assert(SrcMaterialClass === DstMaterialClass, "Incompatible materials");
- //>>includeEnd('debug');
-
- result.featureId = primitive.featureId;
- result.show = primitive.show;
- result.setMaterial(primitive.getMaterial(new SrcMaterialClass()));
- return result;
- }
-
- /**
- * Returns true if this primitive's memory footprint is resizable. Only the
- * newest (most recently created) primitive in a collection can be resized,
- * to guarantee fast and stable performance.
- *
- * @returns {boolean}
- * @protected
- * @ignore
- */
- _isResizable() {
- return this._index === this._collection.primitiveCount - 1;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // ACCESSORS
-
- /**
- * Feature ID associated with the primitive; not required to be unique.
- * @type {number}
- */
- get featureId() {
- return this._getUint32(BufferPrimitive.Layout.FEATURE_ID_U32);
- }
-
- set featureId(featureId) {
- this._setUint32(BufferPrimitive.Layout.FEATURE_ID_U32, featureId);
- }
-
- /**
- * Whether primitive is shown.
- * @type {boolean}
- */
- get show() {
- return this._getUint8(BufferPrimitive.Layout.SHOW_U8) === 1;
- }
-
- set show(show) {
- this._setUint8(BufferPrimitive.Layout.SHOW_U8, show ? 1 : 0);
- }
-
- /**
- * @param {BufferPrimitiveMaterial} result
- * @returns {BufferPrimitiveMaterial}
- */
- getMaterial(result) {
- const collection = this._collection;
- const MaterialClass = collection._getMaterialClass();
-
- return MaterialClass.unpack(
- collection._materialView,
- this._index * MaterialClass.packedLength,
- result,
- );
- }
-
- /**
- * @param {BufferPrimitiveMaterial} material
- */
- setMaterial(material) {
- const collection = this._collection;
- const MaterialClass = collection._getMaterialClass();
-
- MaterialClass.pack(
- material,
- collection._materialView,
- this._index * MaterialClass.packedLength,
- );
-
- this._dirty = true;
-
- return material;
- }
-
- /**
- * Whether the primitive requires an update on next render. Renderers should
- * _not_ iterate over all primitives each frame, but must instead inspect
- * only the dirty range of the parent collection. This flag is managed
- * automatically, by primitive setters and collection renderers.
- *
- * @type {boolean}
- * @ignore
- *
- * @see BufferPrimitiveCollection#_dirtyOffset
- * @see BufferPrimitiveCollection#_dirtyCount
- */
- get _dirty() {
- return this._getUint8(BufferPrimitive.Layout.DIRTY_U8) === 1;
- }
-
- set _dirty(dirty) {
- // Avoid `._setUint8()` here, which would infinitely loop `._dirty = true`.
- this._collection._primitiveView.setUint8(
- this._byteOffset + BufferPrimitive.Layout.DIRTY_U8,
- dirty ? 1 : 0,
- );
-
- // A 'dirty' primitive is responsible for notifying the collection. Applying
- // updates and marking the primitive 'clean' will be handled by the collection,
- // so we don't notify the collection here in that case.
- if (dirty) {
- this._collection._makeDirty(this._index);
- }
- }
-
- /**
- * Pick ID (uint32) of primitive.
- * @type {number}
- * @ignore
- */
- get _pickId() {
- return this._getUint32(BufferPrimitive.Layout.PICK_ID_U32);
- }
-
- set _pickId(pickId) {
- this._setUint32(BufferPrimitive.Layout.PICK_ID_U32, pickId);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // BUFFER ACCESSORS
-
- /**
- * @param {number} itemByteOffset
- * @returns {number}
- * @ignore
- */
- _getUint8(itemByteOffset) {
- return this._collection._primitiveView.getUint8(
- this._byteOffset + itemByteOffset,
- );
- }
-
- /**
- * @param {number} itemByteOffset
- * @param {number} itemValue
- * @ignore
- */
- _setUint8(itemByteOffset, itemValue) {
- this._collection._primitiveView.setUint8(
- this._byteOffset + itemByteOffset,
- itemValue,
- );
- this._dirty = true;
- }
-
- /**
- * @param {number} itemByteOffset
- * @returns {number}
- * @ignore
- */
- _getUint32(itemByteOffset) {
- return this._collection._primitiveView.getUint32(
- this._byteOffset + itemByteOffset,
- true,
- );
- }
-
- /**
- * @param {number} itemByteOffset
- * @param {number} itemValue
- * @ignore
- */
- _setUint32(itemByteOffset, itemValue) {
- this._collection._primitiveView.setUint32(
- this._byteOffset + itemByteOffset,
- itemValue,
- true,
- );
- this._dirty = true;
- }
-
- /**
- * @param {number} itemByteOffset
- * @returns {number}
- * @ignore
- */
- _getFloat32(itemByteOffset) {
- return this._collection._primitiveView.getFloat32(
- this._byteOffset + itemByteOffset,
- true,
- );
- }
-
- /**
- * @param {number} itemByteOffset
- * @param {number} itemValue
- * @ignore
- */
- _setFloat32(itemByteOffset, itemValue) {
- this._collection._primitiveView.setFloat32(
- this._byteOffset + itemByteOffset,
- itemValue,
- true,
- );
- this._dirty = true;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // DEBUG
-
- /**
- * Returns a JSON-serializable object representing the primitive. This encoding
- * is not memory-efficient, and should generally be used for debugging and
- * testing.
- *
- * @returns {Object} JSON-serializable object.
- */
- toJSON() {
- const collection = this._collection;
- const MaterialClass = collection._getMaterialClass();
-
- return {
- featureId: this.featureId,
- show: this.show,
- dirty: this._dirty,
- material: this.getMaterial(new MaterialClass()).toJSON(),
- };
- }
- }
-
- export default BufferPrimitive;
|