playcanvas
Version:
PlayCanvas WebGL game engine
107 lines (104 loc) • 3.24 kB
JavaScript
import { GSplatManager } from './gsplat-manager.js';
class GSplatLayerData {
constructor(device, director, layer, cameraNode){
this.gsplatManager = new GSplatManager(device, director, layer, cameraNode);
}
destroy() {
this.gsplatManager.destroy();
}
}
class GSplatCameraData {
destroy() {
this.layersMap.forEach((layerData)=>layerData.destroy());
this.layersMap.clear();
}
removeLayerData(layer) {
const layerData = this.layersMap.get(layer);
if (layerData) {
layerData.destroy();
this.layersMap.delete(layer);
}
}
getLayerData(device, director, layer, cameraNode) {
let layerData = this.layersMap.get(layer);
if (!layerData) {
layerData = new GSplatLayerData(device, director, layer, cameraNode);
this.layersMap.set(layer, layerData);
}
return layerData;
}
constructor(){
this.layersMap = new Map();
}
}
class GSplatDirector {
constructor(device, renderer, scene, assetLoader){
this.camerasMap = new Map();
this.device = device;
this.renderer = renderer;
this.assetLoader = assetLoader;
this.scene = scene;
}
destroy() {
this.camerasMap.forEach((cameraData)=>cameraData.destroy());
this.camerasMap.clear();
}
getCameraData(camera) {
let cameraData = this.camerasMap.get(camera);
if (!cameraData) {
cameraData = new GSplatCameraData();
this.camerasMap.set(camera, cameraData);
}
return cameraData;
}
update(comp) {
this.camerasMap.forEach((cameraData, camera)=>{
if (!comp.camerasSet.has(camera)) {
cameraData.destroy();
this.camerasMap.delete(camera);
} else {
cameraData.layersMap.forEach((layerData, layer)=>{
if (!camera.layersSet.has(layer.id) || !layer.enabled) {
layerData.destroy();
cameraData.layersMap.delete(layer);
}
});
}
});
let gsplatCount = 0;
const camerasComponents = comp.cameras;
for(let i = 0; i < camerasComponents.length; i++){
const camera = camerasComponents[i].camera;
let cameraData = this.camerasMap.get(camera);
const layerIds = camera.layers;
for(let j = 0; j < layerIds.length; j++){
const layer = comp.getLayerById(layerIds[j]);
if (layer?.enabled) {
if (layer.gsplatPlacementsDirty || !cameraData) {
const placements = layer.gsplatPlacements;
if (placements.length === 0) {
if (cameraData) {
cameraData.removeLayerData(layer);
}
} else {
cameraData ??= this.getCameraData(camera);
const layerData = cameraData.getLayerData(this.device, this, layer, camera.node);
layerData.gsplatManager.reconcile(placements);
}
}
}
}
if (cameraData) {
for (const layerData of cameraData.layersMap.values()){
gsplatCount += layerData.gsplatManager.update();
}
}
}
this.renderer._gsplatCount = gsplatCount;
this.scene.gsplat.dirty = false;
for(let i = 0; i < comp.layerList.length; i++){
comp.layerList[i].gsplatPlacementsDirty = false;
}
}
}
export { GSplatDirector };