UNPKG

@itwin/core-frontend

Version:
271 lines • 12 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.PrimitiveCommand = exports.PopClipCommand = exports.PushClipCommand = exports.PopBranchCommand = exports.PushBranchCommand = exports.PushStateCommand = exports.PushBatchCommand = exports.PopBatchCommand = exports.DrawOpCode = exports.DrawParams = exports.ShaderProgramParams = void 0; exports.extractFlashedVolumeClassifierCommands = extractFlashedVolumeClassifierCommands; exports.extractHilitedVolumeClassifierCommands = extractHilitedVolumeClassifierCommands; const core_bentley_1 = require("@itwin/core-bentley"); const core_common_1 = require("@itwin/core-common"); const FeatureOverrides_1 = require("./FeatureOverrides"); const System_1 = require("./System"); const TechniqueFlags_1 = require("./TechniqueFlags"); /* eslint-disable no-restricted-syntax */ /** @internal */ class ShaderProgramParams { _target; _renderPass = 255 /* RenderPass.None */; get target() { (0, core_bentley_1.assert)(undefined !== this._target); return this._target; } get renderPass() { return this._renderPass; } get projectionMatrix() { return this.target.uniforms.getProjectionMatrix32(this.isViewCoords); } bindProjectionMatrix(uniform) { this.target.uniforms.bindProjectionMatrix(uniform, this.isViewCoords); } get isViewCoords() { return 13 /* RenderPass.ViewOverlay */ === this.renderPass || 0 /* RenderPass.Background */ === this.renderPass; } get isOverlayPass() { return 12 /* RenderPass.WorldOverlay */ === this.renderPass || 13 /* RenderPass.ViewOverlay */ === this.renderPass; } get context() { return System_1.System.instance.context; } init(target, pass = 5 /* RenderPass.OpaqueGeneral */) { this._renderPass = pass; this._target = target; } } exports.ShaderProgramParams = ShaderProgramParams; /** @internal */ class DrawParams { _programParams; _geometry; get geometry() { (0, core_bentley_1.assert)(undefined !== this._geometry); return this._geometry; } get programParams() { (0, core_bentley_1.assert)(undefined !== this._programParams); return this._programParams; } get target() { return this.programParams.target; } get renderPass() { return this.programParams.renderPass; } get projectionMatrix() { return this.programParams.projectionMatrix; } get isViewCoords() { return this.programParams.isViewCoords || this.target.currentBranch.forceViewCoords; } get isOverlayPass() { return this.programParams.isOverlayPass; } get context() { return this.programParams.context; } init(programParams, geometry) { this._programParams = programParams; this._geometry = geometry; } } exports.DrawParams = DrawParams; /** Represents a command to be executed within a RenderPass. The most common command is * to draw a primitive; others involve state changes such as pushing/popping transforms * and symbology overrides, which require that commands be executed in order. * @internal */ var DrawOpCode; (function (DrawOpCode) { DrawOpCode["Primitive"] = "drawPrimitive"; DrawOpCode["PushBranch"] = "pushBranch"; DrawOpCode["PopBranch"] = "popBranch"; DrawOpCode["PushBatch"] = "pushBatch"; DrawOpCode["PopBatch"] = "popBatch"; DrawOpCode["PushState"] = "pushState"; DrawOpCode["PushClip"] = "pushClip"; DrawOpCode["PopClip"] = "popClip"; })(DrawOpCode || (exports.DrawOpCode = DrawOpCode = {})); /** @internal */ class PopBatchCommand { opcode = "popBatch"; constructor() { } static instance = new PopBatchCommand(); execute(exec) { exec.target.popBatch(); } } exports.PopBatchCommand = PopBatchCommand; /** @internal */ class PushBatchCommand { batch; opcode = "pushBatch"; constructor(batch) { this.batch = batch; } execute(exec) { exec.target.pushBatch(this.batch); } } exports.PushBatchCommand = PushBatchCommand; /** @internal */ class PushStateCommand { state; opcode = "pushState"; constructor(state) { this.state = state; } execute(exec) { exec.target.pushState(this.state); } } exports.PushStateCommand = PushStateCommand; /** @internal */ class PushBranchCommand { branch; opcode = "pushBranch"; constructor(branch) { this.branch = branch; } execute(exec) { exec.pushBranch(this.branch); } } exports.PushBranchCommand = PushBranchCommand; /** @internal */ class PopBranchCommand { opcode = "popBranch"; constructor() { } static instance = new PopBranchCommand(); execute(exec) { exec.popBranch(); } } exports.PopBranchCommand = PopBranchCommand; /** @internal */ class PushClipCommand { clip; opcode = "pushClip"; constructor(clip) { this.clip = clip; } execute(exec) { exec.target.uniforms.branch.clipStack.push(this.clip); } } exports.PushClipCommand = PushClipCommand; /** @internal */ class PopClipCommand { opcode = "popClip"; constructor() { } static instance = new PopClipCommand(); execute(exec) { exec.target.uniforms.branch.clipStack.pop(); } } exports.PopClipCommand = PopClipCommand; /** @internal */ class PrimitiveCommand { primitive; opcode = "drawPrimitive"; constructor(primitive) { this.primitive = primitive; } static _scratchTechniqueFlags = new TechniqueFlags_1.TechniqueFlags(); execute(exec) { if (exec.target.isGeometryOutsideActiveVolume(this.primitive.cachedGeometry)) return; const techniqueId = this.primitive.techniqueId; if (-1 /* TechniqueId.Invalid */ === techniqueId) return; const target = exec.target; const thematic = this.primitive.cachedGeometry.supportsThematicDisplay && target.wantThematicDisplay; const shadowable = (techniqueId === 0 /* TechniqueId.Surface */ || techniqueId === 7 /* TechniqueId.RealityMesh */) && target.solarShadowMap.isReady && target.currentViewFlags.shadows && !thematic; const isShadowable = shadowable ? 1 /* IsShadowable.Yes */ : 0 /* IsShadowable.No */; let isThematic = thematic ? 1 /* IsThematic.Yes */ : 0 /* IsThematic.No */; const isClassified = (undefined !== target.currentPlanarClassifierOrDrape || undefined !== target.activeVolumeClassifierTexture) ? 1 /* IsClassified.Yes */ : 0 /* IsClassified.No */; const isInstanced = this.primitive.isInstanced ? 1 /* IsInstanced.Yes */ : 0 /* IsInstanced.No */; const isAnimated = this.primitive.hasAnimation ? 1 /* IsAnimated.Yes */ : 0 /* IsAnimated.No */; // Point clouds do not support hillshade or slope mode for thematic display. if (isThematic && (undefined !== this.primitive.cachedGeometry.asPointCloud) && (target.uniforms.thematic.wantSlopeMode || target.uniforms.thematic.wantHillShadeMode)) isThematic = 0 /* IsThematic.No */; const wiremesh = target.currentViewFlags.wiremesh && (techniqueId === 0 /* TechniqueId.Surface */ || techniqueId === 7 /* TechniqueId.RealityMesh */); const isWiremesh = wiremesh ? 1 /* IsWiremesh.Yes */ : 0 /* IsWiremesh.No */; const flags = PrimitiveCommand._scratchTechniqueFlags; const posType = this.primitive.cachedGeometry.usesQuantizedPositions ? "quantized" : "unquantized"; const enableAtmosphere = target.wantAtmosphere ? 1 /* EnableAtmosphere.Yes */ : 0 /* EnableAtmosphere.No */; flags.init(target, exec.renderPass, isInstanced, isAnimated, isClassified, isShadowable, isThematic, isWiremesh, posType, enableAtmosphere); const technique = target.techniques.getTechnique(techniqueId); const program = technique.getShader(flags); if (exec.setProgram(program)) exec.target.compositor.drawPrimitive(this.primitive, exec, program.outputsToPick); } get hasFeatures() { return this.primitive.hasFeatures; } get renderOrder() { return this.primitive.renderOrder; } getPass(target) { return this.primitive.getPass(target); } } exports.PrimitiveCommand = PrimitiveCommand; /** Extracts the commands for rendering the flashed classifier (if any) from the by-index set of volume classifier commands. * NB: Cmds will be sets of some pushes, a primitive, and then some pops (equal to number of pushes). * The primitive should be right in the middle of a set. We need to find the set which matches the flashID. * @internal */ function extractFlashedVolumeClassifierCommands(flashedId, cmds, numCmdsPerClassifier) { if (!core_bentley_1.Id64.isValid(flashedId) || 0 === numCmdsPerClassifier) return undefined; const firstPrim = (numCmdsPerClassifier - 1) / 2; for (let i = firstPrim; i < cmds.length; i += numCmdsPerClassifier) { (0, core_bentley_1.assert)("drawPrimitive" === cmds[i].opcode, "Command list not configured as expected."); const pc = cmds[i]; const surface = pc.primitive.cachedGeometry.asSurface; if (undefined !== surface && undefined !== surface.mesh.uniformFeatureId) { let j = i - 1; while (j >= 0 && "pushBatch" !== cmds[j].opcode) // Find batch for this primitive j--; if (j < 0) continue; const pushBatch = cmds[j]; const elemId = pushBatch.batch.featureTable.findElementId(surface.mesh.uniformFeatureId); if (undefined !== elemId && elemId === flashedId) { return cmds.slice(i - firstPrim, i + firstPrim + 1); } } } return undefined; } const scratchFeature = core_common_1.PackedFeature.create(); /** @internal */ function extractHilitedVolumeClassifierCommands(hilites, cmds) { // TODO: This could really be done at the time the HiliteClassification render pass commands are being generated // by just not putting the ones which are not hilited into the ClassificationHilite command list. const result = []; let batch; for (const cmd of cmds) { switch (cmd.opcode) { case "popBranch": if (result.length > 0 && "pushBranch" === result[result.length - 1].opcode) { result.pop(); // remove empty push/pop pairs continue; } break; case "popBatch": batch = undefined; if (result.length > 0 && "pushBatch" === result[result.length - 1].opcode) { result.pop(); // remove empty push/pop pairs continue; } break; case "pushBatch": batch = cmd.batch; break; case "drawPrimitive": if (undefined !== batch) { // Skip any primitives that are not hilited. const surface = cmd.primitive.cachedGeometry.asSurface; if (undefined === surface || undefined === surface.mesh.uniformFeatureId) continue; const feature = batch.featureTable.getPackedFeature(surface.mesh.uniformFeatureId, scratchFeature); if (undefined === feature || !(0, FeatureOverrides_1.isFeatureHilited)(feature, hilites, hilites.models.hasId(core_bentley_1.Id64.fromUint32PairObject(feature.modelId)))) continue; break; } } result.push(cmd); } return result; } //# sourceMappingURL=DrawCommand.js.map