UNPKG

playcanvas

Version:

Open-source WebGL/WebGPU 3D engine for the web

93 lines (92 loc) 3.23 kB
import { Vec3 } from "../../../core/math/vec3.js"; import { BoundingBox } from "../../../core/shape/bounding-box.js"; import { GSplatDirector } from "../../../scene/gsplat-unified/gsplat-director.js"; import { Component } from "../component.js"; import { ComponentSystem } from "../system.js"; import { GSplatComponent } from "./component.js"; import { GSplatComponentData } from "./data.js"; import { gsplatChunksGLSL } from "../../../scene/shader-lib/glsl/collections/gsplat-chunks-glsl.js"; import { gsplatChunksWGSL } from "../../../scene/shader-lib/wgsl/collections/gsplat-chunks-wgsl.js"; import { SHADERLANGUAGE_GLSL, SHADERLANGUAGE_WGSL } from "../../../platform/graphics/constants.js"; import { ShaderChunks } from "../../../scene/shader-lib/shader-chunks.js"; const _schema = [ "enabled" ]; const _properties = [ "unified", "lodBaseDistance", "lodMultiplier", "castShadows", "material", "highQualitySH", "asset", "resource", "layers" ]; class GSplatComponentSystem extends ComponentSystem { static EVENT_MATERIALCREATED = "material:created"; static EVENT_FRAMEREADY = "frame:ready"; constructor(app) { super(app); this.id = "gsplat"; this.ComponentType = GSplatComponent; this.DataType = GSplatComponentData; this.schema = _schema; app.renderer.gsplatDirector = new GSplatDirector(app.graphicsDevice, app.renderer, app.scene, this); ShaderChunks.get(app.graphicsDevice, SHADERLANGUAGE_GLSL).add(gsplatChunksGLSL); ShaderChunks.get(app.graphicsDevice, SHADERLANGUAGE_WGSL).add(gsplatChunksWGSL); this.on("beforeremove", this.onRemove, this); } initializeComponentData(component, _data, properties) { if (_data.layers && _data.layers.length) { _data.layers = _data.layers.slice(0); } for (let i = 0; i < _properties.length; i++) { if (_data.hasOwnProperty(_properties[i])) { component[_properties[i]] = _data[_properties[i]]; } } if (_data.aabbCenter && _data.aabbHalfExtents) { component.customAabb = new BoundingBox(new Vec3(_data.aabbCenter), new Vec3(_data.aabbHalfExtents)); } super.initializeComponentData(component, _data, _schema); } cloneComponent(entity, clone) { const gSplatComponent = entity.gsplat; const data = {}; _properties.forEach((prop) => { if (prop === "material") { if (!gSplatComponent.unified) { const srcMaterial = gSplatComponent[prop]; if (srcMaterial) { data[prop] = srcMaterial.clone(); } } } else { data[prop] = gSplatComponent[prop]; } }); data.enabled = gSplatComponent.enabled; const component = this.addComponent(clone, data); component.customAabb = gSplatComponent.customAabb?.clone() ?? null; return component; } onRemove(entity, component) { component.onRemove(); } getMaterial(camera, layer) { const director = this.app.renderer.gsplatDirector; if (!director) return null; const cameraData = director.camerasMap.get(camera); if (!cameraData) return null; const layerData = cameraData.layersMap.get(layer); return layerData?.gsplatManager?.material ?? null; } getGSplatMaterial(camera, layer) { return this.getMaterial(camera, layer); } } Component._buildAccessors(GSplatComponent.prototype, _schema); export { GSplatComponentSystem };