UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

85 lines (82 loc) 2.71 kB
import { Mat4 } from '../../core/math/mat4.js'; import { Vec4 } from '../../core/math/vec4.js'; import { BoundingBox } from '../../core/shape/bounding-box.js'; import { GSplatIntervalTexture } from './gsplat-interval-texture.js'; const vecs = []; class GSplatInfo { constructor(device, resource, placement){ this.activeSplats = 0; this.intervals = []; this.lineStart = 0; this.lineCount = 0; this.padding = 0; this.viewport = new Vec4(); this.previousWorldTransform = new Mat4(); this.aabb = new BoundingBox(); this.intervalTexture = null; this.device = device; this.resource = resource; this.node = placement.node; this.lodIndex = placement.lodIndex; this.numSplats = resource.numSplats; this.aabb.copy(placement.aabb); this.updateIntervals(placement.intervals); } destroy() { this.intervals.length = 0; this.intervalTexture?.destroy(); } setLines(start, count, textureSize, activeSplats) { this.lineStart = start; this.lineCount = count; this.padding = textureSize * count - activeSplats; this.viewport.set(0, start, textureSize, count); } updateIntervals(intervals) { const resource = this.resource; this.intervals.length = 0; this.activeSplats = resource.numSplats; if (intervals.size > 0) { let totalCount = 0; let used = 0; for (const interval of intervals.values()){ totalCount += interval.y - interval.x + 1; vecs[used++] = interval; } if (totalCount !== this.numSplats) { vecs.length = used; vecs.sort((a, b)=>a.x - b.x); this.intervals.length = used * 2; let k = 0; let currentStart = vecs[0].x; let currentEnd = vecs[0].y; for(let i = 1; i < used; i++){ const p = vecs[i]; if (p.x === currentEnd + 1) { currentEnd = p.y; } else { this.intervals[k++] = currentStart; this.intervals[k++] = currentEnd + 1; currentStart = p.x; currentEnd = p.y; } } this.intervals[k++] = currentStart; this.intervals[k++] = currentEnd + 1; this.intervals.length = k; this.intervalTexture = new GSplatIntervalTexture(this.device); this.activeSplats = this.intervalTexture.update(this.intervals, totalCount); } vecs.length = 0; } } update() { const worldMatrix = this.node.getWorldTransform(); const worldMatrixChanged = !this.previousWorldTransform.equals(worldMatrix); if (worldMatrixChanged) { this.previousWorldTransform.copy(worldMatrix); } return worldMatrixChanged; } } export { GSplatInfo };