@itwin/core-frontend
Version:
iTwin.js frontend components
222 lines • 10.1 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.BranchUniforms = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
const core_geometry_1 = require("@itwin/core-geometry");
const BranchStack_1 = require("./BranchStack");
const BatchState_1 = require("./BatchState");
const Matrix_1 = require("./Matrix");
const RenderCommands_1 = require("./RenderCommands");
const Sync_1 = require("./Sync");
const ClipStack_1 = require("./ClipStack");
const IModelApp_1 = require("../../../IModelApp");
function equalXYZs(a, b) {
if (a === b)
return true;
if ((undefined === a) !== (undefined === b))
return false;
if (undefined !== a && undefined !== b)
return a.isExactEqual(b);
(0, core_bentley_1.assert)(undefined === a && undefined === b);
return true;
}
/** Maintains uniform variable state associated with the Branch currently being drawn by a Target.
* @internal
*/
class BranchUniforms {
clipStack;
_viewClipEnabled = false;
// The model-view and model-view-projection matrices depend on the frustum.
syncToken;
syncKey = 0;
_stack = new BranchStack_1.BranchStack();
_target;
// Parameters that affect synchronization.
_isInstanced = false;
_viewIndependentOrigin;
// CPU state
_mv = core_geometry_1.Matrix4d.createIdentity();
_mvp = core_geometry_1.Matrix4d.createIdentity();
// GPU state
_mv32 = new Matrix_1.Matrix4();
_mvp32 = new Matrix_1.Matrix4();
_m32 = new Matrix_1.Matrix4();
_v32 = new Matrix_1.Matrix3();
// Working state
_scratchTransform = core_geometry_1.Transform.createIdentity();
_scratchTransform2 = core_geometry_1.Transform.createIdentity();
_scratchViewToWorld = core_geometry_1.Matrix3d.createIdentity();
_scratchVIModelMatrix = core_geometry_1.Transform.createIdentity();
_zeroPoint = new core_geometry_1.Point3d(0, 0, 0);
get stack() { return this._stack; }
constructor(target) {
this._target = target;
this.clipStack = new ClipStack_1.ClipStack(() => target.uniforms.frustum.viewMatrix, () => this._viewClipEnabled && this.top.viewFlags.clipVolume);
}
createBatchState() {
return new BatchState_1.BatchState(this._stack);
}
createRenderCommands(batchState) {
return new RenderCommands_1.RenderCommands(this._target, this._stack, batchState);
}
get modelViewMatrix() {
return this._mv;
}
get top() {
return this._stack.top;
}
get length() {
return this._stack.length;
}
pushBranch(branch) {
(0, Sync_1.desync)(this);
this._stack.pushBranch(branch);
this.setClipStyle(this.top.disableClipStyle);
if (this.top.clipVolume)
this.clipStack.push(this.top.clipVolume);
if (branch.branch.realityModelDisplaySettings)
this._target.uniforms.realityModel.update(branch.branch.realityModelDisplaySettings);
}
pushState(state) {
(0, Sync_1.desync)(this);
this._stack.pushState(state);
if (this.top.clipVolume)
this.clipStack.push(this.top.clipVolume);
if (state.realityModelDisplaySettings)
this._target.uniforms.realityModel.update(state.realityModelDisplaySettings);
}
pop() {
(0, Sync_1.desync)(this);
if (this.top.clipVolume)
this.clipStack.pop();
this._stack.pop();
this.setClipStyle(this.top.disableClipStyle);
}
pushViewClip() {
(0, core_bentley_1.assert)(!this._viewClipEnabled);
this._viewClipEnabled = true;
// Target.readPixels() pushes another BranchState before pushing view clip...
(0, core_bentley_1.assert)((this._target.isReadPixelsInProgress ? 2 : 1) === this._stack.length);
}
popViewClip() {
(0, core_bentley_1.assert)(this._viewClipEnabled);
this._viewClipEnabled = false;
(0, core_bentley_1.assert)((this._target.isReadPixelsInProgress ? 2 : 1) === this._stack.length);
}
changeRenderPlan(vf, is3d, hline, contourLine) {
this._stack.changeRenderPlan(vf, is3d, hline, contourLine);
}
updateViewClip(clip, style) {
this.clipStack.setViewClip(clip, style);
}
overrideFeatureSymbology(ovr) {
this._stack.setSymbologyOverrides(ovr);
}
bindModelViewMatrix(uniform, geom, isViewCoords) {
if (this.update(uniform, geom, isViewCoords))
uniform.setMatrix4(this._mv32);
}
bindModelViewProjectionMatrix(uniform, geom, isViewCoords) {
if (this.update(uniform, geom, isViewCoords))
uniform.setMatrix4(this._mvp32);
}
bindModelToWorldTransform(uniform, geom, isViewCoords) {
if (this.update(uniform, geom, isViewCoords))
uniform.setMatrix4(this._m32);
}
bindWorldToViewNTransform(uniform, geom, isViewCoords) {
if (this.update(uniform, geom, isViewCoords))
uniform.setMatrix3(this._v32);
}
update(uniform, geometry, isViewCoords) {
const uniforms = this._target.uniforms[isViewCoords ? "viewRect" : "frustum"];
if (!(0, Sync_1.sync)(uniforms, this))
(0, Sync_1.desync)(this);
const instancedGeom = geometry.asInstanced;
if (undefined !== instancedGeom || this._isInstanced) {
this._isInstanced = undefined !== instancedGeom;
(0, Sync_1.desync)(this);
}
const vio = geometry.viewIndependentOrigin;
if (!equalXYZs(vio, this._viewIndependentOrigin)) {
this._viewIndependentOrigin = vio;
(0, Sync_1.desync)(this);
}
if ((0, Sync_1.sync)(this, uniform))
return false;
let mv;
const modelMatrix = this._target.currentTransform;
if (isViewCoords) {
// Zero out Z for silly clipping tools...
mv = modelMatrix.clone(this._scratchTransform);
mv.matrix.coffs[2] = mv.matrix.coffs[5] = mv.matrix.coffs[8] = 0.0;
if (instancedGeom)
mv = instancedGeom.getRtcModelTransform(mv);
// Scale based on device-pixel ratio.
const scale = this._target.devicePixelRatio;
const viewMatrix = core_geometry_1.Transform.createScaleAboutPoint(this._zeroPoint, scale, this._scratchTransform2);
viewMatrix.multiplyTransformTransform(mv, mv);
}
else {
const viewMatrix = this._target.uniforms.frustum.viewMatrix;
if (undefined !== instancedGeom) {
// For instanced geometry, the "model view" matrix is really a transform from center of instanced geometry range to view.
// Shader will compute final model-view matrix based on this and the per-instance transform.
if (vio) {
const viewToWorldRot = viewMatrix.matrix.inverse(this._scratchViewToWorld);
const rotateAboutOrigin = core_geometry_1.Transform.createFixedPointAndMatrix(vio, viewToWorldRot, this._scratchTransform2);
const viModelMatrix = rotateAboutOrigin.multiplyTransformTransform(instancedGeom.getRtcModelTransform(modelMatrix), this._scratchVIModelMatrix);
mv = viewMatrix.multiplyTransformTransform(viModelMatrix, this._scratchTransform);
}
else {
mv = viewMatrix.multiplyTransformTransform(instancedGeom.getRtcModelTransform(modelMatrix), this._scratchTransform);
}
}
else {
if (undefined !== vio) {
const viewToWorldRot = viewMatrix.matrix.inverse(this._scratchViewToWorld);
const rotateAboutOrigin = core_geometry_1.Transform.createFixedPointAndMatrix(vio, viewToWorldRot, this._scratchTransform2);
const viModelMatrix = rotateAboutOrigin.multiplyTransformTransform(modelMatrix, this._scratchVIModelMatrix);
mv = viewMatrix.multiplyTransformTransform(viModelMatrix, this._scratchTransform);
}
else {
mv = viewMatrix.multiplyTransformTransform(modelMatrix, this._scratchTransform);
}
}
}
if (this._target.wantThematicDisplay) {
this._m32.initFromTransform(modelMatrix);
this._v32.initFromMatrix3d(this._target.uniforms.frustum.viewMatrix.matrix);
}
else if (undefined !== geometry.asSurface?.mesh.constantLodVParams || this._target.uniforms.batch.wantContourLines) {
this._m32.initFromTransform(modelMatrix);
}
core_geometry_1.Matrix4d.createTransform(mv, this._mv);
this._mv32.initFromTransform(mv);
// Don't bother computing mvp for instanced geometry - it's not used.
if (!this._isInstanced) {
uniforms.projectionMatrix.multiplyMatrixMatrix(this._mv, this._mvp);
this._mvp32.initFromMatrix4d(this._mvp);
}
return true;
}
// set the clip style based on disableClipStyle
setClipStyle(disableClipStyle) {
const vp = IModelApp_1.IModelApp.viewManager.selectedView;
if (vp) {
const style = vp.view.displayStyle.settings.clipStyle;
this.clipStack.insideColor.alpha = disableClipStyle ? 0 : (style.insideColor ? 1 : 0);
this.clipStack.outsideColor.alpha = disableClipStyle ? 0 : (style.outsideColor ? 1 : 0);
this.clipStack.intersectionStyle.alpha = disableClipStyle ? 0 : (style.intersectionStyle ? style.intersectionStyle.width : 0);
}
}
}
exports.BranchUniforms = BranchUniforms;
//# sourceMappingURL=BranchUniforms.js.map