@itwin/core-frontend
Version:
iTwin.js frontend components
117 lines • 4.65 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 { assert, dispose } from "@itwin/core-bentley";
import { Range3d, Transform } from "@itwin/core-geometry";
import { ThematicDisplaySensor } from "@itwin/core-common";
import { GL } from "./GL";
import { Texture2DHandle } from "./Texture";
import { TextureUnit } from "./RenderFlags";
/** Maintains a floating-point texture representing a list of thematic sensors.
* @internal
*/
export class ThematicSensors {
_texture;
/** Used for writing to texture data. */
_view;
/** Position at which to write next texture data. */
_curPos = 0;
target;
range;
sensorSettings;
get numSensors() { return this._sensors.length; }
_sensors;
_viewMatrix = Transform.createIdentity();
matchesTarget(target) {
return target === this.target && this.sensorSettings === target.plan.thematic?.sensorSettings;
}
static create(target, range) {
let sensors = [];
if (target.plan.thematic !== undefined) {
sensors = _accumulateSensorsInRange(target.plan.thematic.sensorSettings.sensors, range, target.currentTransform, target.plan.thematic.sensorSettings.distanceCutoff);
}
const obj = this.createFloat(target, range, sensors);
obj._update(obj.target.uniforms.frustum.viewMatrix);
return obj;
}
get isDisposed() { return this._texture.handle.isDisposed; }
[Symbol.dispose]() {
dispose(this._texture.handle);
}
bindNumSensors(uniform) {
uniform.setUniform1i(this.numSensors);
}
bindTexture(uniform) {
this._texture.handle.bindSampler(uniform, TextureUnit.ThematicSensors);
}
get bytesUsed() { return this._texture.handle.bytesUsed; }
get texture() { return this._texture.handle; }
_update(viewMatrix) {
this._viewMatrix.setFrom(viewMatrix);
this.reset();
for (const sensor of this._sensors) {
const position = this._viewMatrix.multiplyPoint3d(sensor.position);
this.appendSensor(position, sensor.value);
}
this._texture.handle.replaceTextureData(this._texture.data);
}
update(viewMatrix) {
if (!this._viewMatrix.isAlmostEqual(viewMatrix)) {
this._update(viewMatrix);
}
}
constructor(texture, target, range, sensors) {
this.target = target;
this.range = range;
this.sensorSettings = target.plan.thematic?.sensorSettings;
this._sensors = sensors;
this._texture = texture;
this._view = new DataView(texture.data.buffer);
}
static createFloat(target, range, sensors) {
const data = new Float32Array(sensors.length * 4);
const handle = Texture2DHandle.createForData(1, sensors.length, data, false, GL.Texture.WrapMode.ClampToEdge, GL.Texture.Format.Rgba);
assert(undefined !== handle);
return new this({ handle, data }, target, range, sensors);
}
append(value) { this.appendFloat(value); }
appendFloat(value) {
this._view.setFloat32(this._curPos, value, true);
this.advance(4);
}
appendUint8(value) {
this._view.setUint8(this._curPos, value);
this.advance(1);
}
advance(numBytes) { this._curPos += numBytes; }
reset() { this._curPos = 0; }
appendValues(a, b, c, d) {
this.append(a);
this.append(b);
this.append(c);
this.append(d);
}
appendSensor(position, value) { this.appendValues(position.x, position.y, position.z, value); }
}
function _sensorRadiusAffectsRange(sensor, sensorRadius, range) {
const distance = range.distanceToPoint(sensor.position);
return !(distance > sensorRadius);
}
const scratchRange = Range3d.createNull();
function _accumulateSensorsInRange(sensors, range, transform, distanceCutoff) {
const retSensors = [];
transform.multiplyRange(range, scratchRange);
for (const sensor of sensors) {
const position = sensor.position;
if (distanceCutoff <= 0 || _sensorRadiusAffectsRange(sensor, distanceCutoff, scratchRange)) {
const value = sensor.value;
retSensors.push(ThematicDisplaySensor.fromJSON({ position, value }));
}
}
return retSensors;
}
//# sourceMappingURL=ThematicSensors.js.map