UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

6 lines (5 loc) • 17.2 kB
/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.33/esri/copyright.txt for details. */ import{_ as e}from"../../../../../chunks/tslib.es6.js";import t from"../../../../../core/Accessor.js";import{equals as r,binaryIndexOf as s}from"../../../../../core/arrayUtils.js";import"../../../../../core/has.js";import n from"../../../../../core/Logger.js";import{clamp as i}from"../../../../../core/mathUtils.js";import{disposeMaybe as o,destroyMaybe as a}from"../../../../../core/maybe.js";import{isAbortError as c,onAbortOrThrow as l}from"../../../../../core/promiseUtils.js";import{property as d}from"../../../../../core/accessorSupport/decorators/property.js";import{subclass as h}from"../../../../../core/accessorSupport/decorators/subclass.js";import{fromMat4 as u,transpose as m,invert as g}from"../../../../../core/libs/gl-matrix-2/math/mat3.js";import{create as f}from"../../../../../core/libs/gl-matrix-2/factories/mat3f64.js";import{create as p}from"../../../../../core/libs/gl-matrix-2/factories/mat4f64.js";import{i as _,c as b,a as y,e as j}from"../../../../../chunks/vec32.js";import{create as O,clone as w}from"../../../../../core/libs/gl-matrix-2/factories/vec3f64.js";import{UpdatingHandles as E}from"../../../../../core/support/UpdatingHandles.js";import{a as v,g as x}from"../../../../../chunks/sphere.js";import{c as M}from"../../../../../chunks/vec33.js";import{ViewingMode as R}from"../../../../ViewingMode.js";import{encodeElevationOffset as T}from"../../collections/Component/Material/shader/ComponentData.glsl.js";import{TwoVectorPosition as A}from"../../core/util/TwoVectorPosition.js";import{Attribute as C}from"../Attribute.js";import{GridLocalOriginFactory as D}from"../GridLocalOriginFactory.js";import{applyToModelMatrix as P}from"../localOriginHelper.js";import{LocalOriginManager as U}from"../LocalOriginManager.js";import{Object3D as L}from"../Object3D.js";import{VertexArrayObject as k}from"../VertexArrayObject.js";import{VertexAttribute as I}from"../VertexAttribute.js";import{VertexLayout as S,EdgeInputBufferLayout as B,vertexAttributeLocations as V,glVertexLayout as q}from"./bufferLayouts.js";import{RegularEdgeBufferWriter as H,SilhouetteEdgeBufferWriter as G}from"./edgeBufferWriters.js";import{EdgeRenderer as N,lineWidthFractionFactor as W,extensionLengthOffset as z}from"./EdgeRenderer.js";import{EdgePassParameters as F}from"./EdgeShaderParameters.js";import{EdgeWorkerHandle as K}from"./EdgeWorkerHandle.js";import"./interfaces.js";import{generateStrokesTexture as J}from"./strokes.js";import{determineRendererType as Q,determineEdgeTransparency as X,determineObjectTransparency as Y,fillComponentBufferIndices as Z}from"./util.js";import{BufferManager as $}from"../TextureBackedBuffer/BufferManager.js";import{EdgeSilhouette as ee}from"../../shaders/sources/edgeRenderer/EdgeUtil.glsl.js";import{BufferObject as te}from"../../../../webgl/BufferObject.js";import{Usage as re}from"../../../../webgl/enums.js";const se=128;let ne=class extends t{constructor(e){super(e),this._updatingHandles=new E,this._objectEntries=new Map,this._pendingDeletions=new Map,this._renderers=new Map,this._gpuMemoryUsage=0,this._workerAbort=new AbortController,this._tmpModelPosition=O(),this._localOrigins=new U(new D(e.renderSR));const t=S.createBuffer(4);for(let r=0;r<4;r++)t.sideness.set(r,0,0===r||3===r?0:1),t.sideness.set(r,1,0===r||1===r?0:1);this._verticesBufferObject=te.createVertex(e.rctx,re.STATIC_DRAW,t.buffer)}initialize(){this._worker=new K(this.schedule),this._componentColorManager=new $(this.rctx,3)}destroy(){this.destroyed||(this._objectEntries.forEach((e=>this._discardObjectEntry(e))),this._objectEntries.clear(),this._pendingDeletions.forEach((e=>this._discardObjectEntry(e))),this._pendingDeletions.clear(),this._strokesTexture=o(this._strokesTexture),this._componentColorManager=a(this._componentColorManager),this._workerAbort.abort(),this._worker.destroy(),this._verticesBufferObject.dispose(),this._renderers.clear(),this._updatingHandles.destroy(),this._set("schedule",we))}get updating(){return this._updatingHandles.updating}get usedMemory(){return this._gpuMemoryUsage}shouldRender(){return this._renderers.size>0}async addComponentObject(e,t,r,s,n,i,o){if(this.hasObject(e))return this._getObjectMemoryUsage(e);let a;const c=new ae(null,new Promise((e=>a=e)),e.obb.center,e.obb.radius);this._objectEntries.set(e,c);const l=await this._updatingHandles.addPromise(this._addComponentGeometry(e.transform,c,t,r,s,n,i,o));return this.setNeedsRender(),a(),l}async addOrUpdateObject3D(e,t,r,s){if(this.destroyed)return void n.getLogger(this).warn("Attempt to add an object to a destroyed instance");const i=new AbortController;let o;const a=e.boundingVolumeWorldSpace.bounds,l=new ae(i,new Promise((e=>o=e)),v(a),x(a)),d=this._objectEntries.get(e);d&&(this._pendingDeletions.has(e)?this._discardObjectEntry(d):this._pendingDeletions.set(e,d)),this._objectEntries.set(e,l);try{const n=new Array;if(e.geometries.length>1&&oe(e))n.push(this._addObjectMergedGeometries(e,l,t,r,s));else for(const i of e.geometries)i.material.supportsEdges&&n.push(this._addGeometry(e,l,i,t,r,s));await this._updatingHandles.addPromise(Promise.all(n)),this._removePendingDeletion(e)}catch(h){c(h)?this._discardObjectEntry(l):this._removePendingDeletion(e)}finally{this.setNeedsRender(),o()}}removeObject(e){const t=this._objectEntries.get(e);this._objectEntries.delete(e),this._discardObjectEntry(t),this._removePendingDeletion(e)}_removePendingDeletion(e){const t=this._pendingDeletions.get(e);this._pendingDeletions.delete(e),this._discardObjectEntry(t)}async _getObjectEntry(e){const t=this._objectEntries.get(e);if(!t)throw new Error("no object");return await t.loaded,null==t.loaded?null:t}fastUpdateObject3DEdgesTransform(e){if(this.destroyed)return!1;const t=this._objectEntries.get(e);if(!t)return!1;const{geometries:r}=e,{renderables:s}=t;if(0===r.length||0===s.length)return!0;if(s.length>1)return!1;const[n]=s,i=n.transform;if(!(i instanceof de))return!1;const[o]=r;if(o.localOrigin!==i.origin.origin)return!1;const a=p(),c=this._computeModelTransformWithLocalOrigin(e,o,a);return n.transform=new de(a,c),this.setNeedsRender(),!0}_discardObjectEntry(e){e&&(e.abort?.abort(),e.renderables.length&&(e.renderables.forEach((e=>this._removeRenderable(e))),this.setNeedsRender()),e.loaded=null)}hasObject(e){return this._objectEntries.has(e)}async updateAllComponentOpacities(e,t){const r=await this._updatingHandles.addPromise(this._getObjectEntry(e));if(null==r)return;const s=Array.isArray(t)?e=>t[e]:()=>t;r.renderables.forEach((e=>{const t=e.components.meta.length;for(let r=0;r<t;r++){const t=s(r),n=e.components.meta[r],i=n.index;n.material.opacity=t,e.components.buffer.textureBuffer.setDataElement(i,1,3,255*t)}this._updateTransparency(e)})),this.setNeedsRender()}async _getObjectMemoryUsage(e){const t=await this._getObjectEntry(e);return t?t.renderables.reduce(((e,t)=>e+t.statistics.gpuMemoryUsage),0):0}async updateAllComponentMaterials(e,t,r,s){const n=e instanceof L,i=Q(t),o=N.getKey(i,r,n),a=await this._updatingHandles.addPromise(this._getObjectEntry(e));null!=a&&(a.renderables.forEach((e=>{if(o!==e.rendererKey){const t=this._renderers.get(e.rendererKey),s=this._acquireRenderer(i,r,n);t.removeRenderable(e),--t.refCount,e.rendererKey=o,s.addRenderable(e)}if(Array.isArray(t))for(let r=0;r<t.length;r++)e.components.meta[r].material=t[r];else e.components.meta[0].material=t;s&&me(e.components),this._updateTransparency(e)})),this.setNeedsRender())}async updateAllVerticalOffsets(e,t){const r=await this._updatingHandles.addPromise(this._getObjectEntry(e));null!=r&&this._updateAllVerticalOffsets(r,t)}_updateAllVerticalOffsets(e,t){e.renderables.forEach((e=>{const r=e.components.meta;for(let s=0;s<r.length;s++)e.components.meta[s].verticalOffset=t?.[s]??0;me(e.components)})),this.setNeedsRender()}async updateObjectVisibility(e,t){const r=await this._updatingHandles.addPromise(this._getObjectEntry(e));r&&(r.renderables.forEach((e=>e.visible=t)),this.setNeedsRender())}render(e,t){if(null==this._componentColorManager)return;this._localOrigins.updateViewMatrices(e.camera.viewMatrix);const r=e.camera.viewInverseTransposeMatrix,s=O(),n=new A;let i=0,o=0;if(this._renderers.forEach((r=>{0!==r.refCount?(++this.techniques.precompiling,r.forEachRenderable((t=>{t.visible&&(i+=t.statistics.averageEdgeLength,o++,t.regular&&r.acquireTechnique(e,!1),t.silhouette&&r.acquireTechnique(e,!0))}),t),--this.techniques.precompiling):this._renderers.delete(r.key)})),this._componentColorManager.garbageCollect(),this._componentColorManager.updateTextures(),0===o)return;const a=new F(40*i/o,t);_(s,r[3],r[7],r[11]),n.set(s),b(a.transformWorldFromViewTH,n.high),b(a.transformWorldFromViewTL,n.low),u(a.transformViewFromCameraRelativeRS,e.camera.viewMatrix),m(Oe,a.transformViewFromCameraRelativeRS),g(a.transformNormalViewFromGlobal,Oe),a.transformProjFromView=e.camera.projectionMatrix,this._updateObjectCameraDistances(e),this._renderers.forEach((t=>{ge(t,e,a),fe(t,e,a)}))}_updateTransparency(e){const t=X(e.components.meta),r=Y(e.components.meta);t===e.edgeTransparency&&r===e.objectTransparency||(e.edgeTransparency=t,e.objectTransparency=r,this._renderers.get(e.rendererKey).setRenderablesDirty())}_computeModelTransformWithLocalOrigin(e,t,r){e.getCombinedShaderTransformation(t,r);const s=null!=t.localOrigin?this._localOrigins.register(t.localOrigin):this._localOrigins.acquire(_(this._tmpModelPosition,r[12],r[13],r[14]));return t.localOrigin=s.origin,P(s.origin.vec3,r),s}_createComponentBuffers(e){if(null==this._componentColorManager)return null;const t=new Array,r=this._componentColorManager.getBuffer(e.length);for(let n=0;n<e.length;n++){const s=e[n],i=r.acquireIndex();t.push({index:i,verticalOffset:0,material:s})}const s=new ce(r,t);return me(s),s}_extractEdges(e,t,r,s,n,i,o=i.length){return o<se&&(n=!0),this._worker.process({data:r,indices:i,indicesLength:o,writerSettings:t,skipDeduplicate:s},e,n)}_createRenderable(e,t,r,s,n){const i=t=>new le(new k(this.rctx,V,new Map([["vertices",q],["instances",t===ee.REGULAR?H.glLayout:G.glLayout]]),new Map([["vertices",this._verticesBufferObject],["instances",te.createVertex(this.rctx,re.STATIC_DRAW,t===ee.REGULAR?e.regular.instancesData.buffer:e.silhouette.instancesData.buffer)]])),t===ee.REGULAR?e.regular.lodInfo:e.silhouette.lodInfo),o=e.regular.lodInfo.lengths.length>0?i(ee.REGULAR):null,a=e.silhouette.lodInfo.lengths.length>0?i(ee.SILHOUETTE):null,c=(o?.vao.cachedMemory??0)+(a?.vao.cachedMemory??0);return new he(o,a,{gpuMemoryUsage:c,externalMemoryUsage:n,averageEdgeLength:e.averageEdgeLength},r,X(t.meta),Y(t.meta),t,s)}async _addGeometry(e,t,r,s,n,i){if(r.edgeIndicesLength<=0)return;const o=r.attributes.get(I.POSITION),a=p(),c=this._computeModelTransformWithLocalOrigin(e,r,a),l=new je(o,a,c);return this._addPositionData(t,l,r.edgeIndicesLength,s,n,i)}async _addPositionData(e,t,r,s,n,i=!1){if(null==e.loaded)return;const o=this._createComponentBuffers([s]);if(null==o)return;const a=this._acquireRenderer(s.type,n,!0),{modelTransform:c,origin:l}=t,d=t.position.indices,h=t.position,u=h.data.length/h.size,m=B.createBuffer(u);for(let p=0;p<u;p++)m.position.set(p,0,h.data[p*h.size]),m.position.set(p,1,h.data[p*h.size+1]),m.position.set(p,2,h.data[p*h.size+2]);Z(o.meta,[0,m.componentIndex.count],m.componentIndex);const g=await this._updatingHandles.addPromise(this._extractEdges(e.abort?.signal||this._workerAbort.signal,a.writerSettings,m,!1,i,d,r));if(null==e.loaded)return;const f=this._createRenderable(g,o,new de(c,l),a.key,!1);e.renderables.push(f),a.addRenderable(f),this._gpuMemoryUsage+=f.statistics.gpuMemoryUsage}async _addComponentGeometry(e,t,r,s,n,i,o,a){if(null==t.loaded)return 0;const c=this._createComponentBuffers(i);if(null==c)return 0;const l=Q(i),d=this._acquireRenderer(l,o||!1,!1),h=B.createBuffer(r.length/3);M(h.position.typedBuffer,r,h.position.typedBufferStride,3),Z(c.meta,n,h.componentIndex,s);const u=!0,m=d.writerSettings,g=await this._updatingHandles.addPromise(this._extractEdges(this._workerAbort.signal,m,h,u,!1,s));if(null==t.loaded)return 0;const f=this._createRenderable(g,c,e,d.key,!0);return t.renderables.push(f),d.addRenderable(f),this._updateAllVerticalOffsets(t,a),f.statistics.gpuMemoryUsage}async _addObjectMergedGeometries(e,t,r,s,n){const i=new Map;let o=0,a=0,c=null;const l=e.geometries.filter((e=>{if(e.edgeIndicesLength<=0||!e.material.supportsEdges)return!1;!c&&e.localOrigin&&(c=e);const t=e.attributes.get(I.POSITION);return a+=t.data.length/t.size,o+=e.edgeIndicesLength,!0}));if(0===l.length)return;const d=a>=65536?Uint32Array:Uint16Array,h=o?new d(o):null,u=[];let m=0;l.forEach((e=>{const t=e.attributes.get(I.POSITION),r=t.indices;let s=i.get(t.data);if(null==s){s=u.length/3;for(let e=0;e<t.data.length;e+=t.size)u.push(t.data[e]),u.push(t.data[e+1]),u.push(t.data[e+2]);i.set(t.data,s)}for(let n=0;n<e.edgeIndicesLength;n++)h[m++]=s+r[n]}));const g=c||e.geometries[0],f=p(),_=this._computeModelTransformWithLocalOrigin(e,g,f);for(let p=0;p<e.geometries.length;p++)e.geometries[p].localOrigin=_.origin;const b=new je(new C(u,h,3),f,_);await this._updatingHandles.addPromise(this._addPositionData(t,b,h.length,r,s,n))}_acquireRenderer(e,t,r){const s=N.getKey(e,t,r);let n=this._renderers.get(s);return null==this._strokesTexture&&(this._strokesTexture=J(this.rctx)),n||(n=new N(this.rctx,this.techniques,{type:e,hasSlicePlane:t,strokesTexture:this._strokesTexture,legacy:r,spherical:this.viewingMode===R.Global}),this._renderers.set(s,n)),++n.refCount,n}_removeRenderable(e){ie(e.regular),ie(e.silhouette);const t=this._renderers.get(e.rendererKey);if(t){t.removeRenderable(e),--t.refCount,this._localOrigins.release(e.transform.origin),this._gpuMemoryUsage-=e.statistics.externalMemoryUsage?0:e.statistics.gpuMemoryUsage;for(const t of e.components.meta)e.components.buffer.releaseIndex(t.index)}}_updateObjectCameraDistances(e){const t=e.camera.eye,r=e.camera.viewForward,s=O(),n=e=>{y(s,e.center,t);const n=j(s,r),i=e.radius,o=n<-i?1/0:n<i?0:n-i;e.renderables.forEach((e=>e.distanceToCamera=o))};this._objectEntries.forEach(n),this._pendingDeletions.forEach(n)}get test(){}};function ie(e){e?.vao&&(e.vao.vertexBuffers.get("instances")?.dispose(),e.vao.disposeVAOOnly(),e.vao=null)}function oe(e){let t=null,s=null;for(const n of e.geometries){if(n.material.supportsEdges){if(t){if(!r(t,n.transformation))return!1}else t=n.transformation;if(s||null==n.localOrigin){if(null!=s?.localOrigin&&null!=n.localOrigin&&s.localOrigin.id!==n.localOrigin.id)return!1}else s=n}}return!0}e([d({constructOnly:!0})],ne.prototype,"rctx",void 0),e([d({constructOnly:!0})],ne.prototype,"renderSR",void 0),e([d({constructOnly:!0})],ne.prototype,"viewingMode",void 0),e([d({constructOnly:!0})],ne.prototype,"techniques",void 0),e([d({constructOnly:!0})],ne.prototype,"setNeedsRender",void 0),e([d({constructOnly:!0})],ne.prototype,"schedule",void 0),e([d({readOnly:!0})],ne.prototype,"_updatingHandles",void 0),e([d({readOnly:!0})],ne.prototype,"updating",null),ne=e([h("esri.views.3d.webgl-engine.lib.edgeRendering.EdgeView")],ne);class ae{constructor(e,t,r,s){this.abort=e,this.radius=s,this.renderables=new Array;const n=e?l(e.signal,(()=>e.abort())):null;this.loaded=t,this.loaded.then((()=>{null!=this.loaded&&(this.loaded=!0),this.abort=null,n?.remove()})),this.center=w(r)}}class ce{constructor(e,t){this.buffer=e,this.meta=t}}class le{constructor(e,t){this.vao=e,this.lod=t}}class de{constructor(e,t){this.modelMatrix=e,this.origin=t}}class he{constructor(e,t,r,s,n,i,o,a){this.regular=e,this.silhouette=t,this.statistics=r,this.transform=s,this.edgeTransparency=n,this.objectTransparency=i,this.components=o,this.rendererKey=a,this.distanceToCamera=0,this.visible=!0}}class ue extends he{}function me(e){const{meta:t,buffer:r}=e,s=new Uint8Array(4);for(let n=0;n<t.length;n++){const e=t[n].material,o=t[n].index,a=i(Math.round(e.size*W),0,255),c=i(e.extensionLength,-128,255-z)+z,l=255*e.opacity,d=e.color,h=255*d[0],u=255*d[1],m=255*d[2],g=255*d[3];r.textureBuffer.setData(o,0,h,u,m,g),r.textureBuffer.setData(o,1,a,c,e.type,l),T(t[n].verticalOffset,s),r.textureBuffer.setData(o,2,s[0],s[1],s[2],s[3])}}function ge(e,t,r){let s,n;const i=r.transparency,o=t.camera.perScreenPixelRatio;e.forEachRenderable((i=>{if(!pe(i)||!i.visible)return;s??=e.acquireTechnique(t,!1),n??=e.rctx.bindTechnique(s,t,r);const a=ye(i.regular.lod.lengths,i.distanceToCamera,o);e.renderRegularEdges(n,i,r,t,a)}),i)}function fe(e,t,r){let s,n;const i=r.transparency,o=t.camera.perScreenPixelRatio;e.forEachRenderable((i=>{if(!be(i)||!i.visible)return;s??=e.acquireTechnique(t,!0),n??=e.rctx.bindTechnique(s,t,r);const a=ye(i.silhouette.lod.lengths,i.distanceToCamera,o);e.renderSilhouetteEdges(n,i,r,t,a)}),i)}function pe(e){return null!=e.regular}class _e extends he{}function be(e){return null!=e.silhouette}function ye(e,t,r){const n=t*r,i=s(e,n,!0);return-1===i?n<e[0]?e.length:0:e.length-i}class je{constructor(e,t,r){this.position=e,this.modelTransform=t,this.origin=r}}const Oe=f(),we=()=>Promise.reject();export{ne as EdgeView,de as LegacyTransform,ue as RegularRenderable,he as Renderable,_e as SilhouetteRenderable};