UNPKG

@doegis/core

Version:

DOE GIS API

3 lines (1 loc) 3.47 kB
import{isSome as e,destroyMaybe as t,unwrapOrThrow as r,isNone as s,applySome as i}from"../../../../../core/maybe.js";import{FeatureDisplayList as f}from"../FeatureDisplayList.js";import{Buffer as n}from"./Buffer.js";import{DisplayRecordReader as o}from"./DisplayRecordReader.js";import{VertexArrayObject as d}from"../../../../webgl/VertexArrayObject.js";const h=0,u=1;class c{constructor(e,t){this._vaos=new Map,this._indicesInvalid=!1,this.geometryType=e,this._stage=t}destroy(){for(const[t,r]of this._vaos)e(r)&&r.dispose(!1);this._indexBuffer=t(this._indexBuffer),this._vertexBuffer=t(this._vertexBuffer)}insert(e,t,s){if(!e.records.byteLength)return;const i=e.stride;if(this._vertexBuffer&&this._indexBuffer){const s=e.indices.byteLength/4,f=e.vertices.byteLength/i;this._indexBuffer.ensure(s),this._vertexBuffer.ensure(f);const{vertices:n,indices:d}=e,h=o.from(e.records),u=this._vertexBuffer.insert(n,0,n.byteLength/i,0),c=this._indexBuffer.insert(d,0,d.byteLength/4,u);if(h.forEach((e=>{e.indexFrom+=c,e.vertexFrom+=u})),r(this._records,"Expected records to be defined").link(h),t)this._indicesInvalid=!0;else if(this._displayList){const e=h.getCursor();for(;e.next();)this._displayList.addRecord(e)}}else{const r=e.indices.byteLength/4,s=e.vertices.byteLength/i,f=i/Uint32Array.BYTES_PER_ELEMENT,d=this._stage.bufferPool;this._records=o.from(e.records),this._indexBuffer=new n("index",r,1,d),this._vertexBuffer=new n("vertex",s,f,d),this._indexBuffer.insert(e.indices,0,e.indices.byteLength/4,0),this._vertexBuffer.insert(e.vertices,0,e.vertices.byteLength/i,0),t&&(this._indicesInvalid=!0)}}remove(e){if(!s(this._records))for(const t of e){const e=this._records.getCursor();if(!e.lookup(t))continue;const r=e.indexFrom,s=e.vertexFrom;let i=e.indexCount,f=e.vertexCount;for(;e.next()&&e.id===t;)i+=e.indexCount,f+=e.vertexCount;this._indexBuffer.free(r,i),this._vertexBuffer.free(s,f,!0),this._records.delete(t)}}getVAO(e,t,r,f){if(!this._vertexBuffer||!this._indexBuffer||s(this._records)||!this._vertexBuffer.bufferSize)return null;const n=f?u:h;let o=this._vaos.get(n);(this._vertexBuffer.invalidated||this._indexBuffer.invalidated||f&&this._indexBuffer.invalidatedComputeBuffer)&&(i(o,(e=>e.dispose(!1))),o=null),this._vertexBuffer.upload(),this._indexBuffer.upload();const c=this._indexBuffer.getGPUBuffer(e,1===n),_=this._vertexBuffer.getGPUBuffer(e);return o||(o=new d(e,r,t,{geometry:_},c),this._vaos.set(n,o)),o}forEachCommand(e){if(!s(this._records)){if(this._sortIndices(this._records),!this._displayList){const e=this._cursorIndexOrder;this._displayList=f.from(this,this.geometryType,this._records.getCursor(),e)}this._displayList.forEach(e)}}_sortIndices(e){const t=!!this._indexBuffer.bufferSize;if(!this._indicesInvalid)return;this._indicesInvalid=!1;let r=0;const s=e.getCursor(),i=[],f=[],n=[];for(;s.next();)f.push(s.index),n.push(s.sortKey),i.push(s.id);f.sort(((e,t)=>{const r=n[t],s=n[e];return s===r?i[t]-i[e]:r-s}));const o=e.getCursor(),d=t?this._indexBuffer.getCPUBuffer():this._vertexBuffer.getCPUBuffer();for(const h of f){if(!o.seekIndex(h))throw new Error("Expected to find index");if(t){const{indexFrom:e,indexCount:t}=o;o.indexFrom=r;for(let s=0;s<t;s++)this._indexBuffer.set(r++,d.array[e+s])}else{const{vertexFrom:e,vertexCount:t}=o,s=this._vertexBuffer.strideInt,i=e*s,f=i+t*s;o.vertexFrom=r/s;for(let n=i;n<f;n++)this._vertexBuffer.set(r++,d.array[n])}}this._cursorIndexOrder=f,this._displayList=null}}export{c as Geometry};