UNPKG

@itwin/core-frontend

Version:
162 lines 7.25 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.TargetUniforms = void 0; const core_geometry_1 = require("@itwin/core-geometry"); const BatchUniforms_1 = require("./BatchUniforms"); const BranchUniforms_1 = require("./BranchUniforms"); const FrustumUniforms_1 = require("./FrustumUniforms"); const HiliteUniforms_1 = require("./HiliteUniforms"); const LightingUniforms_1 = require("./LightingUniforms"); const ShadowUniforms_1 = require("./ShadowUniforms"); const StyleUniforms_1 = require("./StyleUniforms"); const Sync_1 = require("./Sync"); const ThematicUniforms_1 = require("./ThematicUniforms"); const ViewRectUniforms_1 = require("./ViewRectUniforms"); const RealityModelUniforms_1 = require("./RealityModelUniforms"); const AtmosphereUniforms_1 = require("./AtmosphereUniforms"); const ContourUniforms_1 = require("./ContourUniforms"); class PixelWidthFactor { /** The pixel width factor depends on both the frustum and the view rect. It also depends on the frustum scale associated with the current Branch. */ _rectSync = {}; _frustumSync = {}; _branchSync = {}; _factor = 0; syncKey = 0; bind(uniform, uniforms) { if (!(0, Sync_1.sync)(uniforms.frustum, this._frustumSync) || !(0, Sync_1.sync)(uniforms.viewRect, this._rectSync) || !(0, Sync_1.sync)(uniforms.branch, this._branchSync)) this.compute(uniforms.frustum, uniforms.viewRect.width, uniforms.viewRect.height, uniforms.branch.top.frustumScale); if (!(0, Sync_1.sync)(this, uniform)) uniform.setUniform1f(this._factor); } compute(frustumUniforms, width, height, scale) { (0, Sync_1.desync)(this); const frustumPlanes = frustumUniforms.planes; const top = frustumPlanes[0]; const bottom = frustumPlanes[1]; const left = frustumPlanes[2]; const right = frustumPlanes[3]; let halfPixelWidth; let halfPixelHeight; const frustum = frustumUniforms.frustum; if (2 /* FrustumUniformType.Perspective */ === frustumUniforms.type) { const inverseNear = 1.0 / frustum[0]; const tanTheta = top * inverseNear; halfPixelHeight = scale.x * tanTheta / height; halfPixelWidth = scale.y * tanTheta / width; } else { halfPixelWidth = scale.x * 0.5 * (right - left) / width; halfPixelHeight = scale.y * 0.5 * (top - bottom) / height; } this._factor = Math.sqrt(halfPixelWidth * halfPixelWidth + halfPixelHeight * halfPixelHeight); } } // Direction in view space used if solar shadows are disabled and LightSettings.useSolarLighting is false. const defaultSunDirectionView = new core_geometry_1.Vector3d(0.272166, 0.680414, 0.680414); class SunDirection { // Sun direction is passed to shader in view coords so depends upon frustum. syncToken; syncKey = 0; _haveWorldDir = false; _worldDir = core_geometry_1.Vector3d.unitZ(); _viewDir = defaultSunDirectionView.clone(); _viewDir32 = new Float32Array(3); _updated = true; update(sunDir) { const haveWorldDir = undefined !== sunDir; if (haveWorldDir !== this._haveWorldDir || (sunDir && !sunDir.isExactEqual(this._worldDir))) { this._updated = true; (0, Sync_1.desync)(this); this._haveWorldDir = haveWorldDir; if (sunDir) { sunDir.clone(this._worldDir); this._worldDir.normalizeInPlace(); } } } bind(uniform, uniforms) { if (!(0, Sync_1.sync)(uniforms.frustum, this) || this._updated) { if (this._haveWorldDir) { uniforms.frustum.viewMatrix.multiplyVector(this._worldDir, this._viewDir); this._viewDir.negate(this._viewDir); } else { defaultSunDirectionView.clone(this._viewDir); } this._viewDir.normalizeInPlace(); this._viewDir32[0] = this._viewDir.x; this._viewDir32[1] = this._viewDir.y; this._viewDir32[2] = this._viewDir.z; (0, Sync_1.desync)(this); this._updated = false; } if (!(0, Sync_1.sync)(this, uniform)) uniform.setUniform3fv(this._viewDir32); } } /** Holds state for commonly-used uniforms to avoid unnecessary recomputation, owned by a Target. * DO NOT directly modify exposed members of the objects exposed by this class. Use their APIs. * e.g., code like `target.uniforms.frustum.projectionMatrix.setFrom(someOtherMatrix)` or `target.uniforms.branch.top.setViewFlags(blah)` will cause bugs. * @internal */ class TargetUniforms { frustum; viewRect = new ViewRectUniforms_1.ViewRectUniforms(); hilite = new HiliteUniforms_1.HiliteUniforms(); style = new StyleUniforms_1.StyleUniforms(); lights = new LightingUniforms_1.LightingUniforms(); thematic = new ThematicUniforms_1.ThematicUniforms(); contours = new ContourUniforms_1.ContourUniforms(); branch; batch; shadow; realityModel = new RealityModelUniforms_1.RealityModelUniforms(); atmosphere = new AtmosphereUniforms_1.AtmosphereUniforms(); _pixelWidthFactor = new PixelWidthFactor(); _sunDirection = new SunDirection(); constructor(target) { this.frustum = new FrustumUniforms_1.FrustumUniforms(); this.branch = new BranchUniforms_1.BranchUniforms(target); this.batch = new BatchUniforms_1.BatchUniforms(target, this.branch.createBatchState()); this.shadow = new ShadowUniforms_1.ShadowUniforms(target); } getProjectionMatrix(forViewCoords) { return forViewCoords ? this.viewRect.projectionMatrix : this.frustum.projectionMatrix; } getProjectionMatrix32(forViewCoords) { return forViewCoords ? this.viewRect.projectionMatrix32 : this.frustum.projectionMatrix32; } bindProjectionMatrix(uniform, forViewCoords) { if (forViewCoords) this.viewRect.bindProjectionMatrix(uniform); else this.frustum.bindProjectionMatrix(uniform); } bindPixelWidthFactor(uniform) { this._pixelWidthFactor.bind(uniform, this); } bindSunDirection(uniform) { this._sunDirection.bind(uniform, this); } updateRenderPlan(plan) { this.style.update(plan); this.hilite.update(plan.hiliteSettings, plan.emphasisSettings); let sunDir; if (plan.lights) { this.lights.update(plan.lights); const useSunDir = plan.viewFlags.shadows || plan.lights.solar.alwaysEnabled; if (useSunDir) sunDir = plan.lights.solar.direction; } this._sunDirection.update(sunDir); } } exports.TargetUniforms = TargetUniforms; //# sourceMappingURL=TargetUniforms.js.map