utils/TerrainWorker.tstypescript
// import { QueueArray } from '../QueueArray.js';
import { BaseWorker } from "./BaseWorker";
import { Segment } from "../segment/Segment";
import type { NumberArray6 } from "../bv/Sphere";
//@ts-ignore
import TerrainWorkerImpl from "./TerrainWorker.worker.js?worker&inline";
import { NumberArray3 } from "../math/Vec3";
interface TerrainInfo {
segment: Segment;
elevations: Float32Array;
}
export interface ITerrainWorkerData {
id: number;
normalMapNormals: Float32Array | null;
normalMapVertices: Float64Array | null;
terrainVertices: Float64Array | null;
terrainVerticesHigh: Float32Array | null;
terrainVerticesLow: Float32Array | null;
noDataVertices: Uint8Array | null;
bounds: NumberArray6;
radiusRange: number[] | null;
relativeCenter: NumberArray3;
}
type MessageEventExt = MessageEvent & {
data: ITerrainWorkerData;
};
class TerrainWorker extends BaseWorker<TerrainInfo> {
constructor(numWorkers: number = 2) {
super(numWorkers, TerrainWorkerImpl);
}
protected override _onMessage(e: MessageEventExt) {
this._source.get(e.data.id)!.segment._terrainWorkerCallback(e.data);
this._source.delete(e.data.id);
e.data.normalMapNormals = null;
e.data.normalMapVertices = null;
e.data.terrainVertices = null;
e.data.terrainVerticesHigh = null;
e.data.terrainVerticesLow = null;
e.data.noDataVertices = null;
e.data.bounds = null;
e.data.relativeCenter = null;
}
public override make(info: TerrainInfo) {
if (info.segment.plainReady && info.segment.terrainIsLoading) {
if (this._workerQueue.length) {
const w = this._workerQueue.pop()!;
this._source.set(this._sourceId, info);
let segment = info.segment;
w.postMessage(
{
elevations: info.elevations,
this_plainVertices: segment.plainVertices,
this_plainNormals: segment.plainNormals,
this_normalMapVertices: segment.normalMapVertices,
this_normalMapNormals: segment.normalMapNormals,
heightFactor: segment.planet._heightFactor,
gridSize: segment.planet.terrain!.gridSizeByZoom[segment.tileZoom],
noDataValues: segment.planet.terrain!.noDataValues,
id: this._sourceId,
relativeCenter: [
segment._relativeCenter.x,
segment._relativeCenter.y,
segment._relativeCenter.z
]
},
[
info.elevations.buffer,
segment.plainVertices!.buffer,
segment.plainNormals!.buffer,
segment.normalMapVertices!.buffer,
segment.normalMapNormals!.buffer
]
);
this._sourceId++;
} else {
this._pendingQueue.push(info);
}
} else {
this.check();
}
}
}
export { TerrainWorker };