UNPKG

@itwin/core-frontend

Version:
114 lines 5.11 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module WebGL */ Object.defineProperty(exports, "__esModule", { value: true }); exports.BatchState = void 0; const core_bentley_1 = require("@itwin/core-bentley"); /** * Assigns a transient, unique 32-bit integer ID to each Batch in a RenderCommands. * A batch ID of 0 means "no batch". * The first batch gets batch ID of 1. * The next batch gets the previous batch's ID plus the number of features in the previous batch's feature table * (or 1, if empty feature table). * The IDs are set temporarily as members on the Batch objects and reset to 0 immediately after rendering. * The currentBatch member identifies the batch containing primitives currently being drawn. * The combination of the current batch's ID (passed as uniform to shader) and the index of a given Feature within * its batch's FeatureTable (stored in vertex table) produce a unique ID for every feature rendered during a frame. * During rendering, the feature IDs are written to the "feature ID" color attachment. * The batch IDs remain valid during a call to Target.readPixels() so that they can be used to extract * Features from the Batch's FeatureTables. * @internal */ class BatchState { _stack; _batches = []; // NB: this list is ordered - but *not* indexed - by batch ID. _curBatch; constructor(stack) { this._stack = stack; } get currentBatch() { return this._curBatch; } get currentBatchId() { return undefined !== this._curBatch ? this._curBatch.batchId : 0; } get currentBatchIModel() { return undefined !== this._curBatch ? this._curBatch.batchIModel : undefined; } get isEmpty() { return 0 === this._batches.length; } push(batch, allowAdd) { (0, core_bentley_1.assert)(undefined === this.currentBatch, "batches cannot nest"); this.getBatchId(batch, allowAdd); this._curBatch = batch; } pop() { (0, core_bentley_1.assert)(undefined !== this.currentBatch); this._curBatch = undefined; } reset() { (0, core_bentley_1.assert)(undefined === this.currentBatch); for (const batch of this._batches) batch.resetContext(); this._batches.length = 0; this._curBatch = undefined; } static _scratchElementIdPair = { lower: 0, upper: 0 }; getElementId(featureId) { const batch = this.find(featureId); if (undefined === batch) return core_bentley_1.Id64.invalid; const featureIndex = featureId - batch.batchId; (0, core_bentley_1.assert)(featureIndex >= 0); const parts = batch.featureTable.getElementIdPair(featureIndex, BatchState._scratchElementIdPair); return core_bentley_1.Id64.fromUint32Pair(parts.lower, parts.upper); } getFeature(featureId, result) { const batch = this.find(featureId); if (undefined === batch) return undefined; const featureIndex = featureId - batch.batchId; (0, core_bentley_1.assert)(featureIndex >= 0); return batch.featureTable.findFeature(featureIndex, result); } get numFeatureIds() { return this.nextBatchId; } get numBatches() { return this._batches.length; } findBatchId(featureId) { const batch = this.find(featureId); return undefined !== batch ? batch.batchId : 0; } get nextBatchId() { if (this.isEmpty) return 1; const prev = this._batches[this._batches.length - 1]; (0, core_bentley_1.assert)(0 !== prev.batchId); let prevNumFeatures = prev.featureTable.numFeatures; if (0 === prevNumFeatures) prevNumFeatures = 1; return prev.batchId + prevNumFeatures; } getBatchId(batch, allowAdd) { if (allowAdd && 0 === batch.batchId) { batch.setContext(this.nextBatchId, this._stack.top); this._batches.push(batch); } return batch.batchId; } indexOf(featureId) { if (featureId <= 0) return -1; const found = (0, core_bentley_1.lowerBound)(featureId, this._batches, (lhs, rhs) => { // Determine if the requested feature ID is within the range of this batch. if (lhs < rhs.batchId) return -1; const numFeatures = rhs.featureTable.numFeatures; const nextBatchId = rhs.batchId + (numFeatures > 0 ? numFeatures : 1); return lhs < nextBatchId ? 0 : 1; }); return found.index < this._batches.length ? found.index : -1; } find(featureId) { const index = this.indexOf(featureId); return -1 !== index ? this._batches[index] : undefined; } } exports.BatchState = BatchState; //# sourceMappingURL=BatchState.js.map