/*
All material copyright Esri, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/5.0/esri/copyright.txt for details.
*/
import{reallocGrowthFactor as e}from"../../../../core/arrayUtils.js";import"../../../../core/has.js";import{signal as r}from"../../../../core/signal.js";import{n as s}from"../../../../chunks/vec32.js";import{create as t}from"../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{intersectsSphere as i}from"../../../../geometry/support/frustum.js";import{Sphere as n}from"../../../../geometry/support/sphere.js";import{makeScheduleFunction as a}from"../../layers/support/makeScheduleFunction.js";import{GaussianSplatSortWorkerHandle as o}from"../GaussianSplatWorkerHandle.js";import{GaussianSplatFadeTexture as u}from"./GaussianSplatFadeTexture.js";import{GaussianSplatOrderTexture as h}from"./GaussianSplatOrderTexture.js";import{GaussianSplatTextureAtlas as d}from"./GaussianSplatTextureAtlas.js";class l{constructor(e){this._updating=r(!1),this.visibleGaussians=0,this._visibleGaussianTiles=new Array,this._workerHandle=null,this._isSorting=!1,this._pendingSortTask=!1,this._bufferCapacity=0,this._minimumBoundingSphere=new n,this._cameraDirectionNormalized=t(),this._renderer=e,this._orderTexture=new h(this._renderer.renderingContext),this._fadingTexture=new u(this._renderer.renderingContext),this._textureAtlas=new d(this._renderer.renderingContext,this._renderer.view.resourceController.memoryController,this._renderer.fboCache);const{resourceController:s}=this._renderer.view;this._workerHandle=new o(a(s))}get textureAtlas(){return this._textureAtlas}get orderTexture(){return this._orderTexture}get fadingTexture(){return this._fadingTexture}get visibleGaussianTiles(){return this._visibleGaussianTiles}updateGaussianVisibility(e){this._visibleGaussianTiles=e,this.requestSort()}isUpdating(){return this._updating.value}destroy(){this._pendingSortTask=!1,this._workerHandle?.destroyWorkerAndSelf(),this._textureAtlas.destroy(),this._orderTexture.destroy(),this._fadingTexture.destroy()}requestSort(){this._updating.value=!0,this._isSorting?this._pendingSortTask=!0:(this._isSorting=!0,this._pendingSortTask=!1,this._sortOnWorker().then(()=>this._handleSortComplete()).catch(()=>this._handleSortComplete()))}_handleSortComplete(){this._isSorting=!1,this._pendingSortTask?this.requestSort():this._updating.value=!1}_clearBuffersAndTextures(){this._bufferCapacity=0,this._orderTexture.clear(),this._textureAtlas.clear()}_ensureBufferCapacity(r){if(this._bufferCapacity<r){const s=Math.ceil(r*e);this._atlasIndicesBuffer=new Uint32Array(s),this._sortedAtlasIndicesBuffer=new Uint32Array(s),this._distancesBuffer=new Float64Array(s),this._sortOrderBuffer=new Uint32Array(s),this._bufferCapacity=s}}async _sortOnWorker(){if(0===this._visibleGaussianTiles.length)return this.visibleGaussians=0,this._clearBuffersAndTextures(),void this._renderer.requestRender(1);const e=!1;let r=this._visibleGaussianTiles.reduce((e,r)=>e+r.gaussianAtlasIndices.length,0);this._ensureBufferCapacity(r),this._textureAtlas.ensureTextureAtlas();const{frustum:t}=this._renderer.camera;s(this._cameraDirectionNormalized,this._renderer.camera.ray.direction);const n=this._cameraDirectionNormalized[0],a=this._cameraDirectionNormalized[1],o=this._cameraDirectionNormalized[2];let u=0;if(this._visibleGaussianTiles.forEach(e=>{const{gaussianAtlasIndices:s,positions:h}=e;if(this._minimumBoundingSphere.center=e.obb.center,this._minimumBoundingSphere.radius=e.obb.radius+e.maxScale,i(t,this._minimumBoundingSphere))for(let r=0;r<s.length;r++){this._atlasIndicesBuffer[u]=s[r];const e=3*r,t=h[e],i=h[e+1],d=h[e+2];this._distancesBuffer[u]=t*n+i*a+d*o,this._sortOrderBuffer[u]=u,u++}else r-=s.length}),0===r)return this.visibleGaussians=0,this._clearBuffersAndTextures(),void this._renderer.requestRender(1);const h={distances:this._distancesBuffer,sortOrderIndices:this._sortOrderBuffer,numGaussians:r,preciseSort:e};await(this._workerHandle?.sort(h).then(e=>{this._distancesBuffer=e.distances,this._sortOrderBuffer=e.sortedOrderIndices;const s=this._sortedAtlasIndicesBuffer.subarray(0,r);for(let i=0;i<r;i++)s[i]=this._atlasIndicesBuffer[e.sortedOrderIndices[i]];this._orderTexture.setData(s,r);const t=this._renderer.view.qualitySettings.gaussianSplat.maxAllowedVisibleGaussians;this.visibleGaussians=Math.min(r,t),this._renderer.requestRender(1)}))}}export{l as GaussianSplatDataStore};
