/*
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{signal as r}from"../../../../core/signal.js";import{n as t}from"../../../../chunks/vec32.js";import{create as s}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._useDeterministicSort=!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=s(),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:t}=this._renderer.view;this._workerHandle=new o(a(t))}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 t=Math.ceil(r*e);this._atlasIndicesBuffer=new Uint32Array(t),this._sortedAtlasIndicesBuffer=new Uint32Array(t),this._distancesBuffer=new Float64Array(t),this._sortOrderBuffer=new Uint32Array(t),this._bufferCapacity=t}}async _sortOnWorker(){if(0===this._visibleGaussianTiles.length)return this.visibleGaussians=0,this._clearBuffersAndTextures(),void this._renderer.requestRender(1);this._useDeterministicSort&&this._visibleGaussianTiles.sort((e,r)=>e.obb.centerX-r.obb.centerX||e.obb.centerY-r.obb.centerY||e.obb.centerZ-r.obb.centerZ);let e=this._visibleGaussianTiles.reduce((e,r)=>e+r.gaussianAtlasIndices.length,0);this._ensureBufferCapacity(e),this._textureAtlas.ensureTextureAtlas();const{frustum:r}=this._renderer.camera;t(this._cameraDirectionNormalized,this._renderer.camera.ray.direction);const s=this._cameraDirectionNormalized[0],n=this._cameraDirectionNormalized[1],a=this._cameraDirectionNormalized[2];let o=0;if(this._visibleGaussianTiles.forEach(t=>{const{gaussianAtlasIndices:u,positions:h}=t;if(this._minimumBoundingSphere.center=t.obb.center,this._minimumBoundingSphere.radius=t.obb.radius+t.maxScale,i(r,this._minimumBoundingSphere))for(let e=0;e<u.length;e++){this._atlasIndicesBuffer[o]=u[e];const r=3*e,t=h[r],i=h[r+1],d=h[r+2];this._distancesBuffer[o]=t*s+i*n+d*a,this._sortOrderBuffer[o]=o,o++}else e-=u.length}),0===e)return this.visibleGaussians=0,this._clearBuffersAndTextures(),void this._renderer.requestRender(1);const u={distances:this._distancesBuffer,sortOrderIndices:this._sortOrderBuffer,numGaussians:e,preciseSort:this._useDeterministicSort};await(this._workerHandle?.sort(u).then(r=>{this._distancesBuffer=r.distances,this._sortOrderBuffer=r.sortedOrderIndices;const t=this._sortedAtlasIndicesBuffer.subarray(0,e);for(let i=0;i<e;i++)t[i]=this._atlasIndicesBuffer[r.sortedOrderIndices[i]];this._orderTexture.setData(t,e);const s=this._renderer.view.qualitySettings.gaussianSplat.maxAllowedVisibleGaussians;this.visibleGaussians=Math.min(e,s),this._renderer.requestRender(1)}))}set useDeterministicSort(e){this._useDeterministicSort=e}}export{l as GaussianSplatDataStore};
