@three.ez/batched-mesh-extensions
Version:
Utility extension methods for BatchedMesh
32 lines (31 loc) • 19.4 kB
JavaScript
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=require("bvh.js"),h=require("three"),bt=require("three/addons/utils/SortUtils.js");class X{constructor(t,e,n=0,s=!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=t,this.accurateCulling=s,this._margin=n,this.bvh=new T.BVH(new T.HybridBuilder,e===2e3?T.WebGLCoordinateSystem:T.WebGPUCoordinateSystem)}create(){const t=this.target.instanceCount,e=this.target._instanceInfo.length,n=this.target._instanceInfo,s=new Array(t),o=new Uint32Array(t);let i=0;this.clear();for(let a=0;a<e;a++)n[a].active&&(s[i]=this.getBox(a,new Float32Array(6)),o[i]=a,i++);this.bvh.createFromArray(o,s,a=>{this.nodesMap.set(a.object,a)},this._margin)}insert(t){const e=this.bvh.insert(t,this.getBox(t,new Float32Array(6)),this._margin);this.nodesMap.set(t,e)}insertRange(t){const e=t.length,n=new Array(e);for(let s=0;s<e;s++)n[s]=this.getBox(t[s],new Float32Array(6));this.bvh.insertRange(t,n,this._margin,s=>{this.nodesMap.set(s.object,s)})}move(t){const e=this.nodesMap.get(t);e&&(this.getBox(t,e.box),this.bvh.move(e,this._margin))}delete(t){const e=this.nodesMap.get(t);e&&(this.bvh.delete(e),this.nodesMap.delete(t))}clear(){this.bvh.clear(),this.nodesMap.clear()}frustumCulling(t,e){this._margin>0&&this.accurateCulling?this.bvh.frustumCulling(t.elements,(n,s,o)=>{s.isIntersectedMargin(n.box,o,this._margin)&&e(n)}):this.bvh.frustumCulling(t.elements,e)}raycast(t,e){const n=t.ray,s=this._origin,o=this._dir;T.vec3ToArray(n.origin,s),T.vec3ToArray(n.direction,o),this.bvh.rayIntersections(o,s,e,t.near,t.far)}intersectBox(t,e){const n=this._boxArray;return T.box3ToArray(t,n),this.bvh.intersectsBox(n,e)}getBox(t,e){const n=this.target,s=n._instanceInfo[t].geometryIndex;return n.getBoundingBoxAt(s,k).applyMatrix4(n.getMatrixAt(t,Ct)),T.box3ToArray(k,e),e}}const k=new h.Box3,Ct=new h.Matrix4;class Z{constructor(){this.array=[],this.pool=[]}push(t,e,n,s){const o=this.pool,i=this.array,a=i.length;a>=o.length&&o.push({start:null,count:null,z:null,zSort:null,index:null});const c=o[a];c.index=t,c.start=n,c.count=s,c.z=e,i.push(c)}reset(){this.array.length=0}}function q(r,t){return Math.max(t,Math.ceil(Math.sqrt(r/t))*t)}function J(r,t,e,n){t===3&&(console.warn('"channels" cannot be 3. Set to 4. More info: https://github.com/mrdoob/three.js/pull/23228'),t=4);const s=q(n,e),o=new r(s*s*t),i=r.name.includes("Float"),a=r.name.includes("Uint"),c=i?h.FloatType:a?h.UnsignedIntType:h.IntType;let m;switch(t){case 1:m=i?h.RedFormat:h.RedIntegerFormat;break;case 2:m=i?h.RGFormat:h.RGIntegerFormat;break;case 4:m=i?h.RGBAFormat:h.RGBAIntegerFormat;break}return{array:o,size:s,type:c,format:m}}class Q extends h.DataTexture{constructor(t,e,n,s,o,i){e===3&&(e=4);const{array:a,format:c,size:m,type:u}=J(t,e,n,s);super(a,m,m,c,u),this.partialUpdate=!0,this.maxUpdateCalls=1/0,this._utils=null,this._needsUpdate=!1,this._lastWidth=null,this._data=a,this._channels=e,this._pixelsPerInstance=n,this._stride=n*e,this._rowToUpdate=new Array(m),this._uniformMap=o,this._fetchUniformsInFragmentShader=i,this.needsUpdate=!0}resize(t){const e=q(t,this._pixelsPerInstance);if(e===this.image.width)return;const n=this._data,s=this._channels;this._rowToUpdate.length=e;const o=n.constructor,i=new o(e*e*s),a=Math.min(n.length,i.length);i.set(new o(n.buffer,0,a)),this.dispose(),this.image={data:i,height:e,width:e},this._data=i}enqueueUpdate(t){if(this._needsUpdate=!0,!this.partialUpdate)return;const e=this.image.width/this._pixelsPerInstance,n=Math.floor(t/e);this._rowToUpdate[n]=!0}update(t){const e=t.properties.get(this),n=this.version>0&&e.__version!==this.version,s=this._lastWidth!==null&&this._lastWidth!==this.image.width;if(!this._needsUpdate||!e.__webglTexture||n||s){this._lastWidth=this.image.width,this._needsUpdate=!1;return}if(this._needsUpdate=!1,!this.partialUpdate){this.needsUpdate=!0;return}const o=this.getUpdateRowsInfo();o.length!==0&&(o.length>this.maxUpdateCalls?this.needsUpdate=!0:this.updateRows(e,t,o),this._rowToUpdate.fill(!1))}getUpdateRowsInfo(){const t=this._rowToUpdate,e=[];for(let n=0,s=t.length;n<s;n++)if(t[n]){const o=n;for(;n<s&&t[n];n++);e.push({row:o,count:n-o})}return e}updateRows(t,e,n){const s=e.state,o=e.getContext();this._utils??(this._utils=new h.WebGLUtils(o,e.extensions,e.capabilities));const i=this._utils.convert(this.format),a=this._utils.convert(this.type),{data:c,width:m}=this.image,u=this._channels;s.bindTexture(o.TEXTURE_2D,t.__webglTexture);const l=h.ColorManagement.getPrimaries(h.ColorManagement.workingColorSpace),f=this.colorSpace===h.NoColorSpace?null:h.ColorManagement.getPrimaries(this.colorSpace),d=this.colorSpace===h.NoColorSpace||l===f?o.NONE:o.BROWSER_DEFAULT_WEBGL;o.pixelStorei(o.UNPACK_FLIP_Y_WEBGL,this.flipY),o.pixelStorei(o.UNPACK_PREMULTIPLY_ALPHA_WEBGL,this.premultiplyAlpha),o.pixelStorei(o.UNPACK_ALIGNMENT,this.unpackAlignment),o.pixelStorei(o.UNPACK_COLORSPACE_CONVERSION_WEBGL,d);for(const{count:g,row:S}of n)o.texSubImage2D(o.TEXTURE_2D,0,0,S,m,g,i,a,c,S*m*u);this.onUpdate&&this.onUpdate(this)}setUniformAt(t,e,n){const{offset:s,size:o}=this._uniformMap.get(e),i=this._stride;o===1?this._data[t*i+s]=n:n.toArray(this._data,t*i+s)}getUniformAt(t,e,n){const{offset:s,size:o}=this._uniformMap.get(e),i=this._stride;return o===1?this._data[t*i+s]:n.fromArray(this._data,t*i+s)}getUniformsGLSL(t,e,n){const s=this.getUniformsVertexGLSL(t,e,n),o=this.getUniformsFragmentGLSL(t,e,n);return{vertex:s,fragment:o}}getUniformsVertexGLSL(t,e,n){if(this._fetchUniformsInFragmentShader)return`
flat varying ${n} ez_v${e};
void main() {
ez_v${e} = ${e};`;const s=this.texelsFetchGLSL(t,e),o=this.getFromTexelsGLSL(),{assignVarying:i,declareVarying:a}=this.getVarying();return`
uniform highp sampler2D ${t};
${a}
void main() {
${s}
${o}
${i}`}getUniformsFragmentGLSL(t,e,n){if(!this._fetchUniformsInFragmentShader){const{declareVarying:i,getVarying:a}=this.getVarying();return`
${i}
void main() {
${a}`}const s=this.texelsFetchGLSL(t,`ez_v${e}`),o=this.getFromTexelsGLSL();return`
uniform highp sampler2D ${t};
flat varying ${n} ez_v${e};
void main() {
${s}
${o}`}texelsFetchGLSL(t,e){const n=this._pixelsPerInstance;let s=`
int size = textureSize(${t}, 0).x;
int j = int(${e}) * ${n};
int x = j % size;
int y = j / size;
`;for(let o=0;o<n;o++)s+=`vec4 ez_texel${o} = texelFetch(${t}, ivec2(x + ${o}, y), 0);
`;return s}getFromTexelsGLSL(){const t=this._uniformMap;let e="";for(const[n,{type:s,offset:o,size:i}]of t){const a=Math.floor(o/this._channels);if(s==="mat3")e+=`mat3 ${n} = mat3(ez_texel${a}.rgb, vec3(ez_texel${a}.a, ez_texel${a+1}.rg), vec3(ez_texel${a+1}.ba, ez_texel${a+2}.r));
`;else if(s==="mat4")e+=`mat4 ${n} = mat4(ez_texel${a}, ez_texel${a+1}, ez_texel${a+2}, ez_texel${a+3});
`;else{const c=this.getUniformComponents(o,i);e+=`${s} ${n} = ez_texel${a}.${c};
`}}return e}getVarying(){const t=this._uniformMap;let e="",n="",s="";for(const[o,{type:i}]of t)e+=`flat varying ${i} ez_v${o};
`,n+=`ez_v${o} = ${o};
`,s+=`${i} ${o} = ez_v${o};
`;return{declareVarying:e,assignVarying:n,getVarying:s}}getUniformComponents(t,e){const n=t%this._channels;let s="";for(let o=0;o<e;o++)s+=At[n+o];return s}copy(t){return super.copy(t),this.partialUpdate=t.partialUpdate,this.maxUpdateCalls=t.maxUpdateCalls,this._channels=t._channels,this._pixelsPerInstance=t._pixelsPerInstance,this._stride=t._stride,this._rowToUpdate=t._rowToUpdate,this._uniformMap=t._uniformMap,this._fetchUniformsInFragmentShader=t._fetchUniformsInFragmentShader,this}}const At=["r","g","b","a"];function tt(r,t={}){this.bvh=new X(this,r,t.margin,t.accurateCulling),this.bvh.create()}function Ut(r){const t={get:e=>e.zSort,aux:new Array(r.maxInstanceCount),reversed:null};return function(n){t.reversed=r.material.transparent,r.maxInstanceCount>t.aux.length&&(t.aux.length=r.maxInstanceCount);let s=1/0,o=-1/0;for(const{z:c}of n)c>o&&(o=c),c<s&&(s=c);const i=o-s,a=(2**32-1)/i;for(const c of n)c.zSort=(c.z-s)*a;bt.radixSort(n,t)}}function et(r,t){return r.z-t.z}function nt(r,t){return t.z-r.z}const H=new h.Frustum,C=new Z,G=new h.Matrix4,z=new h.Matrix4,E=new h.Vector3,$=new h.Vector3,j=new h.Vector3,Bt=new h.Vector3,M=new h.Sphere;function st(r,t,e,n,s,o){var i;this.frustumCulling(e),(i=this.uniformsTexture)==null||i.update(r)}function ot(r,t=r){if(!this._visibilityChanged&&!this.perObjectFrustumCulled&&!this.sortObjects)return;this._indirectTexture.needsUpdate=!0,this._visibilityChanged=!1;const e=this.sortObjects,n=this.perObjectFrustumCulled;if(!n&&!e){this.updateIndexArray();return}if(z.copy(this.matrixWorld).invert(),$.setFromMatrixPosition(r.matrixWorld).applyMatrix4(z),j.setFromMatrixPosition(t.matrixWorld).applyMatrix4(z),E.set(0,0,-1).transformDirection(r.matrixWorld).transformDirection(z),n?(G.multiplyMatrices(r.projectionMatrix,r.matrixWorldInverse).multiply(this.matrixWorld),this.bvh?this.BVHCulling(r,t):this.linearCulling(r,t)):this.updateRenderList(),e){const s=this.geometry.getIndex(),o=s===null?1:s.array.BYTES_PER_ELEMENT,i=this._multiDrawStarts,a=this._multiDrawCounts,c=this._indirectTexture.image.data,m=this.customSort;m===null?C.array.sort(this.material.transparent?nt:et):m(C.array);const u=C.array,l=u.length;for(let f=0;f<l;f++){const d=u[f];i[f]=d.start*o,a[f]=d.count,c[f]=d.index}C.reset()}}function rt(){if(!this._visibilityChanged)return;const r=this.geometry.getIndex(),t=r===null?1:r.array.BYTES_PER_ELEMENT,e=this._instanceInfo,n=this._geometryInfo,s=this._multiDrawStarts,o=this._multiDrawCounts,i=this._indirectTexture.image.data;let a=0;for(let c=0,m=e.length;c<m;c++){const u=e[c];if(u.visible&&u.active){const l=u.geometryIndex,f=n[l];s[a]=f.start*t,o[a]=f.count,i[a]=c,a++}}this._multiDrawCount=a}function it(){const r=this._instanceInfo,t=this._geometryInfo;for(let e=0,n=r.length;e<n;e++){const s=r[e];if(s.visible&&s.active){const o=s.geometryIndex,i=t[o],a=this.getPositionAt(e).sub($).dot(E);C.push(e,a,i.start,i.count)}}this._multiDrawCount=C.array.length}function at(r,t){const e=this.geometry.getIndex(),n=e===null?1:e.array.BYTES_PER_ELEMENT,s=this._instanceInfo,o=this._geometryInfo,i=this.sortObjects,a=this._multiDrawStarts,c=this._multiDrawCounts,m=this._indirectTexture.image.data,u=this.onFrustumEnter;let l=0;const f=r,d=(f.top-f.bottom)/f.zoom,g=r,S=Math.tan(g.fov*.5*(Math.PI/180))**2,A=this.useDistanceForLOD,D=g.isPerspectiveCamera;this.bvh.frustumCulling(G,_=>{const v=_.object,U=s[v];if(!U.visible)return;const F=U.geometryIndex,I=o[F],p=I.LOD;let x,y;if(p){M.radius=I.boundingSphere.radius;let w;if(D){const L=this.getPositionAt(v).distanceToSquared(j);w=ct(A,M,S,L)}else w=ht(A,M,d);const B=this.getLODIndex(p,w,D);if(u&&!u(v,r,t,B))return;x=p[B].start,y=p[B].count}else{if(u&&!u(v,r))return;x=I.start,y=I.count}if(i){const w=this.getPositionAt(v).sub($).dot(E);C.push(v,w,x,y)}else a[l]=x*n,c[l]=y,m[l]=v,l++}),this._multiDrawCount=i?C.array.length:l}function ct(r,t,e,n){return r?n:t.radius**2/(n*e)}function ht(r,t,e){if(r)throw new Error("BatchedMesh: useDistanceForLOD cannot be used with orthographic camera.");return t.radius*2/e}function ut(r,t){const e=this.geometry.getIndex(),n=e===null?1:e.array.BYTES_PER_ELEMENT,s=this._instanceInfo,o=this._geometryInfo,i=this.sortObjects,a=this._multiDrawStarts,c=this._multiDrawCounts,m=this._indirectTexture.image.data,u=this.onFrustumEnter;let l=0;H.setFromProjectionMatrix(G);const f=r,d=(f.top-f.bottom)/f.zoom,g=r,S=Math.tan(g.fov*.5*(Math.PI/180))**2,A=this.useDistanceForLOD,D=g.isPerspectiveCamera;for(let _=0,v=s.length;_<v;_++){const U=s[_];if(!U.visible||!U.active)continue;const F=U.geometryIndex,I=o[F],p=I.LOD;let x,y;const w=I.boundingSphere,B=w.radius,L=w.center;if(L.x===0&&L.y===0&&L.z===0){const P=this.getPositionAndMaxScaleOnAxisAt(_,M.center);M.radius=B*P}else this.applyMatrixAtToSphere(_,M,L,B);if(H.intersectsSphere(M)){if(p){let P;if(D){const Mt=M.center.distanceToSquared(j);P=ct(A,M,S,Mt)}else P=ht(A,M,d);const O=this.getLODIndex(p,P,D);if(u&&!u(_,r,t,O))continue;x=p[O].start,y=p[O].count}else{if(u&&!u(_,r))continue;x=I.start,y=I.count}if(i){const P=Bt.subVectors(M.center,$).dot(E);C.push(_,P,x,y)}else a[l]=x*n,c[l]=y,m[l]=_,l++}}this._multiDrawCount=i?C.array.length:l}const Lt=new h.Vector3;function lt(r,t=Lt){const e=r*16,n=this._matricesTexture.image.data;return t.x=n[e+12],t.y=n[e+13],t.z=n[e+14],t}function ft(r,t){const e=r*16,n=this._matricesTexture.image.data,s=n[e+0],o=n[e+1],i=n[e+2],a=s*s+o*o+i*i,c=n[e+4],m=n[e+5],u=n[e+6],l=c*c+m*m+u*u,f=n[e+8],d=n[e+9],g=n[e+10],S=f*f+d*d+g*g;return t.x=n[e+12],t.y=n[e+13],t.z=n[e+14],Math.sqrt(Math.max(a,l,S))}function mt(r,t,e,n){const s=r*16,o=this._matricesTexture.image.data,i=o[s+0],a=o[s+1],c=o[s+2],m=o[s+3],u=o[s+4],l=o[s+5],f=o[s+6],d=o[s+7],g=o[s+8],S=o[s+9],A=o[s+10],D=o[s+11],_=o[s+12],v=o[s+13],U=o[s+14],F=o[s+15],I=t.center,p=e.x,x=e.y,y=e.z,w=1/(m*p+d*x+D*y+F);I.x=(i*p+u*x+g*y+_)*w,I.y=(a*p+l*x+S*y+v)*w,I.z=(c*p+f*x+A*y+U)*w;const B=i*i+a*a+c*c,L=u*u+l*l+f*f,W=g*g+S*S+A*A;t.radius=n*Math.sqrt(Math.max(B,L,W))}function dt(r,t,e){const n=this._geometryInfo[r],s=t.isBufferGeometry?t.index.array:t,o=e**2;n.LOD??(n.LOD=[{start:n.start,count:n.count,metric:1/0,metricSquared:1/0}]);const i=n.LOD,a=i[i.length-1],c=a.start+a.count,m=s.length;if(c-n.start+m>n.reservedIndexCount)throw new Error("BatchedMesh LOD: Reserved space request exceeds the maximum buffer size.");i.push({start:c,count:m,metric:e,metricSquared:o});const u=this.geometry.getIndex(),l=u.array,f=n.vertexStart;for(let d=0;d<m;d++)l[c+d]=s[d]+f;u.needsUpdate=!0}function gt(r,t,e=!1){const n=e?"metricSquared":"metric";if(this.useDistanceForLOD){for(let s=r.length-1;s>0;s--){const i=r[s][n];if(t>=i)return s}return 0}for(let s=r.length-1;s>0;s--){const i=r[s][n];if(t<=i)return s}return 0}const R=[],b=new h.Mesh,Tt=new h.Ray,Y=new h.Vector3,N=new h.Vector3,K=new h.Matrix4;function pt(r,t){var i,a;if(!this.material||this.instanceCount===0)return;b.geometry=this.geometry,b.material=this.material,(i=b.geometry).boundingBox??(i.boundingBox=new h.Box3),(a=b.geometry).boundingSphere??(a.boundingSphere=new h.Sphere);const e=r.ray,n=r.near,s=r.far;K.copy(this.matrixWorld).invert(),N.setFromMatrixScale(this.matrixWorld),Y.copy(r.ray.direction).multiply(N);const o=Y.length();if(r.ray=Tt.copy(r.ray).applyMatrix4(K),r.near/=o,r.far/=o,this.bvh)this.bvh.raycast(r,c=>this.checkInstanceIntersection(r,c,t));else if(this.boundingSphere===null&&this.computeBoundingSphere(),r.ray.intersectsSphere(this.boundingSphere))for(let c=0,m=this._instanceInfo.length;c<m;c++)this.checkInstanceIntersection(r,c,t);r.ray=e,r.near=n,r.far=s}function xt(r,t,e){const n=this._instanceInfo[t];if(!n.active||!n.visible)return;const s=n.geometryIndex,o=this._geometryInfo[s];this.getMatrixAt(t,b.matrixWorld),b.geometry.boundsTree=this.boundsTrees?this.boundsTrees[s]:void 0,b.geometry.boundsTree||(this.getBoundingBoxAt(s,b.geometry.boundingBox),this.getBoundingSphereAt(s,b.geometry.boundingSphere),b.geometry.setDrawRange(o.start,o.count)),b.raycast(r,R);for(const i of R)i.batchId=t,i.object=this,e.push(i);R.length=0}function yt(r){const t=r.material,e=t.onBeforeCompile.bind(t);t.onBeforeCompile=(n,s)=>{if(r.uniformsTexture){n.uniforms.uniformsTexture={value:r.uniformsTexture};const{vertex:o,fragment:i}=r.uniformsTexture.getUniformsGLSL("uniformsTexture","batchIndex","float");n.vertexShader=n.vertexShader.replace("void main() {",o),n.fragmentShader=n.fragmentShader.replace("void main() {",i),n.vertexShader=n.vertexShader.replace("void main() {","void main() { float batchIndex = getIndirectIndex( gl_DrawID );")}e(n,s)}}function _t(r,t,e){if(!this.uniformsTexture)throw new Error(`Before get/set uniform, it's necessary to use "initUniformsPerInstance".`);return this.uniformsTexture.getUniformAt(r,t,e)}function It(r,t,e){if(!this.uniformsTexture)throw new Error(`Before get/set uniform, it's necessary to use "initUniformsPerInstance".`);this.uniformsTexture.setUniformAt(r,t,e),this.uniformsTexture.enqueueUpdate(r)}function St(r){if(this.uniformsTexture)throw new Error('"initUniformsPerInstance" must be called only once.');const{channels:t,pixelsPerInstance:e,uniformMap:n,fetchInFragmentShader:s}=wt(r);this.uniformsTexture=new Q(Float32Array,t,e,this.maxInstanceCount,n,s),yt(this)}function wt(r){let t=0;const e=new Map,n=[],s=r.vertex??{},o=r.fragment??{};let i=!0;for(const u in s){const l=s[u],f=V(l);t+=f,n.push({name:u,type:l,size:f}),i=!1}for(const u in o)if(!s[u]){const l=o[u],f=V(l);t+=f,n.push({name:u,type:l,size:f})}n.sort((u,l)=>l.size-u.size);const a=[];for(const{name:u,size:l,type:f}of n){const d=vt(l,a);e.set(u,{offset:d,size:l,type:f})}const c=Math.ceil(t/4);return{channels:Math.min(t,4),pixelsPerInstance:c,uniformMap:e,fetchInFragmentShader:i}}function vt(r,t){if(r<4){for(let n=0;n<t.length;n++)if(t[n]+r<=4){const s=n*4+t[n];return t[n]+=r,s}}const e=t.length*4;for(;r>0;r-=4)t.push(r);return e}function V(r){switch(r){case"float":return 1;case"vec2":return 2;case"vec3":return 3;case"vec4":return 4;case"mat3":return 9;case"mat4":return 16;default:throw new Error(`Invalid uniform type: ${r}`)}}function Dt(){h.BatchedMesh.prototype.computeBVH=tt,h.BatchedMesh.prototype.onBeforeRender=st,h.BatchedMesh.prototype.frustumCulling=ot,h.BatchedMesh.prototype.updateIndexArray=rt,h.BatchedMesh.prototype.updateRenderList=it,h.BatchedMesh.prototype.BVHCulling=at,h.BatchedMesh.prototype.linearCulling=ut,h.BatchedMesh.prototype.getPositionAt=lt,h.BatchedMesh.prototype.getPositionAndMaxScaleOnAxisAt=ft,h.BatchedMesh.prototype.applyMatrixAtToSphere=mt,h.BatchedMesh.prototype.addGeometryLOD=dt,h.BatchedMesh.prototype.getLODIndex=gt,h.BatchedMesh.prototype.raycast=pt,h.BatchedMesh.prototype.checkInstanceIntersection=xt}function Pt(){Dt(),h.BatchedMesh.prototype.getUniformAt=_t,h.BatchedMesh.prototype.setUniformAt=It,h.BatchedMesh.prototype.initUniformsPerInstance=St}function Ft(r){let t=0,e=0;for(const n of r)t+=n.attributes.position.count,e+=n.index.count;return{vertexCount:t,indexCount:e}}function zt(r){const t=[];let e=0,n=0;for(const s of r){let o=0;for(const i of s){const a=i.index.count;n+=a,o+=a,e+=i.attributes.position.count}t.push(o)}return{vertexCount:e,indexCount:n,LODIndexCount:t}}exports.BVHCulling=at;exports.BatchedMeshBVH=X;exports.MultiDrawRenderList=Z;exports.SquareDataTexture=Q;exports.addGeometryLOD=dt;exports.applyMatrixAtToSphere=mt;exports.checkInstanceIntersection=xt;exports.computeBVH=tt;exports.createRadixSort=Ut;exports.extendBatchedMeshPrototype=Pt;exports.frustumCulling=ot;exports.getBatchedMeshCount=Ft;exports.getBatchedMeshLODCount=zt;exports.getLODIndex=gt;exports.getPositionAndMaxScaleOnAxisAt=ft;exports.getPositionAt=lt;exports.getSquareTextureInfo=J;exports.getSquareTextureSize=q;exports.getUniformAt=_t;exports.getUniformOffset=vt;exports.getUniformSchemaResult=wt;exports.getUniformSize=V;exports.initUniformsPerInstance=St;exports.linearCulling=ut;exports.onBeforeRender=st;exports.patchBatchedMeshMaterial=yt;exports.raycast=pt;exports.setUniformAt=It;exports.sortOpaque=et;exports.sortTransparent=nt;exports.updateIndexArray=rt;exports.updateRenderList=it;
//# sourceMappingURL=webgl.cjs.map