UNPKG

@three.ez/batched-mesh-extensions

Version:
3 lines (2 loc) 11.2 kB
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const A=require("bvh.js"),u=require("three"),ht=require("three/addons/utils/SortUtils.js");class G{constructor(e,t,o=0,n=!0){this.nodesMap=new Map,this._origin=new Float32Array(3),this._dir=new Float32Array(3),this._cameraPos=new Float32Array(3),this._boxArray=new Float32Array(6),this.target=e,this.accurateCulling=n,this._margin=o,this.bvh=new A.BVH(new A.HybridBuilder,t===2e3?A.WebGLCoordinateSystem:A.WebGPUCoordinateSystem)}create(){const e=this.target.instanceCount,t=this.target._instanceInfo.length,o=this.target._instanceInfo,n=new Array(e),r=new Uint32Array(e);let i=0;this.clear();for(let c=0;c<t;c++)o[c].active&&(n[i]=this.getBox(c,new Float32Array(6)),r[i]=c,i++);this.bvh.createFromArray(r,n,c=>{this.nodesMap.set(c.object,c)},this._margin)}insert(e){const t=this.bvh.insert(e,this.getBox(e,new Float32Array(6)),this._margin);this.nodesMap.set(e,t)}insertRange(e){const t=e.length,o=new Array(t);for(let n=0;n<t;n++)o[n]=this.getBox(e[n],new Float32Array(6));this.bvh.insertRange(e,o,this._margin,n=>{this.nodesMap.set(n.object,n)})}move(e){const t=this.nodesMap.get(e);t&&(this.getBox(e,t.box),this.bvh.move(t,this._margin))}delete(e){const t=this.nodesMap.get(e);t&&(this.bvh.delete(t),this.nodesMap.delete(e))}clear(){this.bvh.clear(),this.nodesMap.clear()}frustumCulling(e,t){this._margin>0&&this.accurateCulling?this.bvh.frustumCulling(e.elements,(o,n,r)=>{n.isIntersectedMargin(o.box,r,this._margin)&&t(o)}):this.bvh.frustumCulling(e.elements,t)}raycast(e,t){const o=e.ray,n=this._origin,r=this._dir;A.vec3ToArray(o.origin,n),A.vec3ToArray(o.direction,r),this.bvh.rayIntersections(r,n,t,e.near,e.far)}intersectBox(e,t){const o=this._boxArray;return A.box3ToArray(e,o),this.bvh.intersectsBox(o,t)}getBox(e,t){const o=this.target,n=o._instanceInfo[e].geometryIndex;return o.getBoundingBoxAt(n,z).applyMatrix4(o.getMatrixAt(e,lt)),A.box3ToArray(z,t),t}}const z=new u.Box3,lt=new u.Matrix4;class U{constructor(){this.array=[],this.pool=[]}push(e,t,o,n){const r=this.pool,i=this.array,c=i.length;c>=r.length&&r.push({start:null,count:null,z:null,zSort:null,index:null});const a=r[c];a.index=e,a.start=o,a.count=n,a.z=t,i.push(a)}reset(){this.array.length=0}}function Y(s,e={}){this.bvh=new G(this,s,e.margin,e.accurateCulling),this.bvh.create()}function dt(s){const e={get:t=>t.zSort,aux:new Array(s.maxInstanceCount),reversed:null};return function(o){e.reversed=s.material.transparent,s.maxInstanceCount>e.aux.length&&(e.aux.length=s.maxInstanceCount);let n=1/0,r=-1/0;for(const{z:a}of o)a>r&&(r=a),a<n&&(n=a);const i=r-n,c=(2**32-1)/i;for(const a of o)a.zSort=(a.z-n)*c;ht.radixSort(o,e)}}function k(s,e){return s.z-e.z}function N(s,e){return e.z-s.z}const V=new u.Frustum,M=new U,R=new u.Matrix4,T=new u.Matrix4,O=new u.Vector3,E=new u.Vector3,j=new u.Vector3,mt=new u.Vector3,D=new u.Sphere;function Z(s,e,t,o,n,r){this.frustumCulling(t)}function X(s,e=s){if(!this._visibilityChanged&&!this.perObjectFrustumCulled&&!this.sortObjects)return;this._indirectTexture.needsUpdate=!0,this._visibilityChanged=!1;const t=this.sortObjects,o=this.perObjectFrustumCulled;if(!o&&!t){this.updateIndexArray();return}if(T.copy(this.matrixWorld).invert(),E.setFromMatrixPosition(s.matrixWorld).applyMatrix4(T),j.setFromMatrixPosition(e.matrixWorld).applyMatrix4(T),O.set(0,0,-1).transformDirection(s.matrixWorld).transformDirection(T),o?(R.multiplyMatrices(s.projectionMatrix,s.matrixWorldInverse).multiply(this.matrixWorld),this.bvh?this.BVHCulling(s,e):this.linearCulling(s,e)):this.updateRenderList(),t){const n=this.geometry.getIndex(),r=n===null?1:n.array.BYTES_PER_ELEMENT,i=this._multiDrawStarts,c=this._multiDrawCounts,a=this._indirectTexture.image.data,g=this.customSort;g===null?M.array.sort(this.material.transparent?N:k):g(M.array);const l=M.array,d=l.length;for(let h=0;h<d;h++){const m=l[h];i[h]=m.start*r,c[h]=m.count,a[h]=m.index}M.reset()}}function $(){if(!this._visibilityChanged)return;const s=this.geometry.getIndex(),e=s===null?1:s.array.BYTES_PER_ELEMENT,t=this._instanceInfo,o=this._geometryInfo,n=this._multiDrawStarts,r=this._multiDrawCounts,i=this._indirectTexture.image.data;let c=0;for(let a=0,g=t.length;a<g;a++){const l=t[a];if(l.visible&&l.active){const d=l.geometryIndex,h=o[d];n[c]=h.start*e,r[c]=h.count,i[c]=a,c++}}this._multiDrawCount=c}function J(){const s=this._instanceInfo,e=this._geometryInfo;for(let t=0,o=s.length;t<o;t++){const n=s[t];if(n.visible&&n.active){const r=n.geometryIndex,i=e[r],c=this.getPositionAt(t).sub(E).dot(O);M.push(t,c,i.start,i.count)}}this._multiDrawCount=M.array.length}function K(s,e){const t=this.geometry.getIndex(),o=t===null?1:t.array.BYTES_PER_ELEMENT,n=this._instanceInfo,r=this._geometryInfo,i=this.sortObjects,c=this._multiDrawStarts,a=this._multiDrawCounts,g=this._indirectTexture.image.data,l=this.onFrustumEnter;let d=0;this.bvh.frustumCulling(R,h=>{const m=h.object,f=n[m];if(!f.visible)return;const B=f.geometryIndex,x=r[B],y=x.LOD;let p,I;if(y){const S=this.getPositionAt(m).distanceToSquared(j),w=this.getLODIndex(y,S);if(l&&!l(m,s,e,w))return;p=y[w].start,I=y[w].count}else{if(l&&!l(m,s))return;p=x.start,I=x.count}if(i){const S=this.getPositionAt(m).sub(E).dot(O);M.push(m,S,p,I)}else c[d]=p*o,a[d]=I,g[d]=m,d++}),this._multiDrawCount=i?M.array.length:d}function Q(s,e){const t=this.geometry.getIndex(),o=t===null?1:t.array.BYTES_PER_ELEMENT,n=this._instanceInfo,r=this._geometryInfo,i=this.sortObjects,c=this._multiDrawStarts,a=this._multiDrawCounts,g=this._indirectTexture.image.data,l=this.onFrustumEnter;let d=0;V.setFromProjectionMatrix(R);for(let h=0,m=n.length;h<m;h++){const f=n[h];if(!f.visible||!f.active)continue;const B=f.geometryIndex,x=r[B],y=x.LOD;let p,I;const S=x.boundingSphere,w=S.radius,C=S.center;if(C.x===0&&C.y===0&&C.z===0){const b=this.getPositionAndMaxScaleOnAxisAt(h,D.center);D.radius=w*b}else this.applyMatrixAtToSphere(h,D,C,w);if(V.intersectsSphere(D)){if(y){const b=D.center.distanceToSquared(j),v=this.getLODIndex(y,b);if(l&&!l(h,s,e,v))continue;p=y[v].start,I=y[v].count}else{if(l&&!l(h,s))continue;p=x.start,I=x.count}if(i){const b=mt.subVectors(D.center,E).dot(O);M.push(h,b,p,I)}else c[d]=p*o,a[d]=I,g[d]=h,d++}}this._multiDrawCount=i?M.array.length:d}const gt=new u.Vector3;function tt(s,e=gt){const t=s*16,o=this._matricesTexture.image.data;return e.x=o[t+12],e.y=o[t+13],e.z=o[t+14],e}function et(s,e){const t=s*16,o=this._matricesTexture.image.data,n=o[t+0],r=o[t+1],i=o[t+2],c=n*n+r*r+i*i,a=o[t+4],g=o[t+5],l=o[t+6],d=a*a+g*g+l*l,h=o[t+8],m=o[t+9],f=o[t+10],B=h*h+m*m+f*f;return e.x=o[t+12],e.y=o[t+13],e.z=o[t+14],Math.sqrt(Math.max(c,d,B))}function nt(s,e,t,o){const n=s*16,r=this._matricesTexture.image.data,i=r[n+0],c=r[n+1],a=r[n+2],g=r[n+3],l=r[n+4],d=r[n+5],h=r[n+6],m=r[n+7],f=r[n+8],B=r[n+9],x=r[n+10],y=r[n+11],p=r[n+12],I=r[n+13],S=r[n+14],w=r[n+15],C=e.center,L=t.x,b=t.y,v=t.z,P=1/(g*L+m*b+y*v+w);C.x=(i*L+l*b+f*v+p)*P,C.y=(c*L+d*b+B*v+I)*P,C.z=(a*L+h*b+x*v+S)*P;const ct=i*i+c*c+a*a,at=l*l+d*d+h*h,ut=f*f+B*B+x*x;e.radius=o*Math.sqrt(Math.max(ct,at,ut))}function ot(s,e,t,o=0){const n=this._geometryInfo[s];t=t**2,n.LOD??(n.LOD=[{start:n.start,count:n.count,distance:0,hysteresis:0}]);const r=n.LOD,i=r[r.length-1],c=i.start+i.count,a=e.index.count;if(c-n.start+a>n.reservedIndexCount)throw new Error("BatchedMesh LOD: Reserved space request exceeds the maximum buffer size.");r.push({start:c,count:a,distance:t,hysteresis:o});const g=e.getIndex().array,l=this.geometry.getIndex(),d=l.array,h=n.vertexStart;for(let m=0;m<a;m++)d[c+m]=g[m]+h;l.needsUpdate=!0}function st(s,e){for(let t=s.length-1;t>0;t--){const o=s[t],n=o.distance-o.distance*o.hysteresis;if(e>=n)return t}return 0}const F=[],_=new u.Mesh,ft=new u.Ray,q=new u.Vector3,W=new u.Vector3,H=new u.Matrix4;function rt(s,e){var i,c;if(!this.material||this.instanceCount===0)return;_.geometry=this.geometry,_.material=this.material,(i=_.geometry).boundingBox??(i.boundingBox=new u.Box3),(c=_.geometry).boundingSphere??(c.boundingSphere=new u.Sphere);const t=s.ray,o=s.near,n=s.far;H.copy(this.matrixWorld).invert(),W.setFromMatrixScale(this.matrixWorld),q.copy(s.ray.direction).multiply(W);const r=q.length();if(s.ray=ft.copy(s.ray).applyMatrix4(H),s.near/=r,s.far/=r,this.bvh)this.bvh.raycast(s,a=>this.checkInstanceIntersection(s,a,e));else if(this.boundingSphere===null&&this.computeBoundingSphere(),s.ray.intersectsSphere(this.boundingSphere))for(let a=0,g=this._instanceInfo.length;a<g;a++)this.checkInstanceIntersection(s,a,e);s.ray=t,s.near=o,s.far=n}function it(s,e,t){const o=this._instanceInfo[e];if(!o.active||!o.visible)return;const n=o.geometryIndex,r=this._geometryInfo[n];this.getMatrixAt(e,_.matrixWorld),_.geometry.boundsTree=this.boundsTrees?this.boundsTrees[n]:void 0,_.geometry.boundsTree||(this.getBoundingBoxAt(n,_.geometry.boundingBox),this.getBoundingSphereAt(n,_.geometry.boundingSphere),_.geometry.setDrawRange(r.start,r.count)),_.raycast(s,F);for(const i of F)i.batchId=e,i.object=this,t.push(i);F.length=0}function xt(){u.BatchedMesh.prototype.computeBVH=Y,u.BatchedMesh.prototype.onBeforeRender=Z,u.BatchedMesh.prototype.frustumCulling=X,u.BatchedMesh.prototype.updateIndexArray=$,u.BatchedMesh.prototype.updateRenderList=J,u.BatchedMesh.prototype.BVHCulling=K,u.BatchedMesh.prototype.linearCulling=Q,u.BatchedMesh.prototype.getPositionAt=tt,u.BatchedMesh.prototype.getPositionAndMaxScaleOnAxisAt=et,u.BatchedMesh.prototype.applyMatrixAtToSphere=nt,u.BatchedMesh.prototype.addGeometryLOD=ot,u.BatchedMesh.prototype.getLODIndex=st,u.BatchedMesh.prototype.raycast=rt,u.BatchedMesh.prototype.checkInstanceIntersection=it}function yt(){xt()}function pt(s){const e=s.material,t=e.onBeforeCompile.bind(e);e.onBeforeCompile=(o,n)=>{if(s.uniformsTexture){o.uniforms.uniformsTexture={value:s.uniformsTexture};const{vertex:r,fragment:i}=s.uniformsTexture.getUniformsGLSL("uniformsTexture","batchIndex","float");o.vertexShader=o.vertexShader.replace("void main() {",r),o.fragmentShader=o.fragmentShader.replace("void main() {",i),o.vertexShader=o.vertexShader.replace("void main() {","void main() { float batchIndex = getIndirectIndex( gl_DrawID );")}t(o,n)}}function It(s){let e=0,t=0;for(const o of s)e+=o.attributes.position.count,t+=o.index.count;return{vertexCount:e,indexCount:t}}function _t(s){const e=[];let t=0,o=0;for(const n of s){let r=0;for(const i of n){const c=i.index.count;o+=c,r+=c,t+=i.attributes.position.count}e.push(r)}return{vertexCount:t,indexCount:o,LODIndexCount:e}}exports.BVHCulling=K;exports.BatchedMeshBVH=G;exports.MultiDrawRenderList=U;exports.addGeometryLOD=ot;exports.applyMatrixAtToSphere=nt;exports.checkInstanceIntersection=it;exports.computeBVH=Y;exports.createRadixSort=dt;exports.extendBatchedMeshPrototype=yt;exports.frustumCulling=X;exports.getBatchedMeshCount=It;exports.getBatchedMeshLODCount=_t;exports.getLODIndex=st;exports.getPositionAndMaxScaleOnAxisAt=et;exports.getPositionAt=tt;exports.linearCulling=Q;exports.onBeforeRender=Z;exports.patchBatchedMeshMaterial=pt;exports.raycast=rt;exports.sortOpaque=k;exports.sortTransparent=N;exports.updateIndexArray=$;exports.updateRenderList=J; //# sourceMappingURL=webgpu.cjs.map