playcanvas
Version:
PlayCanvas WebGL game engine
108 lines (105 loc) • 2.88 kB
JavaScript
import { EventHandler } from '../../core/event-handler.js';
import { TEXTURELOCK_READ } from '../../platform/graphics/constants.js';
import { platform } from '../../core/platform.js';
import { SortWorker } from './gsplat-sort-worker.js';
class GSplatSorter extends EventHandler {
constructor(){
super();
const messageHandler = (message)=>{
const msgData = message.data ?? message;
const newOrder = msgData.order;
const oldOrder = this.orderTexture._levels[0].buffer;
this.worker.postMessage({
order: oldOrder
}, [
oldOrder
]);
this.orderTexture._levels[0] = new Uint32Array(newOrder);
this.orderTexture.upload();
this.fire('updated', msgData.count);
};
const workerSource = `(${SortWorker.toString()})()`;
if (platform.environment === 'node') {
this.worker = new Worker(workerSource, {
eval: true
});
this.worker.on('message', messageHandler);
} else {
this.worker = new Worker(URL.createObjectURL(new Blob([
workerSource
], {
type: "application/javascript"
})));
this.worker.addEventListener('message', messageHandler);
}
}
destroy() {
this.worker.terminate();
this.worker = null;
}
init(orderTexture, centers, chunks) {
this.orderTexture = orderTexture;
this.centers = centers.slice();
const orderBuffer = this.orderTexture.lock({
mode: TEXTURELOCK_READ
}).slice();
this.orderTexture.unlock();
for(let i = 0; i < orderBuffer.length; ++i){
orderBuffer[i] = i;
}
const obj = {
order: orderBuffer.buffer,
centers: centers.buffer,
chunks: chunks?.buffer
};
const transfer = [
orderBuffer.buffer,
centers.buffer
].concat(chunks ? [
chunks.buffer
] : []);
this.worker.postMessage(obj, transfer);
}
setMapping(mapping) {
if (mapping) {
const centers = new Float32Array(mapping.length * 3);
for(let i = 0; i < mapping.length; ++i){
const src = mapping[i] * 3;
const dst = i * 3;
centers[dst + 0] = this.centers[src + 0];
centers[dst + 1] = this.centers[src + 1];
centers[dst + 2] = this.centers[src + 2];
}
this.worker.postMessage({
centers: centers.buffer,
mapping: mapping.buffer
}, [
centers.buffer,
mapping.buffer
]);
} else {
const centers = this.centers.slice();
this.worker.postMessage({
centers: centers.buffer,
mapping: null
}, [
centers.buffer
]);
}
}
setCamera(pos, dir) {
this.worker.postMessage({
cameraPosition: {
x: pos.x,
y: pos.y,
z: pos.z
},
cameraDirection: {
x: dir.x,
y: dir.y,
z: dir.z
}
});
}
}
export { GSplatSorter };