@itwin/core-frontend
Version:
iTwin.js frontend components
162 lines • 7.25 kB
JavaScript
"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