playcanvas
Version:
PlayCanvas WebGL game engine
94 lines (91 loc) • 2.78 kB
JavaScript
import { EventHandler } from '../../core/event-handler.js';
import { platform } from '../../core/platform.js';
import { UnifiedSortWorker } from './gsplat-unified-sort-worker.js';
class GSplatUnifiedSorter extends EventHandler {
constructor(){
super(), this.bufferLength = 0, this.availableOrderData = [], this.jobsInFlight = 0, this.hasNewVersion = false, this.centersSet = new Set(), this._destroyed = false;
const workerSource = `(${UnifiedSortWorker.toString()})()`;
if (platform.environment === 'node') {
this.worker = new Worker(workerSource, {
eval: true
});
this.worker.on('message', this.onSorted.bind(this));
} else {
this.worker = new Worker(URL.createObjectURL(new Blob([
workerSource
], {
type: "application/javascript"
})));
this.worker.addEventListener('message', this.onSorted.bind(this));
}
}
onSorted(message) {
if (this._destroyed) {
return;
}
const msgData = message.data ?? message;
const orderData = new Uint32Array(msgData.order);
this.jobsInFlight--;
this.fire('sorted', msgData.count, msgData.version, orderData);
if (orderData.length === this.bufferLength) {
this.availableOrderData.push(orderData);
}
}
destroy() {
this._destroyed = true;
this.worker.terminate();
this.worker = null;
}
setCenters(id, centers) {
if (centers) {
if (!this.centersSet.has(id)) {
this.centersSet.add(id);
const centersBuffer = centers.buffer.slice();
this.worker.postMessage({
command: 'addCenters',
id: id,
centers: centersBuffer
}, [
centersBuffer
]);
}
} else {
if (this.centersSet.has(id)) {
this.centersSet.delete(id);
this.worker.postMessage({
command: 'removeCenters',
id: id
});
}
}
}
setSortParameters(payload) {
this.hasNewVersion = true;
const { textureSize } = payload;
const newLength = textureSize * textureSize;
if (newLength !== this.bufferLength) {
this.bufferLength = newLength;
this.availableOrderData.length = 0;
}
this.worker.postMessage(payload);
}
setSortParams(params, radialSorting) {
if (this.hasNewVersion || this.jobsInFlight === 0) {
let orderData = this.availableOrderData.pop();
if (!orderData) {
orderData = new Uint32Array(this.bufferLength);
}
this.jobsInFlight++;
this.hasNewVersion = false;
this.worker.postMessage({
command: 'sort',
sortParams: params,
radialSorting: radialSorting,
order: orderData.buffer
}, [
orderData.buffer
]);
}
}
}
export { GSplatUnifiedSorter };