@itwin/core-frontend
Version:
iTwin.js frontend components
149 lines • 8.51 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.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.BackgroundMapDrape = void 0;
/** @packageDocumentation
* @module WebGL
*/
const core_bentley_1 = require("@itwin/core-bentley");
const core_geometry_1 = require("@itwin/core-geometry");
const core_common_1 = require("@itwin/core-common");
const internal_1 = require("../../../tile/internal");
const FeatureSymbology_1 = require("../../../render/FeatureSymbology");
const BatchState_1 = require("./BatchState");
const BranchStack_1 = require("./BranchStack");
const FrameBuffer_1 = require("./FrameBuffer");
const GL_1 = require("./GL");
const PlanarTextureProjection_1 = require("./PlanarTextureProjection");
const RenderCommands_1 = require("./RenderCommands");
const System_1 = require("./System");
const Texture_1 = require("./Texture");
const TextureDrape_1 = require("./TextureDrape");
/** @internal */
class BackgroundMapDrape extends TextureDrape_1.TextureDrape {
_fbo;
_graphics = [];
_frustum;
_width = 0;
_height = 0;
_mapTree;
_drapedTree;
static _postProjectionMatrix = core_geometry_1.Matrix4d.createRowValues(0, 1, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 1);
_debugFrustum;
_debugFrustumGraphic = undefined;
_symbologyOverrides = new FeatureSymbology_1.FeatureSymbology.Overrides();
_bgColor = core_common_1.ColorDef.from(0, 0, 0, 255);
_plane = (0, core_bentley_1.expectDefined)(core_geometry_1.Plane3dByOriginAndUnitNormal.create(core_geometry_1.Point3d.createZero(), core_geometry_1.Vector3d.create(0, 0, 1)));
constructor(drapedTree, mapTree) {
super();
this._drapedTree = drapedTree;
this._mapTree = mapTree;
}
get isDisposed() { return super.isDisposed && undefined === this._fbo; }
[Symbol.dispose]() {
super[Symbol.dispose]();
this._fbo = (0, core_bentley_1.dispose)(this._fbo);
}
addGraphic(graphic) {
this._graphics.push(graphic);
}
static create(draped, map) {
return new BackgroundMapDrape(draped, map);
}
collectGraphics(context) {
this._graphics.length = 0;
if (undefined === context.viewingSpace)
return;
const viewState = context.viewingSpace.view;
if (undefined === viewState)
return;
const tileTree = this._mapTree.treeOwner.load();
if (undefined === tileTree || !this._mapTree.layerRefHandler.initializeLayers(context))
return;
const requiredWidth = 2 * Math.max(context.target.viewRect.width, context.target.viewRect.height); // TBD - Size to textured area.
const requiredHeight = requiredWidth;
if (requiredWidth !== this._width || requiredHeight !== this._height)
this[Symbol.dispose]();
this._width = requiredWidth;
this._height = requiredHeight;
const targetTree = this._drapedTree.treeOwner.tileTree;
const args = this._drapedTree.createDrawArgs(context);
if (!targetTree || !args)
return;
const targetTiles = targetTree.selectTiles(args);
const projection = PlanarTextureProjection_1.PlanarTextureProjection.computePlanarTextureProjection(this._plane, context, { tiles: targetTiles, location: args.location }, [this._mapTree], viewState, this._width, this._height, core_geometry_1.Range3d.createNull());
if (!projection.textureFrustum || !projection.projectionMatrix || !projection.worldToViewMap)
return;
this._frustum = projection.textureFrustum;
this._debugFrustum = projection.debugFrustum;
this._projectionMatrix = projection.projectionMatrix;
const drawArgs = internal_1.GraphicsCollectorDrawArgs.create(context, this, this._mapTree, core_common_1.FrustumPlanes.fromFrustum(this._frustum), projection.worldToViewMap);
if (undefined !== drawArgs)
tileTree.draw(drawArgs);
if (context.target.debugControl && context.target.debugControl.displayDrapeFrustum) {
this._debugFrustumGraphic = (0, core_bentley_1.dispose)(this._debugFrustumGraphic);
const builder = context.createSceneGraphicBuilder();
builder.setSymbology(core_common_1.ColorDef.green, core_common_1.ColorDef.green, 1);
builder.addFrustum(context.viewingSpace.getFrustum());
builder.setSymbology(core_common_1.ColorDef.red, core_common_1.ColorDef.red, 1);
builder.addFrustum((0, core_bentley_1.expectDefined)(this._debugFrustum));
builder.setSymbology(core_common_1.ColorDef.white, core_common_1.ColorDef.white, 1);
builder.addFrustum(this._frustum);
this._debugFrustumGraphic = builder.finish();
}
}
draw(target) {
if (undefined !== this._debugFrustumGraphic)
target.graphics.foreground.push(this._debugFrustumGraphic);
if (undefined === this._frustum || this._graphics.length === 0)
return;
if (undefined === this._fbo) {
const colorTextureHandle = Texture_1.TextureHandle.createForAttachment(this._width, this._height, GL_1.GL.Texture.Format.Rgba, GL_1.GL.Texture.DataType.UnsignedByte);
if (undefined === colorTextureHandle) {
(0, core_bentley_1.assert)(false, "Failed to create planar texture");
return;
}
this._texture = new Texture_1.Texture({ ownership: "external", type: core_common_1.RenderTexture.Type.TileSection, handle: colorTextureHandle, transparency: core_common_1.TextureTransparency.Opaque });
this._fbo = FrameBuffer_1.FrameBuffer.create([colorTextureHandle]);
}
if (undefined === this._fbo) {
(0, core_bentley_1.assert)(false, "unable to create frame buffer object");
return;
}
System_1.System.instance.glTimer.beginOperation("Terrain Projection");
const prevState = System_1.System.instance.currentRenderState.clone();
System_1.System.instance.context.viewport(0, 0, this._width, this._height);
const prevPlan = target.plan;
const drawingParams = PlanarTextureProjection_1.PlanarTextureProjection.getTextureDrawingParams(target);
const stack = new BranchStack_1.BranchStack();
stack.changeRenderPlan(drawingParams.viewFlags, prevPlan.is3d, prevPlan.hline, prevPlan.contours);
stack.setSymbologyOverrides(this._symbologyOverrides);
const batchState = new BatchState_1.BatchState(stack);
System_1.System.instance.applyRenderState(drawingParams.state);
target.uniforms.style.changeBackgroundColor(this._bgColor); // Avoid white on white reversal. Will be reset below in changeRenderPlan().
target.changeFrustum(this._frustum, this._frustum.getFraction(), true);
const prevProjMatrix = target.uniforms.frustum.projectionMatrix;
target.uniforms.frustum.changeProjectionMatrix(BackgroundMapDrape._postProjectionMatrix.multiplyMatrixMatrix(prevProjMatrix));
target.uniforms.branch.pushState(stack.top);
const renderCommands = new RenderCommands_1.RenderCommands(target, stack, batchState);
renderCommands.addGraphics(this._graphics, 5 /* RenderPass.OpaqueGeneral */);
const system = System_1.System.instance;
const gl = system.context;
system.frameBufferStack.execute(this._fbo, true, false, () => {
gl.clearColor(0, 0, 0, 0);
gl.clear(GL_1.GL.BufferBit.Color);
target.techniques.execute(target, renderCommands.getCommands(5 /* RenderPass.OpaqueGeneral */), 19 /* RenderPass.PlanarClassification */); // Draw these with RenderPass.PlanarClassification (rather than Opaque...) so that the pick ordering is avoided.
});
target.uniforms.branch.pop();
batchState.reset(); // Reset the batch Ids...
target.changeRenderPlan(prevPlan);
system.applyRenderState(prevState);
gl.viewport(0, 0, target.viewRect.width, target.viewRect.height); // Restore viewport
system.glTimer.endOperation();
}
}
exports.BackgroundMapDrape = BackgroundMapDrape;
//# sourceMappingURL=BackgroundMapDrape.js.map