@itwin/core-frontend
Version:
iTwin.js frontend components
115 lines • 5.42 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* 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
*/
import { PointCloudDisplaySettings } from "@itwin/core-common";
import { desync, sync } from "./Sync";
import { Vector3d } from "@itwin/core-geometry";
/** A Target keeps track of the current settings for drawing point clouds.
* Pushing a Branch may *replace* the current settings. Popping the Branch does not reset them. It is expected that every Branch containing
* a point cloud will also specify the settings for drawing that point cloud.
* This permits the same point cloud graphics to be rendered differently in different viewports.
* In future these uniforms will include eye-dome lighting.
* @internal
*/
export class PointCloudUniforms {
syncKey = 0;
_settings = PointCloudDisplaySettings.defaults;
_scaleFactor = 8.0;
_is3d = true;
// vec3 u_pointSize
// x = fixed point size in pixels if > 0, else scale applied to voxel size (negated).
// y = minimum size in pixels if using voxel size.
// z = maximum size in pixels if using voxel size
// w = 1.0 if drawing square points, 0.0 if round.
_vec4 = new Float32Array(4);
// x = strength - 0.0 disables EDL
// y = radius
// z =
// w =
_edl1 = new Float32Array(4);
_edl2 = new Float32Array(4);
constructor() {
this.initialize(this._settings);
}
update(settings) {
if (this._settings.equals(settings))
return;
this._settings = settings;
desync(this);
this.initialize(settings);
}
updateRange(range, target, xform, is3d) {
let rangeFactor = 8.0; // default to min scale factor of 8
const near = target.uniforms.frustum.nearPlane;
const far = target.uniforms.frustum.farPlane;
const viewDepth = far - near;
if (range !== undefined) {
const scale = xform.matrix;
// calculate a "normalized" strength factor based on the size of the point cloud versus the current viewing depth
// from the matrix, only care about scaling factor here (entries 0,4,8) to scale the range lengths
// then use the largest length component as the reference for the size of the point cloud
const rangeScale = Vector3d.create(scale.coffs[0] * range.xLength(), scale.coffs[4] * range.xLength(), scale.coffs[8] * range.xLength()).maxAbs();
// limit the viewDepth/rangeScale ratio to min of 10 to still get reasonable factors when close to and inside the model
rangeFactor = Math.log(Math.max(10, viewDepth / rangeScale));
}
const zoomFactor = Math.log(far / near); // compensate for zoom level
const winSizeFactor = Math.pow(1.8440033, Math.log2(2226 / target.uniforms.viewRect.width)); // compensate for window size
const scaleFactor = (rangeFactor + zoomFactor) / winSizeFactor;
if (this._scaleFactor === scaleFactor && this._is3d === is3d)
return;
this._scaleFactor = scaleFactor;
this._is3d = is3d;
desync(this);
this.initialize(this._settings);
}
bind(uniform) {
if (!sync(this, uniform))
uniform.setUniform4fv(this._vec4);
}
bindEDL1(uniform) {
if (!sync(this, uniform))
uniform.setUniform4fv(this._edl1);
}
bindEDL2(uniform) {
if (!sync(this, uniform))
uniform.setUniform4fv(this._edl2);
}
initialize(settings) {
this._vec4[0] = "pixel" === settings.sizeMode ? settings.pixelSize : -settings.voxelScale;
this._vec4[1] = settings.minPixelsPerVoxel;
this._vec4[2] = settings.maxPixelsPerVoxel;
this._vec4[3] = "square" === settings.shape ? 1 : 0;
this._edl1[0] = settings.edlStrength;
this._edl1[1] = settings.edlRadius;
this._edl1[2] = this._scaleFactor;
this._edl1[3] = this._is3d ? 1 : 0;
this._edl2[0] = settings?.edlMixWts1 ?? 1.0;
this._edl2[1] = settings?.edlMixWts2 ?? 0.5;
this._edl2[2] = settings?.edlMixWts4 ?? 0.25;
this._edl2[3] = 0;
}
}
/** Uniforms affecting how reality models are drawn.
* Pushing a Branch may *replace* the current settings. Popping the Branch does not reset them. It is expected that every Branch containing
* a reality model will also specify the settings for drawing that reality model.
* This permits the same reality model graphics to be rendered differently in different viewports.
* In future these uniforms may include additional settings for reality meshes - currently only the override color ratio applies to them.
* @internal
*/
export class RealityModelUniforms {
// ###TODO when we need it: public readonly mesh = new RealityMeshUniforms();
pointCloud = new PointCloudUniforms();
_overrideColorMix = 0.5;
update(settings) {
this._overrideColorMix = settings.overrideColorRatio;
this.pointCloud.update(settings.pointCloud);
}
bindOverrideColorMix(uniform) {
uniform.setUniform1f(this._overrideColorMix);
}
}
//# sourceMappingURL=RealityModelUniforms.js.map