@doegis/core
Version:
DOE GIS API
3 lines (1 loc) • 8.64 kB
JavaScript
import{unpackFloatRGBA as e}from"../../../../core/floatRGBA.js";import{isSome as t,isNone as r}from"../../../../core/maybe.js";import i from"../../../../core/PooledArray.js";import{m as n,c as s}from"../../../../chunks/mat4.js";import{c as a}from"../../../../chunks/mat4f64.js";import{m as o}from"../../../../chunks/vec3.js";import{l as h}from"../../../../chunks/vec4.js";import{c as f}from"../../../../chunks/vec4f64.js";import{intersectsSphere as c,create as _,copy as l}from"../../../../geometry/support/frustum.js";import{c as u}from"../../../../chunks/sphere.js";import{maxScale as d}from"../../support/mathUtils.js";import{empty as m,union as g,set as p,DepthRange as b}from"./depthRange.js";import w from"./Octree.js";import{assert as v}from"./Util.js";const j=1e4,R=100,C=500,A=500,B=.1;function M(t,r,i){return e(r,t)*(i[1]-i[0])+i[0]}function O(e,t,r){let i=0;if(!t.some((e=>(i+=e.numGeometries,i>=j))))return G.compute(e,t);const n=m();return r.forAll((t=>{t.visible&&g(n,T(e,t))})),n}function T(e,r){if(!r.visible)return;const i=m(),n=r.getSpatialQueryAccelerator();return t(n)?D(i,e,n):F(i,e,r.objects),i}function D(e,t,r){const i=t.eye,n=t.viewForward,s=t.frustum,a=e=>e.visible,o=r.objectCount;if(o<C)p(K,t.near,Math.min(e.near,t.far)),r.forEachInDepthRange(i,n,w.DepthOrder.FRONT_TO_BACK,K,((r,i)=>{x(e,t,r),K.far=e.near,i.setRange(K)}),s,a),p(K,Math.max(e.far,t.near),t.far),r.forEachInDepthRange(i,n,w.DepthOrder.BACK_TO_FRONT,K,((r,i)=>{x(e,t,r),K.near=e.far,i.setRange(K)}),s,a);else{const i=Math.max(Math.min(o,A),Math.ceil(o*B)),h=r.findClosest(n,w.DepthOrder.FRONT_TO_BACK,s,a,i),f=r.findClosest(n,w.DepthOrder.BACK_TO_FRONT,s,a,i);h&&f&&(y(e,t,h.boundingVolumeWorldSpace.bounds),y(e,t,f.boundingVolumeWorldSpace.bounds))}}function F(e,t,r){V.clear(),r.forAll((e=>{e.visible&&0!==e.geometries.length&&V.add(e)})),V.empty||(V.sort(t),p(K,t.near,Math.min(e.near,t.far)),V.forEachInDepthRange(K,w.DepthOrder.FRONT_TO_BACK,((r,i)=>{i<e.near&&x(e,t,r)})),p(K,Math.max(e.far,t.near),t.far),V.forEachInDepthRange(K,w.DepthOrder.BACK_TO_FRONT,((t,r,i)=>{e.far=Math.max(e.far,i)})))}function x(e,t,r){if(!r.visible)return;if(!c(t.frustum,r.boundingVolumeWorldSpace.bounds))return;const i=r.transformation,s=E;r.geometries.forEach((r=>{n(s,i,r.shaderTransformation);const a=d(s);I(e,t,r.boundingInfo,s,a)}))}function I(e,t,i,n,s){if(r(i))return;o(k,i.center,n);const{eye:a,viewForward:h}=t,f=h[0]*(k[0]-a[0])+h[1]*(k[1]-a[1])+h[2]*(k[2]-a[2]);if(k[3]=i.radius*s,!(f-k[3]>e.near&&f+k[3]<e.far)&&c(t.frustum,k))if(i.radius>R&&i.getChildren())for(const r of i.getChildren())I(e,t,r,n,s);else U.unionDepthRangeWithAABB(e,t.viewProjectionMatrix,n,i.bbMin,i.bbMax)}function y(e,t,r){const i=t.eye,n=t.viewForward,s=(r[0]-i[0])*n[0]+(r[1]-i[1])*n[1]+(r[2]-i[2])*n[2];e.near=Math.min(e.near,s-r[3]),e.far=Math.max(e.far,s+r[3])}class P{constructor(){this._items=new i({allocator:e=>e||{obj:null,distance:0,near:0,far:0},deallocator:e=>(e.obj=null,e.distance=0,e.near=0,e.far=0,e)})}get length(){return this._items.length}get empty(){return 0===this._items.length}clear(){this._items.clear()}add(e){this._items.pushNew().obj=e}sort(e){const t=e.eye,r=e.viewForward;this._items.forAll((e=>{const i=e.obj.boundingVolumeWorldSpace.bounds,n=(i[0]-t[0])*r[0]+(i[1]-t[1])*r[1]+(i[2]-t[2])*r[2];e.distance=n,e.near=n-i[3],e.far=n+i[3]})),this._items.sort(((e,t)=>e.distance-t.distance))}forEachInDepthRange(e,t,r){if(t===w.DepthOrder.FRONT_TO_BACK)for(let i=0;i<this._items.length;++i){const t=this._items.data[i];t.far<e.near||t.near>e.far||r(t.obj,t.near,t.far)}else for(let i=this._items.length-1;i>=0;--i){const t=this._items.data[i];t.far<e.near||t.near>e.far||r(t.obj,t.near,t.far)}}}class N{constructor(){this._view=a(),this._viewProj=a(),this._frustum=_(),this._geometries=new Array,this._near=[],this._far=[],this._nearCandidates=[],this._farCandidates=[],this._looseRange={near:0,far:0}}compute(e,t){this._reset(),s(this._view,e.viewMatrix),n(this._viewProj,e.projectionMatrix,this._view),l(this._frustum,e.frustum);const r=this._view,i=r[2],a=r[6],o=r[10],h=r[14];t.forAll((e=>e.forEachGeometry((e=>{if(!e.visible||!e.castShadow)return;let t;e.hasShaderTransformation?(e.computeBoundingSphere(e.shaderTransformation,k,1),t=k):t=e.boundingSphere;const r=i*t[0]+a*t[1]+o*t[2]+h,n=r-t[3],s=r+t[3];this._geometries.push(e),this._near.push(-s),this._far.push(-n)}))));const f=new b;if(0===this._geometries.length)return f;for(let n=0;n<this._geometries.length;++n)this._near[n]>f.far&&(f.far=this._near[n]),this._near[n]>2&&this._far[n]<f.near&&(f.near=this._far[n]);const c=this._looseRange;c.near=Math.max(.5*f.near,2),c.far=2*f.far;let _=0,u=0;for(let n=0;n<this._geometries.length;++n)this._near[n]<f.near&&(this._near[n]>=c.near?f.near=this._near[n]:this._nearCandidates[_++]=n),this._far[n]>f.far&&(this._far[n]<=c.far?f.far=this._far[n]:this._farCandidates[u++]=n);if(0===this._nearCandidates.length&&0===this._farCandidates.length)return f;this._nearCandidates.sort(((e,t)=>this._near[e]<this._near[t]?-1:this._near[e]>this._near[t]?1:0)),this._farCandidates.sort(((e,t)=>this._far[e]<this._far[t]?1:this._far[e]>this._far[t]?-1:0));for(let n=0;n<this._nearCandidates.length;++n){const e=this._nearCandidates[n];if(this._near[e]<f.near){const t=this._geometries[e],r=t.boundingInfo;this._includeNearBoundingInfoRec(r,t.shaderTransformation,f)}}for(let n=0;n<this._farCandidates.length;++n){const e=this._farCandidates[n];if(this._far[e]>f.far){const t=this._geometries[e],r=t.boundingInfo;this._includeFarBoundingInfoRec(r,t.shaderTransformation,f)}}return this._reset(),f}_reset(){this._geometries.length=0,this._near.length=0,this._far.length=0,this._nearCandidates.length=0,this._farCandidates.length=0}_includeNearBoundingInfoRec(e,t,i){if(r(e))return;const n=e.center;o(k,n,t);const s=d(t),a=k[0],h=k[1],f=k[2],c=e.radius*s,_=this._frustum;if(_[0][0]*a+_[0][1]*h+_[0][2]*f+_[0][3]>c||_[1][0]*a+_[1][1]*h+_[1][2]*f+_[1][3]>c||_[2][0]*a+_[2][1]*h+_[2][2]*f+_[2][3]>c||_[3][0]*a+_[3][1]*h+_[3][2]*f+_[3][3]>c)return;const l=this._view[2]*a+this._view[6]*h+this._view[10]*f+this._view[14],u=l+c;if(!(-(l-c)<2||-u>=i.near))if(-u>this._looseRange.near)i.near=-u;else{if(c>R){const r=e.getChildren();if(void 0!==r){for(const e of r)this._includeNearBoundingInfoRec(e,t,i);return}}U.unionDepthRangeWithAABB(i,this._viewProj,t,e.bbMin,e.bbMax)}}_includeFarBoundingInfoRec(e,t,i){if(r(e))return;let n=e.radius;const s=e.center;o(k,s,t);const a=d(t),h=k[0],f=k[1],c=k[2];n*=a;const _=this._frustum;if(_[0][0]*h+_[0][1]*f+_[0][2]*c+_[0][3]>n||_[1][0]*h+_[1][1]*f+_[1][2]*c+_[1][3]>n||_[2][0]*h+_[2][1]*f+_[2][2]*c+_[2][3]>n||_[3][0]*h+_[3][1]*f+_[3][2]*c+_[3][3]>n)return;const l=this._view[2]*h+this._view[6]*f+this._view[10]*c+this._view[14]-n;if(!(-l<=i.far))if(-l<this._looseRange.far)i.far=-l;else{if(n>R){const r=e.getChildren();if(void 0!==r){for(const e of r)this._includeFarBoundingInfoRec(e,t,i);return}}U.unionDepthRangeWithAABB(i,this._viewProj,t,e.bbMin,e.bbMax)}}}class S{constructor(){this._modelViewProj=a(),this._clipPosition=[f(),f(),f(),f(),f(),f(),f(),f()]}unionDepthRangeWithAABB(e,t,r,i,s){const a=this._modelViewProj;n(a,t,r);let o=!1;for(let n=0;n<8;++n){const e=this._clipPosition[n],t=0===n||3===n||4===n||7===n?i[0]:s[0],r=0===n||1===n||4===n||5===n?i[1]:s[1],o=n<4?i[2]:s[2];e[0]=a[0]*t+a[4]*r+a[8]*o+a[12],e[1]=a[1]*t+a[5]*r+a[9]*o+a[13],e[2]=a[2]*t+a[6]*r+a[10]*o+a[14],e[3]=a[3]*t+a[7]*r+a[11]*o+a[15]}for(let n=0;n<12;++n){const t=this._clipPosition[W[n][0]],r=this._clipPosition[W[n][1]],i=this._clipPosition[W[n][2]],s=this._clipTriangle(t,r,i);let a=!0;for(let e=0;e<s.length;++e){if(s[e][3]>=2){a=!1;break}}if(!a){o=!0;for(let t=0;t<s.length;++t){const r=s[t][3];Number.isFinite(r)&&(e.near=Math.min(r,e.near),e.far=Math.max(r,e.far))}}}return o}_inside(e,t){return 0===t?e[0]>=-e[3]:1===t?e[1]>=-e[3]:2===t?e[0]<=e[3]:3===t?e[1]<=e[3]:void v(!1)}_intersect(e,t,r){let i=0;return 0===r?i=(-e[3]-e[0])/(t[0]-e[0]+t[3]-e[3]):1===r?i=(-e[3]-e[1])/(t[1]-e[1]+t[3]-e[3]):2===r?i=(e[3]-e[0])/(t[0]-e[0]-t[3]+e[3]):3===r&&(i=(e[3]-e[1])/(t[1]-e[1]-t[3]+e[3])),h(f(),e,t,i)}_clipTriangle(e,t,r){let i=[e,t,r];for(let n=0;n<4;++n){const e=i;i=[];for(let t=0;t<e.length;++t){const r=e[t],s=e[(t+1)%e.length];this._inside(s,n)?(this._inside(r,n)||i.push(this._intersect(r,s,n)),i.push(s)):this._inside(r,n)&&i.push(this._intersect(r,s,n))}}return i}}const W=[[0,1,3],[2,3,1],[1,5,2],[6,2,5],[5,4,6],[7,6,4],[4,0,7],[3,7,0],[3,2,7],[6,7,2],[4,5,0],[1,0,5]],k=u(),E=a(),K=m(),V=new P,G=new N,U=new S;export{N as DepthRangeFromRenderGeometries,T as depthRangeFromLayer,O as depthRangeFromScene,M as textureToDepth};