UNPKG

@itwin/core-frontend

Version:
131 lines 5.95 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.Contours = void 0; const core_bentley_1 = require("@itwin/core-bentley"); const core_common_1 = require("@itwin/core-common"); const GL_1 = require("./GL"); const RenderFlags_1 = require("./RenderFlags"); const System_1 = require("./System"); const Texture_1 = require("./Texture"); const VertexTable_1 = require("../../../common/internal/render/VertexTable"); const scratchPackedFeature = core_common_1.PackedFeature.createWithIndex(); /** @internal */ class Contours { target; _options; _contours; _lut; _lutWidth = 0; _numFeatures = 0; get byteLength() { return undefined !== this._lut ? this._lut.bytesUsed : 0; } matchesTargetAndFeatureCount(target, map) { // checking for target change or texture size requirement change return target === this.target && this._numFeatures === map.numFeatures; } matchesSubCategories() { if (this._contours === undefined && this.target.currentContours === undefined) return true; if (this._contours === undefined || this.target.currentContours === undefined) return false; if (this._contours.groups.length !== this.target.currentContours.groups.length) return false; for (let index = 0, len = this._contours.groups.length; index < len && index < core_common_1.ContourDisplay.maxContourGroups; ++index) { if (!this._contours.groups[index].subCategoriesEqual(this.target.currentContours.groups[index])) return false; } return true; } _initialize(map) { (0, core_bentley_1.assert)(0 < map.numFeatures); this._numFeatures = map.numFeatures; const dims = (0, VertexTable_1.computeDimensions)(this._numFeatures, 1 / 8, 0, System_1.System.instance.maxTextureSize); const width = dims.width; const height = dims.height; (0, core_bentley_1.assert)(width * height * 8 >= this._numFeatures); const data = new Uint8Array(width * height * 4); const creator = new Texture_1.Texture2DDataUpdater(data); this.buildLookupTable(creator, map, this.target.currentContours); this._lut = Texture_1.TextureHandle.createForData(width, height, data, true, GL_1.GL.Texture.WrapMode.ClampToEdge); this._lutWidth = width; } _update(map, lut) { (0, core_bentley_1.assert)(this._numFeatures === map.numFeatures); const updater = new Texture_1.Texture2DDataUpdater(lut.dataBytes); this.buildLookupTable(updater, map, this.target.currentContours); lut.update(updater); } buildLookupTable(data, map, contours) { // setup an efficient way to compare feature subcategories with lists in terrains const subCatMap = new core_bentley_1.Id64.Uint32Map(); let defaultNdx = 0xf; // default for unmatched subcategories is to not show contours // NB: index also has to be a max of 14 - has to fit in 4 bits with value 15 reserved for no terrain def for (let index = 0, len = contours.groups.length; index < len && index < core_common_1.ContourDisplay.maxContourGroups; ++index) { const subCats = contours.groups[index].subCategories; if (core_bentley_1.OrderedId64Iterable.isEmptySet(subCats)) { defaultNdx = index; // change default for unmatched subcategories to this definition } else { for (const subCat of subCats) subCatMap.setById(subCat, index); } } // NB: We currently use 1/2 of one component of RGBA value per feature as follows: // [0] R/G/B/A = index pair - lower 4 bits = ndx n, upper 4 bits = ndx n+1 let even = false; let byteOut = 0; let dataIndex = 0; for (const feature of map.iterable(scratchPackedFeature)) { dataIndex = Math.floor(feature.index * 0.5); even = (feature.index & 1) === 0; const terrainNdx = subCatMap.get(feature.subCategoryId.lower, feature.subCategoryId.upper) ?? defaultNdx; if (even) byteOut = terrainNdx; else data.setByteAtIndex(dataIndex, (terrainNdx << 4) | byteOut); } if (even) // not written data.setByteAtIndex(dataIndex, byteOut); } constructor(target, options) { this.target = target; this._options = options; this._contours = target.currentContours; } static createFromTarget(target, options) { return new Contours(target, options); } get isDisposed() { return undefined === this._lut; } [Symbol.dispose]() { this._lut = (0, core_bentley_1.dispose)(this._lut); return undefined; } initFromMap(map) { this._lut = (0, core_bentley_1.dispose)(this._lut); this._initialize(map); } update(features) { if (this.matchesSubCategories()) return; this._contours = this.target.currentContours; // _lut can be undefined if context was lost, (gl.createTexture returns null) if (this._lut) { this._update(features, this._lut); } } bindContourLUTWidth(uniform) { uniform.setUniform1ui(this._lutWidth); } bindContourLUT(uniform) { if (this._lut) this._lut.bindSampler(uniform, RenderFlags_1.TextureUnit.Contours); } } exports.Contours = Contours; //# sourceMappingURL=Contours.js.map