| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282 | 
							- import Cartesian3 from "../Core/Cartesian3.js";
 
- import Color from "../Core/Color.js";
 
- import ComponentDatatype from "../Core/ComponentDatatype.js";
 
- import defaultValue from "../Core/defaultValue.js";
 
- import defined from "../Core/defined.js";
 
- import destroyObject from "../Core/destroyObject.js";
 
- import IndexDatatype from "../Core/IndexDatatype.js";
 
- import Matrix4 from "../Core/Matrix4.js";
 
- import PrimitiveType from "../Core/PrimitiveType.js";
 
- import Buffer from "../Renderer/Buffer.js";
 
- import BufferUsage from "../Renderer/BufferUsage.js";
 
- import DrawCommand from "../Renderer/DrawCommand.js";
 
- import Pass from "../Renderer/Pass.js";
 
- import RenderState from "../Renderer/RenderState.js";
 
- import ShaderProgram from "../Renderer/ShaderProgram.js";
 
- import ShaderSource from "../Renderer/ShaderSource.js";
 
- import VertexArray from "../Renderer/VertexArray.js";
 
- import ShadowVolumeFS from "../Shaders/ShadowVolumeFS.js";
 
- import VectorTileVS from "../Shaders/VectorTileVS.js";
 
- import BlendingState from "./BlendingState.js";
 
- import Cesium3DTileFeature from "./Cesium3DTileFeature.js";
 
- import ClassificationType from "./ClassificationType.js";
 
- import DepthFunction from "./DepthFunction.js";
 
- import Expression from "./Expression.js";
 
- import StencilConstants from "./StencilConstants.js";
 
- import StencilFunction from "./StencilFunction.js";
 
- import StencilOperation from "./StencilOperation.js";
 
- import Vector3DTileBatch from "./Vector3DTileBatch.js";
 
- /**
 
-  * Creates a batch of classification meshes.
 
-  *
 
-  * @alias Vector3DTilePrimitive
 
-  * @constructor
 
-  *
 
-  * @param {Object} options An object with following properties:
 
-  * @param {Float32Array} options.positions The positions of the meshes.
 
-  * @param {Uint16Array|Uint32Array} options.indices The indices of the triangulated meshes. The indices must be contiguous so that
 
-  * the indices for mesh n are in [i, i + indexCounts[n]] where i = sum{indexCounts[0], indexCounts[n - 1]}.
 
-  * @param {Uint32Array} options.indexCounts The number of indices for each mesh.
 
-  * @param {Uint32Array} options.indexOffsets The offset into the index buffer for each mesh.
 
-  * @param {Vector3DTileBatch[]} options.batchedIndices The index offset and count for each batch with the same color.
 
-  * @param {Cartesian3} [options.center=Cartesian3.ZERO] The RTC center.
 
-  * @param {Cesium3DTileBatchTable} options.batchTable The batch table for the tile containing the batched meshes.
 
-  * @param {Uint16Array} options.batchIds The batch ids for each mesh.
 
-  * @param {Uint16Array} options.vertexBatchIds The batch id for each vertex.
 
-  * @param {BoundingSphere} options.boundingVolume The bounding volume for the entire batch of meshes.
 
-  * @param {BoundingSphere[]} options.boundingVolumes The bounding volume for each mesh.
 
-  * @param {ClassificationType} [options.classificationType] What this tile will classify.
 
-  *
 
-  * @private
 
-  */
 
- function Vector3DTilePrimitive(options) {
 
-   options = defaultValue(options, defaultValue.EMPTY_OBJECT);
 
-   this._batchTable = options.batchTable;
 
-   this._batchIds = options.batchIds;
 
-   // These arrays are released after VAO creation.
 
-   this._positions = options.positions;
 
-   this._vertexBatchIds = options.vertexBatchIds;
 
-   // These arrays are kept for re-batching indices based on colors.
 
-   // If WebGL 2 is supported, indices will be released and re-batching uses buffer-to-buffer copies.
 
-   this._indices = options.indices;
 
-   this._indexCounts = options.indexCounts;
 
-   this._indexOffsets = options.indexOffsets;
 
-   this._batchedIndices = options.batchedIndices;
 
-   this._boundingVolume = options.boundingVolume;
 
-   this._boundingVolumes = options.boundingVolumes;
 
-   this._center = defaultValue(options.center, Cartesian3.ZERO);
 
-   this._va = undefined;
 
-   this._sp = undefined;
 
-   this._spStencil = undefined;
 
-   this._spPick = undefined;
 
-   this._uniformMap = undefined;
 
-   // Only used with WebGL 2 to ping-pong ibos after copy.
 
-   this._vaSwap = undefined;
 
-   this._rsStencilDepthPass = undefined;
 
-   this._rsStencilDepthPass3DTiles = undefined;
 
-   this._rsColorPass = undefined;
 
-   this._rsPickPass = undefined;
 
-   this._rsWireframe = undefined;
 
-   this._commands = [];
 
-   this._commandsIgnoreShow = [];
 
-   this._pickCommands = [];
 
-   this._constantColor = Color.clone(Color.WHITE);
 
-   this._highlightColor = this._constantColor;
 
-   this._batchDirty = true;
 
-   this._pickCommandsDirty = true;
 
-   this._framesSinceLastRebatch = 0;
 
-   this._updatingAllCommands = false;
 
-   this._trianglesLength = this._indices.length / 3;
 
-   this._geometryByteLength =
 
-     this._indices.byteLength +
 
-     this._positions.byteLength +
 
-     this._vertexBatchIds.byteLength;
 
-   /**
 
-    * Draw the wireframe of the classification meshes.
 
-    * @type {Boolean}
 
-    * @default false
 
-    */
 
-   this.debugWireframe = false;
 
-   this._debugWireframe = this.debugWireframe;
 
-   this._wireframeDirty = false;
 
-   /**
 
-    * Forces a re-batch instead of waiting after a number of frames have been rendered. For testing only.
 
-    * @type {Boolean}
 
-    * @default false
 
-    */
 
-   this.forceRebatch = false;
 
-   /**
 
-    * What this tile will classify.
 
-    * @type {ClassificationType}
 
-    * @default ClassificationType.BOTH
 
-    */
 
-   this.classificationType = defaultValue(
 
-     options.classificationType,
 
-     ClassificationType.BOTH
 
-   );
 
-   // Hidden options
 
-   this._vertexShaderSource = options._vertexShaderSource;
 
-   this._fragmentShaderSource = options._fragmentShaderSource;
 
-   this._attributeLocations = options._attributeLocations;
 
-   this._uniformMap = options._uniformMap;
 
-   this._pickId = options._pickId;
 
-   this._modelMatrix = options._modelMatrix;
 
-   this._boundingSphere = options._boundingSphere;
 
-   this._batchIdLookUp = {};
 
-   const length = this._batchIds.length;
 
-   for (let i = 0; i < length; ++i) {
 
-     const batchId = this._batchIds[i];
 
-     this._batchIdLookUp[batchId] = i;
 
-   }
 
- }
 
- Object.defineProperties(Vector3DTilePrimitive.prototype, {
 
-   /**
 
-    * Gets the number of triangles.
 
-    *
 
-    * @memberof Vector3DTilePrimitive.prototype
 
-    *
 
-    * @type {Number}
 
-    * @readonly
 
-    */
 
-   trianglesLength: {
 
-     get: function () {
 
-       return this._trianglesLength;
 
-     },
 
-   },
 
-   /**
 
-    * Gets the geometry memory in bytes.
 
-    *
 
-    * @memberof Vector3DTilePrimitive.prototype
 
-    *
 
-    * @type {Number}
 
-    * @readonly
 
-    */
 
-   geometryByteLength: {
 
-     get: function () {
 
-       return this._geometryByteLength;
 
-     },
 
-   },
 
- });
 
- const defaultAttributeLocations = {
 
-   position: 0,
 
-   a_batchId: 1,
 
- };
 
- function createVertexArray(primitive, context) {
 
-   if (defined(primitive._va)) {
 
-     return;
 
-   }
 
-   const positionBuffer = Buffer.createVertexBuffer({
 
-     context: context,
 
-     typedArray: primitive._positions,
 
-     usage: BufferUsage.STATIC_DRAW,
 
-   });
 
-   const idBuffer = Buffer.createVertexBuffer({
 
-     context: context,
 
-     typedArray: primitive._vertexBatchIds,
 
-     usage: BufferUsage.STATIC_DRAW,
 
-   });
 
-   const indexBuffer = Buffer.createIndexBuffer({
 
-     context: context,
 
-     typedArray: primitive._indices,
 
-     usage: BufferUsage.DYNAMIC_DRAW,
 
-     indexDatatype:
 
-       primitive._indices.BYTES_PER_ELEMENT === 2
 
-         ? IndexDatatype.UNSIGNED_SHORT
 
-         : IndexDatatype.UNSIGNED_INT,
 
-   });
 
-   const vertexAttributes = [
 
-     {
 
-       index: 0,
 
-       vertexBuffer: positionBuffer,
 
-       componentDatatype: ComponentDatatype.fromTypedArray(primitive._positions),
 
-       componentsPerAttribute: 3,
 
-     },
 
-     {
 
-       index: 1,
 
-       vertexBuffer: idBuffer,
 
-       componentDatatype: ComponentDatatype.fromTypedArray(
 
-         primitive._vertexBatchIds
 
-       ),
 
-       componentsPerAttribute: 1,
 
-     },
 
-   ];
 
-   primitive._va = new VertexArray({
 
-     context: context,
 
-     attributes: vertexAttributes,
 
-     indexBuffer: indexBuffer,
 
-   });
 
-   if (context.webgl2) {
 
-     primitive._vaSwap = new VertexArray({
 
-       context: context,
 
-       attributes: vertexAttributes,
 
-       indexBuffer: Buffer.createIndexBuffer({
 
-         context: context,
 
-         sizeInBytes: indexBuffer.sizeInBytes,
 
-         usage: BufferUsage.DYNAMIC_DRAW,
 
-         indexDatatype: indexBuffer.indexDatatype,
 
-       }),
 
-     });
 
-   }
 
-   primitive._batchedPositions = undefined;
 
-   primitive._transferrableBatchIds = undefined;
 
-   primitive._vertexBatchIds = undefined;
 
-   primitive._verticesPromise = undefined;
 
- }
 
- function createShaders(primitive, context) {
 
-   if (defined(primitive._sp)) {
 
-     return;
 
-   }
 
-   const batchTable = primitive._batchTable;
 
-   const attributeLocations = defaultValue(
 
-     primitive._attributeLocations,
 
-     defaultAttributeLocations
 
-   );
 
-   let pickId = primitive._pickId;
 
-   const vertexShaderSource = primitive._vertexShaderSource;
 
-   let fragmentShaderSource = primitive._fragmentShaderSource;
 
-   if (defined(vertexShaderSource)) {
 
-     primitive._sp = ShaderProgram.fromCache({
 
-       context: context,
 
-       vertexShaderSource: vertexShaderSource,
 
-       fragmentShaderSource: fragmentShaderSource,
 
-       attributeLocations: attributeLocations,
 
-     });
 
-     primitive._spStencil = primitive._sp;
 
-     fragmentShaderSource = ShaderSource.replaceMain(
 
-       fragmentShaderSource,
 
-       "czm_non_pick_main"
 
-     );
 
-     fragmentShaderSource =
 
-       `${fragmentShaderSource}void main() \n` +
 
-       `{ \n` +
 
-       `    czm_non_pick_main(); \n` +
 
-       `    gl_FragColor = ${pickId}; \n` +
 
-       `} \n`;
 
-     primitive._spPick = ShaderProgram.fromCache({
 
-       context: context,
 
-       vertexShaderSource: vertexShaderSource,
 
-       fragmentShaderSource: fragmentShaderSource,
 
-       attributeLocations: attributeLocations,
 
-     });
 
-     return;
 
-   }
 
-   const vsSource = batchTable.getVertexShaderCallback(
 
-     false,
 
-     "a_batchId",
 
-     undefined
 
-   )(VectorTileVS);
 
-   let fsSource = batchTable.getFragmentShaderCallback(
 
-     false,
 
-     undefined,
 
-     true
 
-   )(ShadowVolumeFS);
 
-   pickId = batchTable.getPickId();
 
-   let vs = new ShaderSource({
 
-     sources: [vsSource],
 
-   });
 
-   let fs = new ShaderSource({
 
-     defines: ["VECTOR_TILE"],
 
-     sources: [fsSource],
 
-   });
 
-   primitive._sp = ShaderProgram.fromCache({
 
-     context: context,
 
-     vertexShaderSource: vs,
 
-     fragmentShaderSource: fs,
 
-     attributeLocations: attributeLocations,
 
-   });
 
-   vs = new ShaderSource({
 
-     sources: [VectorTileVS],
 
-   });
 
-   fs = new ShaderSource({
 
-     defines: ["VECTOR_TILE"],
 
-     sources: [ShadowVolumeFS],
 
-   });
 
-   primitive._spStencil = ShaderProgram.fromCache({
 
-     context: context,
 
-     vertexShaderSource: vs,
 
-     fragmentShaderSource: fs,
 
-     attributeLocations: attributeLocations,
 
-   });
 
-   fsSource = ShaderSource.replaceMain(fsSource, "czm_non_pick_main");
 
-   fsSource =
 
-     `${fsSource}\n` +
 
-     `void main() \n` +
 
-     `{ \n` +
 
-     `    czm_non_pick_main(); \n` +
 
-     `    gl_FragColor = ${pickId}; \n` +
 
-     `} \n`;
 
-   const pickVS = new ShaderSource({
 
-     sources: [vsSource],
 
-   });
 
-   const pickFS = new ShaderSource({
 
-     defines: ["VECTOR_TILE"],
 
-     sources: [fsSource],
 
-   });
 
-   primitive._spPick = ShaderProgram.fromCache({
 
-     context: context,
 
-     vertexShaderSource: pickVS,
 
-     fragmentShaderSource: pickFS,
 
-     attributeLocations: attributeLocations,
 
-   });
 
- }
 
- function getStencilDepthRenderState(mask3DTiles) {
 
-   const stencilFunction = mask3DTiles
 
-     ? StencilFunction.EQUAL
 
-     : StencilFunction.ALWAYS;
 
-   return {
 
-     colorMask: {
 
-       red: false,
 
-       green: false,
 
-       blue: false,
 
-       alpha: false,
 
-     },
 
-     stencilTest: {
 
-       enabled: true,
 
-       frontFunction: stencilFunction,
 
-       frontOperation: {
 
-         fail: StencilOperation.KEEP,
 
-         zFail: StencilOperation.DECREMENT_WRAP,
 
-         zPass: StencilOperation.KEEP,
 
-       },
 
-       backFunction: stencilFunction,
 
-       backOperation: {
 
-         fail: StencilOperation.KEEP,
 
-         zFail: StencilOperation.INCREMENT_WRAP,
 
-         zPass: StencilOperation.KEEP,
 
-       },
 
-       reference: StencilConstants.CESIUM_3D_TILE_MASK,
 
-       mask: StencilConstants.CESIUM_3D_TILE_MASK,
 
-     },
 
-     stencilMask: StencilConstants.CLASSIFICATION_MASK,
 
-     depthTest: {
 
-       enabled: true,
 
-       func: DepthFunction.LESS_OR_EQUAL,
 
-     },
 
-     depthMask: false,
 
-   };
 
- }
 
- const colorRenderState = {
 
-   stencilTest: {
 
-     enabled: true,
 
-     frontFunction: StencilFunction.NOT_EQUAL,
 
-     frontOperation: {
 
-       fail: StencilOperation.ZERO,
 
-       zFail: StencilOperation.ZERO,
 
-       zPass: StencilOperation.ZERO,
 
-     },
 
-     backFunction: StencilFunction.NOT_EQUAL,
 
-     backOperation: {
 
-       fail: StencilOperation.ZERO,
 
-       zFail: StencilOperation.ZERO,
 
-       zPass: StencilOperation.ZERO,
 
-     },
 
-     reference: 0,
 
-     mask: StencilConstants.CLASSIFICATION_MASK,
 
-   },
 
-   stencilMask: StencilConstants.CLASSIFICATION_MASK,
 
-   depthTest: {
 
-     enabled: false,
 
-   },
 
-   depthMask: false,
 
-   blending: BlendingState.PRE_MULTIPLIED_ALPHA_BLEND,
 
- };
 
- const pickRenderState = {
 
-   stencilTest: {
 
-     enabled: true,
 
-     frontFunction: StencilFunction.NOT_EQUAL,
 
-     frontOperation: {
 
-       fail: StencilOperation.ZERO,
 
-       zFail: StencilOperation.ZERO,
 
-       zPass: StencilOperation.ZERO,
 
-     },
 
-     backFunction: StencilFunction.NOT_EQUAL,
 
-     backOperation: {
 
-       fail: StencilOperation.ZERO,
 
-       zFail: StencilOperation.ZERO,
 
-       zPass: StencilOperation.ZERO,
 
-     },
 
-     reference: 0,
 
-     mask: StencilConstants.CLASSIFICATION_MASK,
 
-   },
 
-   stencilMask: StencilConstants.CLASSIFICATION_MASK,
 
-   depthTest: {
 
-     enabled: false,
 
-   },
 
-   depthMask: false,
 
- };
 
- function createRenderStates(primitive) {
 
-   if (defined(primitive._rsStencilDepthPass)) {
 
-     return;
 
-   }
 
-   primitive._rsStencilDepthPass = RenderState.fromCache(
 
-     getStencilDepthRenderState(false)
 
-   );
 
-   primitive._rsStencilDepthPass3DTiles = RenderState.fromCache(
 
-     getStencilDepthRenderState(true)
 
-   );
 
-   primitive._rsColorPass = RenderState.fromCache(colorRenderState);
 
-   primitive._rsPickPass = RenderState.fromCache(pickRenderState);
 
- }
 
- const modifiedModelViewScratch = new Matrix4();
 
- const rtcScratch = new Cartesian3();
 
- function createUniformMap(primitive, context) {
 
-   if (defined(primitive._uniformMap)) {
 
-     return;
 
-   }
 
-   const uniformMap = {
 
-     u_modifiedModelViewProjection: function () {
 
-       const viewMatrix = context.uniformState.view;
 
-       const projectionMatrix = context.uniformState.projection;
 
-       Matrix4.clone(viewMatrix, modifiedModelViewScratch);
 
-       Matrix4.multiplyByPoint(
 
-         modifiedModelViewScratch,
 
-         primitive._center,
 
-         rtcScratch
 
-       );
 
-       Matrix4.setTranslation(
 
-         modifiedModelViewScratch,
 
-         rtcScratch,
 
-         modifiedModelViewScratch
 
-       );
 
-       Matrix4.multiply(
 
-         projectionMatrix,
 
-         modifiedModelViewScratch,
 
-         modifiedModelViewScratch
 
-       );
 
-       return modifiedModelViewScratch;
 
-     },
 
-     u_highlightColor: function () {
 
-       return primitive._highlightColor;
 
-     },
 
-   };
 
-   primitive._uniformMap = primitive._batchTable.getUniformMapCallback()(
 
-     uniformMap
 
-   );
 
- }
 
- function copyIndicesCPU(
 
-   indices,
 
-   newIndices,
 
-   currentOffset,
 
-   offsets,
 
-   counts,
 
-   batchIds,
 
-   batchIdLookUp
 
- ) {
 
-   const sizeInBytes = indices.constructor.BYTES_PER_ELEMENT;
 
-   const batchedIdsLength = batchIds.length;
 
-   for (let j = 0; j < batchedIdsLength; ++j) {
 
-     const batchedId = batchIds[j];
 
-     const index = batchIdLookUp[batchedId];
 
-     const offset = offsets[index];
 
-     const count = counts[index];
 
-     const subarray = new indices.constructor(
 
-       indices.buffer,
 
-       sizeInBytes * offset,
 
-       count
 
-     );
 
-     newIndices.set(subarray, currentOffset);
 
-     offsets[index] = currentOffset;
 
-     currentOffset += count;
 
-   }
 
-   return currentOffset;
 
- }
 
- function rebatchCPU(primitive, batchedIndices) {
 
-   const indices = primitive._indices;
 
-   const indexOffsets = primitive._indexOffsets;
 
-   const indexCounts = primitive._indexCounts;
 
-   const batchIdLookUp = primitive._batchIdLookUp;
 
-   const newIndices = new indices.constructor(indices.length);
 
-   let current = batchedIndices.pop();
 
-   const newBatchedIndices = [current];
 
-   let currentOffset = copyIndicesCPU(
 
-     indices,
 
-     newIndices,
 
-     0,
 
-     indexOffsets,
 
-     indexCounts,
 
-     current.batchIds,
 
-     batchIdLookUp
 
-   );
 
-   current.offset = 0;
 
-   current.count = currentOffset;
 
-   while (batchedIndices.length > 0) {
 
-     const next = batchedIndices.pop();
 
-     if (Color.equals(next.color, current.color)) {
 
-       currentOffset = copyIndicesCPU(
 
-         indices,
 
-         newIndices,
 
-         currentOffset,
 
-         indexOffsets,
 
-         indexCounts,
 
-         next.batchIds,
 
-         batchIdLookUp
 
-       );
 
-       current.batchIds = current.batchIds.concat(next.batchIds);
 
-       current.count = currentOffset - current.offset;
 
-     } else {
 
-       const offset = currentOffset;
 
-       currentOffset = copyIndicesCPU(
 
-         indices,
 
-         newIndices,
 
-         currentOffset,
 
-         indexOffsets,
 
-         indexCounts,
 
-         next.batchIds,
 
-         batchIdLookUp
 
-       );
 
-       next.offset = offset;
 
-       next.count = currentOffset - offset;
 
-       newBatchedIndices.push(next);
 
-       current = next;
 
-     }
 
-   }
 
-   primitive._va.indexBuffer.copyFromArrayView(newIndices);
 
-   primitive._indices = newIndices;
 
-   primitive._batchedIndices = newBatchedIndices;
 
- }
 
- function copyIndicesGPU(
 
-   readBuffer,
 
-   writeBuffer,
 
-   currentOffset,
 
-   offsets,
 
-   counts,
 
-   batchIds,
 
-   batchIdLookUp
 
- ) {
 
-   const sizeInBytes = readBuffer.bytesPerIndex;
 
-   const batchedIdsLength = batchIds.length;
 
-   for (let j = 0; j < batchedIdsLength; ++j) {
 
-     const batchedId = batchIds[j];
 
-     const index = batchIdLookUp[batchedId];
 
-     const offset = offsets[index];
 
-     const count = counts[index];
 
-     writeBuffer.copyFromBuffer(
 
-       readBuffer,
 
-       offset * sizeInBytes,
 
-       currentOffset * sizeInBytes,
 
-       count * sizeInBytes
 
-     );
 
-     offsets[index] = currentOffset;
 
-     currentOffset += count;
 
-   }
 
-   return currentOffset;
 
- }
 
- function rebatchGPU(primitive, batchedIndices) {
 
-   const indexOffsets = primitive._indexOffsets;
 
-   const indexCounts = primitive._indexCounts;
 
-   const batchIdLookUp = primitive._batchIdLookUp;
 
-   let current = batchedIndices.pop();
 
-   const newBatchedIndices = [current];
 
-   const readBuffer = primitive._va.indexBuffer;
 
-   const writeBuffer = primitive._vaSwap.indexBuffer;
 
-   let currentOffset = copyIndicesGPU(
 
-     readBuffer,
 
-     writeBuffer,
 
-     0,
 
-     indexOffsets,
 
-     indexCounts,
 
-     current.batchIds,
 
-     batchIdLookUp
 
-   );
 
-   current.offset = 0;
 
-   current.count = currentOffset;
 
-   while (batchedIndices.length > 0) {
 
-     const next = batchedIndices.pop();
 
-     if (Color.equals(next.color, current.color)) {
 
-       currentOffset = copyIndicesGPU(
 
-         readBuffer,
 
-         writeBuffer,
 
-         currentOffset,
 
-         indexOffsets,
 
-         indexCounts,
 
-         next.batchIds,
 
-         batchIdLookUp
 
-       );
 
-       current.batchIds = current.batchIds.concat(next.batchIds);
 
-       current.count = currentOffset - current.offset;
 
-     } else {
 
-       const offset = currentOffset;
 
-       currentOffset = copyIndicesGPU(
 
-         readBuffer,
 
-         writeBuffer,
 
-         currentOffset,
 
-         indexOffsets,
 
-         indexCounts,
 
-         next.batchIds,
 
-         batchIdLookUp
 
-       );
 
-       next.offset = offset;
 
-       next.count = currentOffset - offset;
 
-       newBatchedIndices.push(next);
 
-       current = next;
 
-     }
 
-   }
 
-   const temp = primitive._va;
 
-   primitive._va = primitive._vaSwap;
 
-   primitive._vaSwap = temp;
 
-   primitive._batchedIndices = newBatchedIndices;
 
- }
 
- function compareColors(a, b) {
 
-   return b.color.toRgba() - a.color.toRgba();
 
- }
 
- // PERFORMANCE_IDEA: For WebGL 2, we can use copyBufferSubData for buffer-to-buffer copies.
 
- // PERFORMANCE_IDEA: Not supported, but we could use glMultiDrawElements here.
 
- function rebatchCommands(primitive, context) {
 
-   if (!primitive._batchDirty) {
 
-     return false;
 
-   }
 
-   const batchedIndices = primitive._batchedIndices;
 
-   const length = batchedIndices.length;
 
-   let needToRebatch = false;
 
-   const colorCounts = {};
 
-   for (let i = 0; i < length; ++i) {
 
-     const color = batchedIndices[i].color;
 
-     const rgba = color.toRgba();
 
-     if (defined(colorCounts[rgba])) {
 
-       needToRebatch = true;
 
-       break;
 
-     } else {
 
-       colorCounts[rgba] = true;
 
-     }
 
-   }
 
-   if (!needToRebatch) {
 
-     primitive._batchDirty = false;
 
-     return false;
 
-   }
 
-   if (
 
-     needToRebatch &&
 
-     !primitive.forceRebatch &&
 
-     primitive._framesSinceLastRebatch < 120
 
-   ) {
 
-     ++primitive._framesSinceLastRebatch;
 
-     return;
 
-   }
 
-   batchedIndices.sort(compareColors);
 
-   if (context.webgl2) {
 
-     rebatchGPU(primitive, batchedIndices);
 
-   } else {
 
-     rebatchCPU(primitive, batchedIndices);
 
-   }
 
-   primitive._framesSinceLastRebatch = 0;
 
-   primitive._batchDirty = false;
 
-   primitive._pickCommandsDirty = true;
 
-   primitive._wireframeDirty = true;
 
-   return true;
 
- }
 
- function createColorCommands(primitive, context) {
 
-   const needsRebatch = rebatchCommands(primitive, context);
 
-   const commands = primitive._commands;
 
-   const batchedIndices = primitive._batchedIndices;
 
-   const length = batchedIndices.length;
 
-   const commandsLength = length * 2;
 
-   if (
 
-     defined(commands) &&
 
-     !needsRebatch &&
 
-     commands.length === commandsLength
 
-   ) {
 
-     return;
 
-   }
 
-   commands.length = commandsLength;
 
-   const vertexArray = primitive._va;
 
-   const sp = primitive._sp;
 
-   const modelMatrix = defaultValue(primitive._modelMatrix, Matrix4.IDENTITY);
 
-   const uniformMap = primitive._uniformMap;
 
-   const bv = primitive._boundingVolume;
 
-   for (let j = 0; j < length; ++j) {
 
-     const offset = batchedIndices[j].offset;
 
-     const count = batchedIndices[j].count;
 
-     let stencilDepthCommand = commands[j * 2];
 
-     if (!defined(stencilDepthCommand)) {
 
-       stencilDepthCommand = commands[j * 2] = new DrawCommand({
 
-         owner: primitive,
 
-       });
 
-     }
 
-     stencilDepthCommand.vertexArray = vertexArray;
 
-     stencilDepthCommand.modelMatrix = modelMatrix;
 
-     stencilDepthCommand.offset = offset;
 
-     stencilDepthCommand.count = count;
 
-     stencilDepthCommand.renderState = primitive._rsStencilDepthPass;
 
-     stencilDepthCommand.shaderProgram = sp;
 
-     stencilDepthCommand.uniformMap = uniformMap;
 
-     stencilDepthCommand.boundingVolume = bv;
 
-     stencilDepthCommand.cull = false;
 
-     stencilDepthCommand.pass = Pass.TERRAIN_CLASSIFICATION;
 
-     const stencilDepthDerivedCommand = DrawCommand.shallowClone(
 
-       stencilDepthCommand,
 
-       stencilDepthCommand.derivedCommands.tileset
 
-     );
 
-     stencilDepthDerivedCommand.renderState =
 
-       primitive._rsStencilDepthPass3DTiles;
 
-     stencilDepthDerivedCommand.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION;
 
-     stencilDepthCommand.derivedCommands.tileset = stencilDepthDerivedCommand;
 
-     let colorCommand = commands[j * 2 + 1];
 
-     if (!defined(colorCommand)) {
 
-       colorCommand = commands[j * 2 + 1] = new DrawCommand({
 
-         owner: primitive,
 
-       });
 
-     }
 
-     colorCommand.vertexArray = vertexArray;
 
-     colorCommand.modelMatrix = modelMatrix;
 
-     colorCommand.offset = offset;
 
-     colorCommand.count = count;
 
-     colorCommand.renderState = primitive._rsColorPass;
 
-     colorCommand.shaderProgram = sp;
 
-     colorCommand.uniformMap = uniformMap;
 
-     colorCommand.boundingVolume = bv;
 
-     colorCommand.cull = false;
 
-     colorCommand.pass = Pass.TERRAIN_CLASSIFICATION;
 
-     const colorDerivedCommand = DrawCommand.shallowClone(
 
-       colorCommand,
 
-       colorCommand.derivedCommands.tileset
 
-     );
 
-     colorDerivedCommand.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION;
 
-     colorCommand.derivedCommands.tileset = colorDerivedCommand;
 
-   }
 
-   primitive._commandsDirty = true;
 
- }
 
- function createColorCommandsIgnoreShow(primitive, frameState) {
 
-   if (
 
-     primitive.classificationType === ClassificationType.TERRAIN ||
 
-     !frameState.invertClassification ||
 
-     (defined(primitive._commandsIgnoreShow) && !primitive._commandsDirty)
 
-   ) {
 
-     return;
 
-   }
 
-   const commands = primitive._commands;
 
-   const commandsIgnoreShow = primitive._commandsIgnoreShow;
 
-   const spStencil = primitive._spStencil;
 
-   const commandsLength = commands.length;
 
-   const length = (commandsIgnoreShow.length = commandsLength / 2);
 
-   let commandIndex = 0;
 
-   for (let j = 0; j < length; ++j) {
 
-     const commandIgnoreShow = (commandsIgnoreShow[j] = DrawCommand.shallowClone(
 
-       commands[commandIndex],
 
-       commandsIgnoreShow[j]
 
-     ));
 
-     commandIgnoreShow.shaderProgram = spStencil;
 
-     commandIgnoreShow.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW;
 
-     commandIndex += 2;
 
-   }
 
-   primitive._commandsDirty = false;
 
- }
 
- function createPickCommands(primitive) {
 
-   if (!primitive._pickCommandsDirty) {
 
-     return;
 
-   }
 
-   const length = primitive._indexOffsets.length;
 
-   const pickCommands = primitive._pickCommands;
 
-   pickCommands.length = length * 2;
 
-   const vertexArray = primitive._va;
 
-   const spStencil = primitive._spStencil;
 
-   const spPick = primitive._spPick;
 
-   const modelMatrix = defaultValue(primitive._modelMatrix, Matrix4.IDENTITY);
 
-   const uniformMap = primitive._uniformMap;
 
-   for (let j = 0; j < length; ++j) {
 
-     const offset = primitive._indexOffsets[j];
 
-     const count = primitive._indexCounts[j];
 
-     const bv = defined(primitive._boundingVolumes)
 
-       ? primitive._boundingVolumes[j]
 
-       : primitive.boundingVolume;
 
-     let stencilDepthCommand = pickCommands[j * 2];
 
-     if (!defined(stencilDepthCommand)) {
 
-       stencilDepthCommand = pickCommands[j * 2] = new DrawCommand({
 
-         owner: primitive,
 
-         pickOnly: true,
 
-       });
 
-     }
 
-     stencilDepthCommand.vertexArray = vertexArray;
 
-     stencilDepthCommand.modelMatrix = modelMatrix;
 
-     stencilDepthCommand.offset = offset;
 
-     stencilDepthCommand.count = count;
 
-     stencilDepthCommand.renderState = primitive._rsStencilDepthPass;
 
-     stencilDepthCommand.shaderProgram = spStencil;
 
-     stencilDepthCommand.uniformMap = uniformMap;
 
-     stencilDepthCommand.boundingVolume = bv;
 
-     stencilDepthCommand.pass = Pass.TERRAIN_CLASSIFICATION;
 
-     const stencilDepthDerivedCommand = DrawCommand.shallowClone(
 
-       stencilDepthCommand,
 
-       stencilDepthCommand.derivedCommands.tileset
 
-     );
 
-     stencilDepthDerivedCommand.renderState =
 
-       primitive._rsStencilDepthPass3DTiles;
 
-     stencilDepthDerivedCommand.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION;
 
-     stencilDepthCommand.derivedCommands.tileset = stencilDepthDerivedCommand;
 
-     let colorCommand = pickCommands[j * 2 + 1];
 
-     if (!defined(colorCommand)) {
 
-       colorCommand = pickCommands[j * 2 + 1] = new DrawCommand({
 
-         owner: primitive,
 
-         pickOnly: true,
 
-       });
 
-     }
 
-     colorCommand.vertexArray = vertexArray;
 
-     colorCommand.modelMatrix = modelMatrix;
 
-     colorCommand.offset = offset;
 
-     colorCommand.count = count;
 
-     colorCommand.renderState = primitive._rsPickPass;
 
-     colorCommand.shaderProgram = spPick;
 
-     colorCommand.uniformMap = uniformMap;
 
-     colorCommand.boundingVolume = bv;
 
-     colorCommand.pass = Pass.TERRAIN_CLASSIFICATION;
 
-     const colorDerivedCommand = DrawCommand.shallowClone(
 
-       colorCommand,
 
-       colorCommand.derivedCommands.tileset
 
-     );
 
-     colorDerivedCommand.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION;
 
-     colorCommand.derivedCommands.tileset = colorDerivedCommand;
 
-   }
 
-   primitive._pickCommandsDirty = false;
 
- }
 
- /**
 
-  * Creates features for each mesh and places it at the batch id index of features.
 
-  *
 
-  * @param {Vector3DTileContent} content The vector tile content.
 
-  * @param {Cesium3DTileFeature[]} features An array of features where the polygon features will be placed.
 
-  */
 
- Vector3DTilePrimitive.prototype.createFeatures = function (content, features) {
 
-   const batchIds = this._batchIds;
 
-   const length = batchIds.length;
 
-   for (let i = 0; i < length; ++i) {
 
-     const batchId = batchIds[i];
 
-     features[batchId] = new Cesium3DTileFeature(content, batchId);
 
-   }
 
- };
 
- /**
 
-  * Colors the entire tile when enabled is true. The resulting color will be (mesh batch table color * color).
 
-  *
 
-  * @param {Boolean} enabled Whether to enable debug coloring.
 
-  * @param {Color} color The debug color.
 
-  */
 
- Vector3DTilePrimitive.prototype.applyDebugSettings = function (enabled, color) {
 
-   this._highlightColor = enabled ? color : this._constantColor;
 
- };
 
- function clearStyle(polygons, features) {
 
-   polygons._updatingAllCommands = true;
 
-   const batchIds = polygons._batchIds;
 
-   let length = batchIds.length;
 
-   let i;
 
-   for (i = 0; i < length; ++i) {
 
-     const batchId = batchIds[i];
 
-     const feature = features[batchId];
 
-     feature.show = true;
 
-     feature.color = Color.WHITE;
 
-   }
 
-   const batchedIndices = polygons._batchedIndices;
 
-   length = batchedIndices.length;
 
-   for (i = 0; i < length; ++i) {
 
-     batchedIndices[i].color = Color.clone(Color.WHITE);
 
-   }
 
-   polygons._updatingAllCommands = false;
 
-   polygons._batchDirty = true;
 
- }
 
- const scratchColor = new Color();
 
- const DEFAULT_COLOR_VALUE = Color.WHITE;
 
- const DEFAULT_SHOW_VALUE = true;
 
- const complexExpressionReg = /\$/;
 
- /**
 
-  * Apply a style to the content.
 
-  *
 
-  * @param {Cesium3DTileStyle} style The style.
 
-  * @param {Cesium3DTileFeature[]} features The array of features.
 
-  */
 
- Vector3DTilePrimitive.prototype.applyStyle = function (style, features) {
 
-   if (!defined(style)) {
 
-     clearStyle(this, features);
 
-     return;
 
-   }
 
-   const colorExpression = style.color;
 
-   const isSimpleStyle =
 
-     colorExpression instanceof Expression &&
 
-     !complexExpressionReg.test(colorExpression.expression);
 
-   this._updatingAllCommands = isSimpleStyle;
 
-   const batchIds = this._batchIds;
 
-   let length = batchIds.length;
 
-   let i;
 
-   for (i = 0; i < length; ++i) {
 
-     const batchId = batchIds[i];
 
-     const feature = features[batchId];
 
-     feature.color = defined(style.color)
 
-       ? style.color.evaluateColor(feature, scratchColor)
 
-       : DEFAULT_COLOR_VALUE;
 
-     feature.show = defined(style.show)
 
-       ? style.show.evaluate(feature)
 
-       : DEFAULT_SHOW_VALUE;
 
-   }
 
-   if (isSimpleStyle) {
 
-     const batchedIndices = this._batchedIndices;
 
-     length = batchedIndices.length;
 
-     for (i = 0; i < length; ++i) {
 
-       batchedIndices[i].color = Color.clone(Color.WHITE);
 
-     }
 
-     this._updatingAllCommands = false;
 
-     this._batchDirty = true;
 
-   }
 
- };
 
- /**
 
-  * Call when updating the color of a mesh with batchId changes color. The meshes will need to be re-batched
 
-  * on the next update.
 
-  *
 
-  * @param {Number} batchId The batch id of the meshes whose color has changed.
 
-  * @param {Color} color The new polygon color.
 
-  */
 
- Vector3DTilePrimitive.prototype.updateCommands = function (batchId, color) {
 
-   if (this._updatingAllCommands) {
 
-     return;
 
-   }
 
-   const batchIdLookUp = this._batchIdLookUp;
 
-   const index = batchIdLookUp[batchId];
 
-   if (!defined(index)) {
 
-     return;
 
-   }
 
-   const indexOffsets = this._indexOffsets;
 
-   const indexCounts = this._indexCounts;
 
-   const offset = indexOffsets[index];
 
-   const count = indexCounts[index];
 
-   const batchedIndices = this._batchedIndices;
 
-   const length = batchedIndices.length;
 
-   let i;
 
-   for (i = 0; i < length; ++i) {
 
-     const batchedOffset = batchedIndices[i].offset;
 
-     const batchedCount = batchedIndices[i].count;
 
-     if (offset >= batchedOffset && offset < batchedOffset + batchedCount) {
 
-       break;
 
-     }
 
-   }
 
-   batchedIndices.push(
 
-     new Vector3DTileBatch({
 
-       color: Color.clone(color),
 
-       offset: offset,
 
-       count: count,
 
-       batchIds: [batchId],
 
-     })
 
-   );
 
-   const startIds = [];
 
-   const endIds = [];
 
-   const batchIds = batchedIndices[i].batchIds;
 
-   const batchIdsLength = batchIds.length;
 
-   for (let j = 0; j < batchIdsLength; ++j) {
 
-     const id = batchIds[j];
 
-     if (id === batchId) {
 
-       continue;
 
-     }
 
-     const offsetIndex = batchIdLookUp[id];
 
-     if (indexOffsets[offsetIndex] < offset) {
 
-       startIds.push(id);
 
-     } else {
 
-       endIds.push(id);
 
-     }
 
-   }
 
-   if (endIds.length !== 0) {
 
-     batchedIndices.push(
 
-       new Vector3DTileBatch({
 
-         color: Color.clone(batchedIndices[i].color),
 
-         offset: offset + count,
 
-         count:
 
-           batchedIndices[i].offset + batchedIndices[i].count - (offset + count),
 
-         batchIds: endIds,
 
-       })
 
-     );
 
-   }
 
-   if (startIds.length !== 0) {
 
-     batchedIndices[i].count = offset - batchedIndices[i].offset;
 
-     batchedIndices[i].batchIds = startIds;
 
-   } else {
 
-     batchedIndices.splice(i, 1);
 
-   }
 
-   this._batchDirty = true;
 
- };
 
- function queueCommands(primitive, frameState, commands, commandsIgnoreShow) {
 
-   const classificationType = primitive.classificationType;
 
-   const queueTerrainCommands =
 
-     classificationType !== ClassificationType.CESIUM_3D_TILE;
 
-   const queue3DTilesCommands =
 
-     classificationType !== ClassificationType.TERRAIN;
 
-   const commandList = frameState.commandList;
 
-   let commandLength = commands.length;
 
-   let command;
 
-   let i;
 
-   for (i = 0; i < commandLength; ++i) {
 
-     if (queueTerrainCommands) {
 
-       command = commands[i];
 
-       command.pass = Pass.TERRAIN_CLASSIFICATION;
 
-       commandList.push(command);
 
-     }
 
-     if (queue3DTilesCommands) {
 
-       command = commands[i].derivedCommands.tileset;
 
-       command.pass = Pass.CESIUM_3D_TILE_CLASSIFICATION;
 
-       commandList.push(command);
 
-     }
 
-   }
 
-   if (!frameState.invertClassification || !defined(commandsIgnoreShow)) {
 
-     return;
 
-   }
 
-   commandLength = commandsIgnoreShow.length;
 
-   for (i = 0; i < commandLength; ++i) {
 
-     commandList.push(commandsIgnoreShow[i]);
 
-   }
 
- }
 
- function queueWireframeCommands(frameState, commands) {
 
-   const commandList = frameState.commandList;
 
-   const commandLength = commands.length;
 
-   for (let i = 0; i < commandLength; i += 2) {
 
-     const command = commands[i + 1];
 
-     command.pass = Pass.OPAQUE;
 
-     commandList.push(command);
 
-   }
 
- }
 
- function updateWireframe(primitive) {
 
-   let earlyExit = primitive.debugWireframe === primitive._debugWireframe;
 
-   earlyExit =
 
-     earlyExit && !(primitive.debugWireframe && primitive._wireframeDirty);
 
-   if (earlyExit) {
 
-     return;
 
-   }
 
-   if (!defined(primitive._rsWireframe)) {
 
-     primitive._rsWireframe = RenderState.fromCache({});
 
-   }
 
-   let rs;
 
-   let type;
 
-   if (primitive.debugWireframe) {
 
-     rs = primitive._rsWireframe;
 
-     type = PrimitiveType.LINES;
 
-   } else {
 
-     rs = primitive._rsColorPass;
 
-     type = PrimitiveType.TRIANGLES;
 
-   }
 
-   const commands = primitive._commands;
 
-   const commandLength = commands.length;
 
-   for (let i = 0; i < commandLength; i += 2) {
 
-     const command = commands[i + 1];
 
-     command.renderState = rs;
 
-     command.primitiveType = type;
 
-   }
 
-   primitive._debugWireframe = primitive.debugWireframe;
 
-   primitive._wireframeDirty = false;
 
- }
 
- /**
 
-  * Updates the batches and queues the commands for rendering.
 
-  *
 
-  * @param {FrameState} frameState The current frame state.
 
-  */
 
- Vector3DTilePrimitive.prototype.update = function (frameState) {
 
-   const context = frameState.context;
 
-   createVertexArray(this, context);
 
-   createShaders(this, context);
 
-   createRenderStates(this);
 
-   createUniformMap(this, context);
 
-   const passes = frameState.passes;
 
-   if (passes.render) {
 
-     createColorCommands(this, context);
 
-     createColorCommandsIgnoreShow(this, frameState);
 
-     updateWireframe(this);
 
-     if (this._debugWireframe) {
 
-       queueWireframeCommands(frameState, this._commands);
 
-     } else {
 
-       queueCommands(this, frameState, this._commands, this._commandsIgnoreShow);
 
-     }
 
-   }
 
-   if (passes.pick) {
 
-     createPickCommands(this);
 
-     queueCommands(this, frameState, this._pickCommands);
 
-   }
 
- };
 
- /**
 
-  * Returns true if this object was destroyed; otherwise, false.
 
-  * <p>
 
-  * If this object was destroyed, it should not be used; calling any function other than
 
-  * <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
 
-  * </p>
 
-  *
 
-  * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>.
 
-  */
 
- Vector3DTilePrimitive.prototype.isDestroyed = function () {
 
-   return false;
 
- };
 
- /**
 
-  * Destroys the WebGL resources held by this object.  Destroying an object allows for deterministic
 
-  * release of WebGL resources, instead of relying on the garbage collector to destroy this object.
 
-  * <p>
 
-  * Once an object is destroyed, it should not be used; calling any function other than
 
-  * <code>isDestroyed</code> will result in a {@link DeveloperError} exception.  Therefore,
 
-  * assign the return value (<code>undefined</code>) to the object as done in the example.
 
-  * </p>
 
-  *
 
-  * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
 
-  */
 
- Vector3DTilePrimitive.prototype.destroy = function () {
 
-   this._va = this._va && this._va.destroy();
 
-   this._sp = this._sp && this._sp.destroy();
 
-   this._spPick = this._spPick && this._spPick.destroy();
 
-   this._vaSwap = this._vaSwap && this._vaSwap.destroy();
 
-   return destroyObject(this);
 
- };
 
- export default Vector3DTilePrimitive;
 
 
  |