@doegis/core
Version:
DOE GIS API
3 lines (1 loc) • 9.61 kB
JavaScript
import has from"../../../../../core/has.js";import e from"../../../../../core/Logger.js";import{isNone as t,isSome as o,unwrap as r,applySome as n}from"../../../../../core/maybe.js";import i from"../../../../../core/PooledArray.js";import{e as s,t as a}from"../../../../../chunks/mat3.js";import{c}from"../../../../../chunks/mat3f32.js";import{d as m,w as l,t as f}from"../../../../../chunks/vec3.js";import{a as p,c as h}from"../../../../../chunks/vec3f64.js";import{a as b}from"../../../../../chunks/vec32.js";import{c as u}from"../../../../../chunks/vec33.js";import{ViewingMode as g}from"../../../../ViewingMode.js";import{ColorMixModeEnum as d,encodeSymbolColor as y}from"../../../layers/support/symbolColorUtils.js";import{clone as j,computeOffsetObb as C,radius as v}from"../../../support/orientedBoundingBox.js";import{glLayout as _}from"../../../support/buffer/glUtil.js";import{newLayout as w}from"../../../support/buffer/InterleavedLayout.js";import O from"./ComponentData.js";import{State as M,ComponentObject as x}from"./ComponentObject.js";import A from"./IntersectionGeometry.js";import{Renderable as D}from"./Renderable.js";import{RenderGeometry as S}from"./RenderGeometry.js";import{RenderSubmitSystem as I}from"./RenderSubmitSystem.js";import{createVertexBufferLayout as P}from"./SourceGeometry.js";import{UniformComponentParameters as E}from"./UniformComponentParameters.js";import{ComponentParametersVarying as R,ComponentParametersUniform as U,ComponentParameterSummary as T,ComponentMaterial as B}from"./Material/ComponentMaterial.js";import{attributeLocations as L}from"./Material/ComponentTechnique.js";import{encodeElevationOffset as V}from"./Material/shader/ComponentData.glsl.js";import{getVisibility as k,updateVisibilityWithCount as G}from"../../lib/ComponentUtils.js";import{assert as N}from"../../lib/Util.js";import{VertexAttribute as q}from"../../lib/VertexAttribute.js";import{getVerticalOffsetI3S as H}from"../../lib/verticalOffsetUtils.js";import{EdgeInputBufferLayout as z}from"../../lib/edgeRendering/bufferLayouts.js";import{extractComponentsEdgeLocationsLayout as W}from"../../lib/edgeRendering/edgeProcessing.js";import{BufferManager as X}from"../../lib/TextureBackedBuffer/BufferManager.js";import{BufferObject as Y}from"../../../../webgl/BufferObject.js";import{Usage as F,PrimitiveType as J}from"../../../../webgl/enums.js";import{VertexArrayObject as K}from"../../../../webgl/VertexArrayObject.js";const Q=e.getLogger("esri.views.3d.webgl-engine.collections.Component.ComponentObjectCollection");class Z{constructor(e,t){this._renderManager=e,this._viewingMode=t,this._objects=[new i,new i],this._renderSubmit=new I(this),this._renderManager.register(this._renderSubmit),this._hasObjectAndLayerId=has("enable-feature:objectAndLayerId-rendering"),this._componentBufferManager=new X(e.rctx,2+(this._hasObjectAndLayerId?1:0))}destroy(){N(0===this._objects[M.Hidden].length&&0===this._objects[M.Visible].length,"ObjectCollection should be empty upon disposal"),this._componentBufferManager.destroy()}createObject(e){const t=new x;return t.toMapSpace=e.toMapSpace,t.transform=e.transform,t.obb=j(e.obb),t.components=new O(this._componentBufferManager,e.geometry.componentOffsets),t.renderable=this._createRenderable(e,t.components),t.intersectionGeometry=new A(e.geometry.positionData,t.components),this._objects[t.visible].push(t),t}destroyObject(e){const t=e;this._objects[t.visible].removeUnordered(t),t.destroy(),this._notifyDirty()}setObjectVisibility(e,t){const o=e;t!==o.visible&&(this._objects[o.visible].removeUnordered(o),this._objects[t].push(o),o.visible=t,this._notifyDirty())}preSubmit(e){const t=e.camera.eye;this.visibleObjects.forAll((e=>e.renderable.meta.cameraDepthSquared=m(t,e.obb.center)))}getMaterial(e){return e.renderable.material}updateMaterial(e,t){const o=e.renderable.material;t(o),o.dirty&&this._notifyDirty()}setAllComponentVisibilities(e,t){const o=e;o.components.visibility.reset(t),o.components.visibilityDirty(),this._notifyDirty()}forEachVisibleComponent(e,t){return e.components.visibility.forEachComponent(t)}getComponentCount(e){const t=e,o=t.components.visibility.componentCount();return{visible:o,invisible:t.components.count-o}}setComponentData(e,r){const n=e,i=n.renderable.material,s=n.components,a=s.materialDataBuffer,c=s.materialDataIndices,m=new E,l=a.textureBuffer,f=new Uint8Array(4),p=new Uint32Array(f.buffer);let h=0,b=0,u=0,g=s.verticalOffsets,v=1/0,_=-1/0,w=!1,O=!1,M=0;for(let j=0;j<s.count;j++){r(j,m),h+=+(m.externalColor[3]<1),b+=+(m.externalColorMixMode===d.Replace&&1===m.externalColor[3]),u+=+m.castShadows,y(m.externalColor,m.externalColorMixMode,f),f[2]=254&f[2]|+m.castShadows,l.setData(c[j],0,f[0],f[1],f[2],f[3]),w||(w=j>0&&M!==p[0]),M=p[0],O||(O=0!==m.elevationOffset),O&&t(g)&&(g=new Array(j).fill(0)),o(g)&&(g[j]=m.elevationOffset),v=Math.min(v,m.elevationOffset),_=Math.max(_,m.elevationOffset),V(m.elevationOffset,f),l.setData(c[j],1,f[0],f[1],f[2],f[3]);const e=m.objectAndLayerIdColor;o(e)&&l.setData(c[j],2,e[0],e[1],e[2],e[3]),m.pickable!==k(s.pickability,j)&&(s.pickability=G(s.pickability,s.count,j,m.pickable))}s.verticalOffsets=O?g:null,n.offsetObb=O?C(n.obb,v,_,this._viewingMode,o(n.offsetObb)?n.offsetObb:j(n.obb)):null,w||O||this._hasObjectAndLayerId?(i.componentParameters=new R,i.componentParameters.castShadows=ee(u,s.count),i.componentParameters.transparent=ee(h,s.count),i.componentParameters.opaqueOverride=ee(b,s.count),i.componentParameters.texture=l,l.updateTexture()):(i.componentParameters=new U,i.componentParameters.castShadows=m.castShadows?T.All:T.None,i.componentParameters.externalColor=m.externalColor,i.componentParameters.externalColorMixMode=m.externalColorMixMode),this._notifyDirty()}getComponentAabb(e,o,n,i=!1){e.intersectionGeometry.getComponentAabb(o,n);const s=e,a=s.components.verticalOffsets;if(i||t(a))return n;const c=a[o];if(this._viewingMode===g.Local||0===c)return n[2]+=c,n[5]+=c,n;const m=r(H(c));return m.localOrigin=s.transform.position,m.applyToAabb(n)}getComponentObb(e){return e.obb}getObjectTransform(e){return e.transform}getComponentPositions(e,t,o){return e.intersectionGeometry.getComponentPositions(t,o)}intersect(e,t,r,n,i,c){const m=e;o(i)&&(i.localOrigin=m.transform.position);const p=s(te,m.transform.rotationScale);l(oe,t,m.transform.position),l(re,r,m.transform.position),f(oe,oe,p),f(re,re,p);const h=a(te,p);return m.intersectionGeometry.intersect(oe,re,n,h,i,m.components.verticalOffsets,c)}addEdges(e,t,o,r){const n=e,{indices:i,positions:s}=n.intersectionGeometry,a=n.components.offsets;return t.addComponentObject(e,n.transform,{center:n.obb.center,radius:v(n.obb)},s,i,a,o,r)}async extractEdgeInformation(e,t,o){const r=e,n=r.components.visibility;if(n.allInvisible())return{buffer:W.createBuffer(0),origin:[0,0,0]};const{indices:i,positions:s}=r.intersectionGeometry,a=r.components.offsets,c=z.createBuffer(s.count);u(c.position,s),b(c.position,c.position,r.transform.rotationScale),this._setComponentIndices(c.componentIndex,i,a);const m=c.count,l=this._computeVisibilityIndices(i,n,a,m);return{origin:p(r.transform.position),buffer:await t.extractComponentsEdgeLocations({indices:l,indicesLength:l.length,skipDeduplicate:!0,data:c,writerSettings:{reducedPrecision:!1,variants:0}},o)}}_setComponentIndices(e,t,o){let r=0;for(let n=0;n<o.length-1;n++){const i=o[n],s=o[n+1];for(let o=i;o<s;o++){const n=t?t[o]:o;e.set(n,r)}r++}}_computeVisibilityIndices(e,t,o,r){if(e&&t.allVisible())return e;let n=0;t.forEachComponentRange(((e,t)=>(n+=o[t]-o[e],!0)));const i=Array.isArray(e)?new Array(n):2===e?.BYTES_PER_ELEMENT||r<=65536?new Uint16Array(n):new Uint32Array(n);let s=0;return t.forEachComponentRange(((t,r)=>{const n=o[t],a=o[r];for(let o=n;o<a;o++)i[s++]=e?e[o]:o;return!0})),i}addComponentHighlight(e,o){const r=e.components;t(r.highlightCounts)&&(r.highlightCounts=new Uint32Array(r.count+1));0===r.highlightCounts[o]++&&(r.highlightsDirty(),this._notifyDirty()),r.highlightCounts[r.count]++}removeComponentHighlight(e,o){const r=e.components;if(t(r.highlightCounts))return void Q.warn("Removing non-existing highlight.");const n=r.highlightCounts[o],i=r.highlightCounts[r.count];if(0!==n){if(n>1)return r.highlightCounts[o]=n-1,void(r.highlightCounts[r.count]=i-1);r.highlightCounts[o]=0,r.highlightsDirty(),this._notifyDirty(),1===i?r.highlightCounts=null:r.highlightCounts[r.count]=i-1}else Q.warn("Removing non-existing highlight.")}clearHighlights(e){const t=e.components;o(t.highlightCounts)&&(t.highlightCounts=null,t.highlightsDirty(),this._notifyDirty())}getObjectGPUMemoryUsage(e){return e.renderable.meta.gpuMemoryEstimate}get visibleObjects(){return this._objects[M.Visible]}_createRenderable(e,t){const i=this._renderManager.rctx,s=e.geometry,a=s.vertices.layoutParameters,c=Y.createVertex(i,F.STATIC_DRAW,s.vertices.data),m=n(s.indices,(e=>Y.createIndex(i,F.STATIC_DRAW,e))),l=_(P(a)),f=new Uint16Array(s.vertices.count);for(let r=0;r<t.count;r++){const e=t.offsets[r],n=t.offsets[r+1],i=t.materialDataIndices[r];if(o(s.indices))for(let t=e;t<n;t++){f[s.indices[t]]=i}else for(let t=e;t<n;t++)f[t]=i}const p=Y.createVertex(i,F.STATIC_DRAW,f.buffer),h=new B(e.transform,e.toMapSpace),b=new K(i,L,{data:l,componentIndices:$},{data:c,componentIndices:p},r(m)),u=new S(b,J.TRIANGLES,a,o(m)),g={cameraDepthSquared:.5,gpuMemoryEstimate:c.byteSize+p.byteSize+(o(m)?m.byteSize:0)};return new D(h,u,g)}_notifyDirty(){this._renderManager.notifyDirty()}}const $=_(w().u16(q.COMPONENTINDEX));function ee(e,t){return e===t?T.All:0===e?T.None:T.Some}const te=c(),oe=h(),re=h();export{Z as ComponentObjectCollection};