UNPKG

@three.ez/instanced-mesh

Version:

Enhanced InstancedMesh with frustum culling, fast raycasting (using BVH), sorting, visibility management and more.

98 lines (90 loc) 48.9 kB
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("three"),D=require("bvh.js"),St=require("three/addons/utils/SortUtils.js");class st{constructor(t,e,n){if(this.isInstanceEntity=!0,this.position=new u.Vector3,this.scale=new u.Vector3(1,1,1),this.quaternion=new u.Quaternion,this.id=e,this.owner=t,n){const i=this.quaternion,s=this.rotation=new u.Euler;s._onChange(()=>i.setFromEuler(s,!1)),i._onChange(()=>s.setFromQuaternion(i,void 0,!1))}}get visible(){return this.owner.getVisibilityAt(this.id)}set visible(t){this.owner.setVisibilityAt(this.id,t)}get active(){return this.owner.getActiveAt(this.id)}set active(t){this.owner.setActiveAt(this.id,t)}get color(){return this.owner.getColorAt(this.id)}set color(t){this.owner.setColorAt(this.id,t)}get opacity(){return this.owner.getOpacityAt(this.id)}set opacity(t){this.owner.setOpacityAt(this.id,t)}get morph(){return this.owner.getMorphAt(this.id)}set morph(t){this.owner.setMorphAt(this.id,t)}get matrix(){return this.owner.getMatrixAt(this.id)}get matrixWorld(){return this.matrix.premultiply(this.owner.matrixWorld)}setMatrixIdentity(){const t=this.owner,e=t.matricesTexture._data,n=this.id,i=n*16;e[i+0]=1,e[i+1]=0,e[i+2]=0,e[i+3]=0,e[i+4]=0,e[i+5]=1,e[i+6]=0,e[i+7]=0,e[i+8]=0,e[i+9]=0,e[i+10]=1,e[i+11]=0,e[i+12]=0,e[i+13]=0,e[i+14]=0,e[i+15]=1,t.matricesTexture.enqueueUpdate(n)}updateMatrix(){const t=this.owner,e=this.position,n=this.quaternion,i=this.scale,s=t.matricesTexture._data,o=this.id,a=o*16,c=n._x,h=n._y,l=n._z,d=n._w,p=c+c,x=h+h,m=l+l,_=c*p,g=c*x,v=c*m,w=h*x,S=h*m,M=l*m,O=d*p,L=d*x,T=d*m,y=i.x,b=i.y,A=i.z;s[a+0]=(1-(w+M))*y,s[a+1]=(g+T)*y,s[a+2]=(v-L)*y,s[a+3]=0,s[a+4]=(g-T)*b,s[a+5]=(1-(_+M))*b,s[a+6]=(S+O)*b,s[a+7]=0,s[a+8]=(v+L)*A,s[a+9]=(S-O)*A,s[a+10]=(1-(_+w))*A,s[a+11]=0,s[a+12]=e.x,s[a+13]=e.y,s[a+14]=e.z,s[a+15]=1,t.matricesTexture.enqueueUpdate(o),t.bvh&&t.autoUpdateBVH&&t.bvh.move(o)}updateMatrixPosition(){const t=this.owner,e=this.position,n=t.matricesTexture._data,i=this.id,s=i*16;n[s+12]=e.x,n[s+13]=e.y,n[s+14]=e.z,t.matricesTexture.enqueueUpdate(i),t.bvh&&t.autoUpdateBVH&&t.bvh.move(i)}getUniform(t,e){return this.owner.getUniformAt(this.id,t,e)}updateBones(t=!0,e){this.owner.setBonesAt(this.id,t,e)}setUniform(t,e){this.owner.setUniformAt(this.id,t,e)}copyTo(t){t.position.copy(this.position),t.scale.copy(this.scale),t.quaternion.copy(this.quaternion),this.rotation&&t.rotation.copy(this.rotation)}applyMatrix4(t){return this.matrix.premultiply(t).decompose(this.position,this.quaternion,this.scale),this}applyQuaternion(t){return this.quaternion.premultiply(t),this}rotateOnAxis(t,e){return X.setFromAxisAngle(t,e),this.quaternion.multiply(X),this}rotateOnWorldAxis(t,e){return X.setFromAxisAngle(t,e),this.quaternion.premultiply(X),this}rotateX(t){return this.rotateOnAxis(ht,t)}rotateY(t){return this.rotateOnAxis(ut,t)}rotateZ(t){return this.rotateOnAxis(lt,t)}translateOnAxis(t,e){return ct.copy(t).applyQuaternion(this.quaternion),this.position.add(ct.multiplyScalar(e)),this}translateX(t){return this.translateOnAxis(ht,t)}translateY(t){return this.translateOnAxis(ut,t)}translateZ(t){return this.translateOnAxis(lt,t)}remove(){return this.owner.removeInstances(this.id),this}}const X=new u.Quaternion,ct=new u.Vector3,ht=new u.Vector3(1,0,0),ut=new u.Vector3(0,1,0),lt=new u.Vector3(0,0,1);class At{constructor(t,e=0,n=!1,i=!0){this.nodesMap=new Map,this.LODsMap=new Map,this._geoBoundingSphere=null,this._sphereTarget=null,this.target=t,this.accurateCulling=i,this._margin=e;const s=t._geometry;if(s.boundingBox||s.computeBoundingBox(),this.geoBoundingBox=s.boundingBox,n){s.boundingSphere||s.computeBoundingSphere();const o=s.boundingSphere.center;o.x===0&&o.y===0&&o.z===0?(this._geoBoundingSphere=s.boundingSphere,this._sphereTarget={centerX:0,centerY:0,centerZ:0,maxScale:0}):(console.warn('"getBoxFromSphere" is ignored because geometry is not centered.'),n=!1)}this.bvh=new D.BVH(new D.HybridBuilder,D.WebGLCoordinateSystem),this._origin=new Float32Array(3),this._dir=new Float32Array(3),this._cameraPos=new Float32Array(3),this._getBoxFromSphere=n}create(){const t=this.target._instancesCount,e=this.target._instancesArrayCount,n=new Array(t),i=new Uint32Array(t);let s=0;this.clear();for(let o=0;o<e;o++)this.target.getActiveAt(o)&&(n[s]=this.getBox(o,new Float32Array(6)),i[s]=o,s++);this.bvh.createFromArray(i,n,o=>{this.nodesMap.set(o.object,o)},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 i=0;i<e;i++)n[i]=this.getBox(t[i],new Float32Array(6));this.bvh.insertRange(t,n,this._margin,i=>{this.nodesMap.set(i.object,i)})}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,i,s)=>{i.isIntersectedMargin(n.box,s,this._margin)&&e(n)}):this.bvh.frustumCulling(t.elements,e)}frustumCullingLOD(t,e,n,i){this.LODsMap.has(n)||this.LODsMap.set(n,new Float32Array(n.length));const s=this.LODsMap.get(n);for(let a=0;a<n.length;a++)s[a]=n[a].distance;const o=this._cameraPos;o[0]=e.x,o[1]=e.y,o[2]=e.z,this._margin>0&&this.accurateCulling?this.bvh.frustumCullingLOD(t.elements,o,s,(a,c,h,l)=>{h.isIntersectedMargin(a.box,l,this._margin)&&i(a,c)}):this.bvh.frustumCullingLOD(t.elements,o,s,i)}raycast(t,e){const n=t.ray,i=this._origin,s=this._dir;D.vec3ToArray(n.origin,i),D.vec3ToArray(n.direction,s),this.bvh.rayIntersections(s,i,e,t.near,t.far)}intersectBox(t,e){this._boxArray||(this._boxArray=new Float32Array(6));const n=this._boxArray;return D.box3ToArray(t,n),this.bvh.intersectsBox(n,e)}getBox(t,e){if(this._getBoxFromSphere){const n=this.target.matricesTexture._data,{centerX:i,centerY:s,centerZ:o,maxScale:a}=this.getSphereFromMatrix_centeredGeometry(t,n,this._sphereTarget),c=this._geoBoundingSphere.radius*a;e[0]=i-c,e[1]=i+c,e[2]=s-c,e[3]=s+c,e[4]=o-c,e[5]=o+c}else dt.copy(this.geoBoundingBox).applyMatrix4(this.target.getMatrixAt(t)),D.box3ToArray(dt,e);return e}getSphereFromMatrix_centeredGeometry(t,e,n){const i=t*16,s=e[i+0],o=e[i+1],a=e[i+2],c=e[i+4],h=e[i+5],l=e[i+6],d=e[i+8],p=e[i+9],x=e[i+10],m=s*s+o*o+a*a,_=c*c+h*h+l*l,g=d*d+p*p+x*x;return n.maxScale=Math.sqrt(Math.max(m,_,g)),n.centerX=e[i+12],n.centerY=e[i+13],n.centerZ=e[i+14],n}}const dt=new u.Box3;class vt extends u.GLBufferAttribute{constructor(t,e,n,i,s,o=1){const a=t.createBuffer();super(a,e,n,i,s.length/n),this.isGLInstancedBufferAttribute=!0,this._needsUpdate=!1,this.isInstancedBufferAttribute=!0,this.meshPerAttribute=o,this.array=s,this._cacheArray=s,t.bindBuffer(t.ARRAY_BUFFER,a),t.bufferData(t.ARRAY_BUFFER,s,t.DYNAMIC_DRAW)}update(t,e){if(!this._needsUpdate||e===0)return;const n=t.getContext();n.bindBuffer(n.ARRAY_BUFFER,this.buffer),this.array===this._cacheArray?n.bufferSubData(n.ARRAY_BUFFER,0,this.array,0,e):(n.bufferData(n.ARRAY_BUFFER,this.array,n.DYNAMIC_DRAW),this._cacheArray=this.array),this._needsUpdate=!1}clone(){return this}}let tt=null,Z=null;const ft={};function Mt(r){return Z.get(r)?.()??tt(r)}function Ot(r){if(Z.has(r))return;const t={};Z.set(r,()=>{if(r.isMeshDistanceMaterial){const e=tt(r);t.light=e.light}return t})}function Tt(r,t,e){const n=t.properties;tt=n.get;const i=`${!!r.colorsTexture}_${r._useOpacity}_${!!r.boneTexture}_${!!r.uniformsTexture}`;ft[i]??=new WeakMap,Z=ft[i],n.get=Mt,Ot(e)}function It(r){r.properties.get=tt}function rt(r,t){return Math.max(t,Math.ceil(Math.sqrt(r/t))*t)}function Ct(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 i=rt(n,e),s=new r(i*i*t),o=r.name.includes("Float"),a=r.name.includes("Uint"),c=o?u.FloatType:a?u.UnsignedIntType:u.IntType;let h;switch(t){case 1:h=o?u.RedFormat:u.RedIntegerFormat;break;case 2:h=o?u.RGFormat:u.RGIntegerFormat;break;case 4:h=o?u.RGBAFormat:u.RGBAIntegerFormat;break}return{array:s,size:i,type:c,format:h}}class j extends u.DataTexture{constructor(t,e,n,i,s,o){e===3&&(e=4);const{array:a,format:c,size:h,type:l}=Ct(t,e,n,i);super(a,h,h,c,l),this.partialUpdate=!0,this.maxUpdateCalls=1/0,this._utils=null,this._needsUpdate=!0,this._lastWidth=-1,this._data=a,this._channels=e,this._pixelsPerInstance=n,this._stride=n*e,this._rowToUpdate=new Array(h),this._uniformMap=s,this._fetchUniformsInFragmentShader=o,this.needsUpdate=!0}resize(t){const e=rt(t,this._pixelsPerInstance);if(e===this.image.width)return;const n=this._data,i=this._channels;this._rowToUpdate.length=e;const s=n.constructor,o=new s(e*e*i),a=Math.min(n.length,o.length);o.set(new s(n.buffer,0,a)),this.dispose(),this.image={data:o,height:e,width:e},this._data=o}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}bindToProgram(t,e,n,i,s){if(!i[s])return;i[s].value=this;const o=this.getSlot(n,s);if(o===void 0)return;const a=t.properties.get(this);t.state.bindTexture(e.TEXTURE_2D,a.__webglTexture,e.TEXTURE0+o)}update(t,e,n){const i=t.properties.get(this),s=i.__version!==this.version;if(!this._needsUpdate&&!s)return;const o=this._lastWidth!==this.image.width;if(!i.__webglTexture||o)t.initTexture(this);else{const a=this.getSlot(e,n)??t.capabilities.maxTextures-1;this.partialUpdate?this.updatePartial(i,t,a):this.updateFull(i,t,a),i.__version=this.version}this._lastWidth=this.image.width,this._needsUpdate=!1}getSlot(t,e){return t[e]?.cache[0]}updateFull(t,e,n){this.updateRows(t,e,[{row:0,count:this.image.height}],n)}updatePartial(t,e,n){const i=this.getUpdateRowsInfo();i.length!==0&&(i.length>this.maxUpdateCalls?this.updateFull(t,e,n):this.updateRows(t,e,i,n),this._rowToUpdate.fill(!1))}getUpdateRowsInfo(){const t=this._rowToUpdate,e=[];for(let n=0,i=t.length;n<i;n++)if(t[n]){const s=n;for(;n<i&&t[n];n++);e.push({row:s,count:n-s})}return e}updateRows(t,e,n,i){const s=e.getContext();this._utils??=new u.WebGLUtils(s,e.extensions,e.capabilities);const o=this._utils.convert(this.format),a=this._utils.convert(this.type),{data:c,width:h}=this.image,l=this._channels;e.state.activeTexture(s.TEXTURE0+i),e.state.bindTexture(s.TEXTURE_2D,t.__webglTexture,s.TEXTURE0+i);const d=u.ColorManagement.getPrimaries(u.ColorManagement.workingColorSpace),p=this.colorSpace===u.NoColorSpace?null:u.ColorManagement.getPrimaries(this.colorSpace),x=this.colorSpace===u.NoColorSpace||d===p?s.NONE:s.BROWSER_DEFAULT_WEBGL;s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL,this.flipY),s.pixelStorei(s.UNPACK_PREMULTIPLY_ALPHA_WEBGL,this.premultiplyAlpha),s.pixelStorei(s.UNPACK_ALIGNMENT,this.unpackAlignment),s.pixelStorei(s.UNPACK_COLORSPACE_CONVERSION_WEBGL,x);for(const{count:m,row:_}of n)s.texSubImage2D(s.TEXTURE_2D,0,0,_,h,m,o,a,c,_*h*l);this.onUpdate?.(this)}setUniformAt(t,e,n){const{offset:i,size:s}=this._uniformMap.get(e),o=this._stride;s===1?this._data[t*o+i]=n:n.toArray(this._data,t*o+i)}getUniformAt(t,e,n){const{offset:i,size:s}=this._uniformMap.get(e),o=this._stride;return s===1?this._data[t*o+i]:n.fromArray(this._data,t*o+i)}getUniformsGLSL(t,e,n){const i=this.getUniformsVertexGLSL(t,e,n),s=this.getUniformsFragmentGLSL(t,e,n);return{vertex:i,fragment:s}}getUniformsVertexGLSL(t,e,n){if(this._fetchUniformsInFragmentShader)return` flat varying ${n} ez_v${e}; void main() { ez_v${e} = ${e};`;const i=this.texelsFetchGLSL(t,e),s=this.getFromTexelsGLSL(),{assignVarying:o,declareVarying:a}=this.getVarying();return` uniform highp sampler2D ${t}; ${a} void main() { ${i} ${s} ${o}`}getUniformsFragmentGLSL(t,e,n){if(!this._fetchUniformsInFragmentShader){const{declareVarying:o,getVarying:a}=this.getVarying();return` ${o} void main() { ${a}`}const i=this.texelsFetchGLSL(t,`ez_v${e}`),s=this.getFromTexelsGLSL();return` uniform highp sampler2D ${t}; flat varying ${n} ez_v${e}; void main() { ${i} ${s}`}texelsFetchGLSL(t,e){const n=this._pixelsPerInstance;let i=` int size = textureSize(${t}, 0).x; int j = int(${e}) * ${n}; int x = j % size; int y = j / size; `;for(let s=0;s<n;s++)i+=`vec4 ez_texel${s} = texelFetch(${t}, ivec2(x + ${s}, y), 0); `;return i}getFromTexelsGLSL(){const t=this._uniformMap;let e="";for(const[n,{type:i,offset:s,size:o}]of t){const a=Math.floor(s/this._channels);if(i==="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(i==="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(s,o);e+=`${i} ${n} = ez_texel${a}.${c}; `}}return e}getVarying(){const t=this._uniformMap;let e="",n="",i="";for(const[s,{type:o}]of t)e+=`flat varying ${o} ez_v${s}; `,n+=`ez_v${s} = ${s}; `,i+=`${o} ${s} = ez_v${s}; `;return{declareVarying:e,assignVarying:n,getVarying:i}}getUniformComponents(t,e){const n=t%this._channels;let i="";for(let s=0;s<e;s++)i+=Lt[n+s];return i}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 Lt=["r","g","b","a"];class f extends u.Mesh{constructor(t,e,n={},i){if(!t)throw new Error('"geometry" is mandatory.');if(!e)throw new Error('"material" is mandatory.');const{allowsEuler:s,renderer:o,createEntities:a}=n;super(t,null),this.type="InstancedMesh2",this.isInstancedMesh2=!0,this.instances=null,this.instanceIndex=null,this.colorsTexture=null,this.morphTexture=null,this.boneTexture=null,this.uniformsTexture=null,this.boundingBox=null,this.boundingSphere=null,this.bvh=null,this.customSort=null,this.raycastOnlyFrustum=!1,this.LODinfo=null,this.autoUpdate=!0,this.bindMode=u.AttachedBindMode,this.bindMatrix=null,this.bindMatrixInverse=null,this.skeleton=null,this.autoUpdateBVH=!0,this.onFrustumEnter=null,this._renderer=null,this._instancesCount=0,this._instancesArrayCount=0,this._perObjectFrustumCulled=!0,this._sortObjects=!1,this._indexArrayNeedsUpdate=!1,this._useOpacity=!1,this._currentMaterial=null,this._customProgramCacheKeyBase=null,this._onBeforeCompileBase=null,this._definesBase=null,this._freeIds=[],this.isInstancedMesh=!0,this.instanceMatrix=new u.InstancedBufferAttribute(new Float32Array(0),16),this.instanceColor=null,this._customProgramCacheKey=()=>`ez_${!!this.colorsTexture}_${this._useOpacity}_${!!this.boneTexture}_${!!this.uniformsTexture}_${this._customProgramCacheKeyBase.call(this._currentMaterial)}`,this._onBeforeCompile=(h,l)=>{if(this._onBeforeCompileBase&&this._onBeforeCompileBase.call(this._currentMaterial,h,l),h.defines={...h.defines},h.defines.USE_INSTANCING_INDIRECT="",h.uniforms.matricesTexture={value:this.matricesTexture},this.uniformsTexture){h.uniforms.uniformsTexture={value:this.uniformsTexture};const{vertex:d,fragment:p}=this.uniformsTexture.getUniformsGLSL("uniformsTexture","instanceIndex","uint");h.vertexShader=h.vertexShader.replace("void main() {",d),h.fragmentShader=h.fragmentShader.replace("void main() {",p)}this.colorsTexture&&h.fragmentShader.includes("#include <color_pars_fragment>")&&(h.defines.USE_INSTANCING_COLOR_INDIRECT="",h.uniforms.colorsTexture={value:this.colorsTexture},h.vertexShader=h.vertexShader.replace("<color_vertex>","<instanced_color_vertex>"),h.vertexColors&&(h.defines.USE_VERTEX_COLOR=""),h.defines.USE_COLOR_ALPHA=""),this.boneTexture&&(h.defines.USE_SKINNING="",h.defines.USE_INSTANCING_SKINNING="",h.uniforms.bindMatrix={value:this.bindMatrix},h.uniforms.bindMatrixInverse={value:this.bindMatrixInverse},h.uniforms.bonesPerInstance={value:this.skeleton.bones.length},h.uniforms.boneTexture={value:this.boneTexture})};const c=n.capacity>0?n.capacity:Ut;this._renderer=o,this._capacity=c,this._parentLOD=i,this._geometry=t,this.material=e,this._allowsEuler=s??!1,this._tempInstance=new st(this,-1,s),this.availabilityArray=i?.availabilityArray??new Array(c*2),this._createEntities=a,this.initLastRenderInfo(),this.initIndexAttribute(),this.initMatricesTexture()}get capacity(){return this._capacity}get instancesCount(){return this._instancesCount}get perObjectFrustumCulled(){return this._perObjectFrustumCulled}set perObjectFrustumCulled(t){this._perObjectFrustumCulled=t,this._indexArrayNeedsUpdate=!0}get sortObjects(){return this._sortObjects}set sortObjects(t){this._sortObjects=t,this._indexArrayNeedsUpdate=!0}get geometry(){return this._geometry}set geometry(t){this._geometry=t,this.patchGeometry(t)}onBeforeShadow(t,e,n,i,s,o,a){this.patchMaterial(t,o),this.updateTextures(t,o);const c=t.info.render.frame;this.instanceIndex&&this.autoUpdate&&!this.frustumCullingAlreadyPerformed(c,n,i)&&this.performFrustumCulling(i,n),this.count!==0&&(this.instanceIndex.update(this._renderer,this.count),this.bindTextures(t,o))}onBeforeRender(t,e,n,i,s,o){if(this.patchMaterial(t,s),this.updateTextures(t,s),!this.instanceIndex){this._renderer=t;return}const a=t.info.render.frame;this.autoUpdate&&!this.frustumCullingAlreadyPerformed(a,n,null)&&this.performFrustumCulling(n),this.count!==0&&(this.instanceIndex.update(this._renderer,this.count),this.bindTextures(t,s))}onAfterShadow(t,e,n,i,s,o,a){this.unpatchMaterial(t,o)}onAfterRender(t,e,n,i,s,o){this.unpatchMaterial(t,s),!(this.instanceIndex||o&&!this.isLastGroup(o.materialIndex))&&this.initIndexAttribute()}updateTextures(t,e){const n=t.properties.get(e);this.matricesTexture.update(t,n,"matricesTexture"),this.colorsTexture?.update(t,n,"colorsTexture"),this.uniformsTexture?.update(t,n,"uniformsTexture"),this.boneTexture?.update(t,n,"boneTexture")}bindTextures(t,e){const n=t.properties.get(e),i=n.uniforms;if(!i)return;const s=n.currentProgram,o=s?.program;if(!o)return;const a=t.getContext(),c=s.getUniforms().map,h=a.getParameter(a.CURRENT_PROGRAM);t.state.useProgram(o),this.matricesTexture.bindToProgram(t,a,c,i,"matricesTexture"),this.colorsTexture?.bindToProgram(t,a,c,i,"colorsTexture"),this.uniformsTexture?.bindToProgram(t,a,c,i,"uniformsTexture"),this.boneTexture?.bindToProgram(t,a,c,i,"boneTexture"),t.state.useProgram(h)}isLastGroup(t){const e=this.material;for(let n=e.length-1;n>=t;n--)if(e[n].visible)return n===t}initIndexAttribute(){if(!this._renderer){this.count=0;return}const t=this._renderer.getContext(),e=this._capacity,n=new Uint32Array(e);for(let i=0;i<e;i++)n[i]=i;this.instanceIndex=new vt(t,t.UNSIGNED_INT,1,4,n),this._geometry.setAttribute("instanceIndex",this.instanceIndex)}initLastRenderInfo(){this._parentLOD||(this._lastRenderInfo={frame:-1,camera:null,shadowCamera:null})}initMatricesTexture(){this._parentLOD||(this.matricesTexture=new j(Float32Array,4,4,this._capacity))}initColorsTexture(){this._parentLOD||(this.colorsTexture=new j(Float32Array,4,1,this._capacity),this.colorsTexture.colorSpace=u.ColorManagement.workingColorSpace,this.colorsTexture._data.fill(1),this.materialsNeedsUpdate())}materialsNeedsUpdate(){if(this.material.isMaterial){this.material.needsUpdate=!0;return}for(const t of this.material)t.needsUpdate=!0}patchGeometry(t){const e=t.getAttribute("instanceIndex");if(e){if(e===this.instanceIndex)return;console.warn("The geometry has been cloned because it was already used."),t=t.clone(),t.deleteAttribute("instanceIndex")}this.instanceIndex&&t.setAttribute("instanceIndex",this.instanceIndex)}patchMaterial(t,e){this._currentMaterial=e,this._customProgramCacheKeyBase=e.customProgramCacheKey,this._onBeforeCompileBase=e.onBeforeCompile,this._definesBase=e.defines,e.customProgramCacheKey=this._customProgramCacheKey,e.onBeforeCompile=this._onBeforeCompile,Tt(this,t,e)}unpatchMaterial(t,e){this._currentMaterial=null,It(t),e.defines=this._definesBase,e.onBeforeCompile=this._onBeforeCompileBase,e.customProgramCacheKey=this._customProgramCacheKeyBase,this._onBeforeCompileBase=null,this._customProgramCacheKeyBase=null,this._definesBase=null}computeBVH(t={}){this.bvh||(this.bvh=new At(this,t.margin,t.getBBoxFromBSphere,t.accurateCulling)),this.bvh.clear(),this.bvh.create()}disposeBVH(){this.bvh=null}setMatrixAt(t,e){if(e.toArray(this.matricesTexture._data,t*16),this.instances){const n=this.instances[t];e.decompose(n.position,n.quaternion,n.scale)}this.matricesTexture.enqueueUpdate(t),this.bvh&&this.autoUpdateBVH&&this.bvh.move(t)}getMatrixAt(t,e=Dt){return e.fromArray(this.matricesTexture._data,t*16)}getPositionAt(t,e=Bt){const n=t*16,i=this.matricesTexture._data;return e.x=i[n+12],e.y=i[n+13],e.z=i[n+14],e}getPositionAndMaxScaleOnAxisAt(t,e){const n=t*16,i=this.matricesTexture._data,s=i[n+0],o=i[n+1],a=i[n+2],c=s*s+o*o+a*a,h=i[n+4],l=i[n+5],d=i[n+6],p=h*h+l*l+d*d,x=i[n+8],m=i[n+9],_=i[n+10],g=x*x+m*m+_*_;return e.x=i[n+12],e.y=i[n+13],e.z=i[n+14],Math.sqrt(Math.max(c,p,g))}applyMatrixAtToSphere(t,e,n,i){const s=t*16,o=this.matricesTexture._data,a=o[s+0],c=o[s+1],h=o[s+2],l=o[s+3],d=o[s+4],p=o[s+5],x=o[s+6],m=o[s+7],_=o[s+8],g=o[s+9],v=o[s+10],w=o[s+11],S=o[s+12],M=o[s+13],O=o[s+14],L=o[s+15],T=e.center,y=n.x,b=n.y,A=n.z,U=1/(l*y+m*b+w*A+L);T.x=(a*y+d*b+_*A+S)*U,T.y=(c*y+p*b+g*A+M)*U,T.z=(h*y+x*b+v*A+O)*U;const F=a*a+c*c+h*h,E=d*d+p*p+x*x,R=_*_+g*g+v*v;e.radius=i*Math.sqrt(Math.max(F,E,R))}setVisibilityAt(t,e){this.availabilityArray[t*2]=e,this._indexArrayNeedsUpdate=!0}getVisibilityAt(t){return this.availabilityArray[t*2]}setActiveAt(t,e){this.availabilityArray[t*2+1]=e,this._indexArrayNeedsUpdate=!0}getActiveAt(t){return this.availabilityArray[t*2+1]}getActiveAndVisibilityAt(t){const e=t*2,n=this.availabilityArray;return n[e]&&n[e+1]}setActiveAndVisibilityAt(t,e){const n=t*2,i=this.availabilityArray;i[n]=e,i[n+1]=e,this._indexArrayNeedsUpdate=!0}setColorAt(t,e){this.colorsTexture===null&&this.initColorsTexture(),e.isColor?e.toArray(this.colorsTexture._data,t*4):mt.set(e).toArray(this.colorsTexture._data,t*4),this.colorsTexture.enqueueUpdate(t)}getColorAt(t,e=mt){return e.fromArray(this.colorsTexture._data,t*4)}setOpacityAt(t,e){this._useOpacity||(this.colorsTexture===null?this.initColorsTexture():this.materialsNeedsUpdate(),this._useOpacity=!0),this.colorsTexture._data[t*4+3]=e,this.colorsTexture.enqueueUpdate(t)}getOpacityAt(t){return this._useOpacity?this.colorsTexture._data[t*4+3]:1}copyTo(t,e){this.getMatrixAt(t,e.matrix).decompose(e.position,e.quaternion,e.scale)}computeBoundingBox(){const t=this._geometry,e=this._instancesArrayCount;this.boundingBox??=new u.Box3,t.boundingBox===null&&t.computeBoundingBox();const n=t.boundingBox,i=this.boundingBox;i.makeEmpty();for(let s=0;s<e;s++)this.getActiveAt(s)&&(pt.copy(n).applyMatrix4(this.getMatrixAt(s)),i.union(pt))}computeBoundingSphere(){const t=this._geometry,e=this._instancesArrayCount;this.boundingSphere??=new u.Sphere,t.boundingSphere===null&&t.computeBoundingSphere();const n=t.boundingSphere,i=this.boundingSphere;i.makeEmpty();for(let s=0;s<e;s++)this.getActiveAt(s)&&(xt.copy(n).applyMatrix4(this.getMatrixAt(s)),i.union(xt))}clone(t){const e={capacity:this._capacity,renderer:this._renderer,allowsEuler:this._allowsEuler,createEntities:this._createEntities};return new this.constructor(this.geometry,this.material,e).copy(this,t)}copy(t,e){return super.copy(t,e),this.count=t._capacity,this._instancesCount=t._instancesCount,this._instancesArrayCount=t._instancesArrayCount,this._capacity=t._capacity,t.boundingBox!==null&&(this.boundingBox=t.boundingBox.clone()),t.boundingSphere!==null&&(this.boundingSphere=t.boundingSphere.clone()),this.matricesTexture=t.matricesTexture.clone(),this.matricesTexture.image.data=this.matricesTexture.image.data.slice(),t.colorsTexture!==null&&(this.colorsTexture=t.colorsTexture.clone(),this.colorsTexture.image.data=this.colorsTexture.image.data.slice()),t.uniformsTexture!==null&&(this.uniformsTexture=t.uniformsTexture.clone(),this.uniformsTexture.image.data=this.uniformsTexture.image.data.slice()),t.morphTexture!==null&&(this.morphTexture=t.morphTexture.clone(),this.morphTexture.image.data=this.morphTexture.image.data.slice()),t.boneTexture!==null&&(this.boneTexture=t.boneTexture.clone(),this.boneTexture.image.data=this.boneTexture.image.data.slice()),this}dispose(){this.dispatchEvent({type:"dispose"}),this.matricesTexture.dispose(),this.colorsTexture?.dispose(),this.morphTexture?.dispose(),this.boneTexture?.dispose(),this.uniformsTexture?.dispose()}updateMatrixWorld(t){super.updateMatrixWorld(t),this.bindMatrixInverse&&(this.bindMode===u.AttachedBindMode?this.bindMatrixInverse.copy(this.matrixWorld).invert():this.bindMode===u.DetachedBindMode?this.bindMatrixInverse.copy(this.bindMatrix).invert():console.warn("Unrecognized bindMode: "+this.bindMode))}}const Ut=1e3,pt=new u.Box3,xt=new u.Sphere,Dt=new u.Matrix4,mt=new u.Color,Bt=new u.Vector3;f.prototype.resizeBuffers=function(r){const t=this._capacity;this._capacity=r;const e=Math.min(r,t);if(this.instanceIndex){const n=new Uint32Array(r);n.set(new Uint32Array(this.instanceIndex.array.buffer,0,e)),this.instanceIndex.array=n}if(this.LODinfo){for(const n of this.LODinfo.objects)if(n._capacity=r,n.instanceIndex){const i=new Uint32Array(r);i.set(new Uint32Array(n.instanceIndex.array.buffer,0,e)),n.instanceIndex.array=i}}if(this.availabilityArray.length=r*2,this.matricesTexture.resize(r),this.colorsTexture&&(this.colorsTexture.resize(r),r>t&&this.colorsTexture._data.fill(1,t*4)),this.morphTexture){const n=this.morphTexture.image.data,i=n.length/t;this.morphTexture.dispose(),this.morphTexture=new u.DataTexture(new Float32Array(i*r),i,r,u.RedFormat,u.FloatType),this.morphTexture.image.data.set(n)}return this.uniformsTexture?.resize(r),this};f.prototype.setInstancesArrayCount=function(r){if(r<this._instancesArrayCount){const e=this.bvh;if(e)for(let n=this._instancesArrayCount-1;n>=r;n--)this.getActiveAt(n)&&e.delete(n);this._instancesArrayCount=r;return}if(r>this._capacity){let e=this._capacity+(this._capacity>>1)+512;for(;e<r;)e+=(e>>1)+512;this.resizeBuffers(e)}const t=this._instancesArrayCount;this._instancesArrayCount=r,this._createEntities&&this.createEntities(t)};function Ft(r){const t={get:e=>e.depthSort,aux:new Array(r._capacity),reversed:!1};return function(n){t.reversed=!!r.material?.transparent,r._capacity>t.aux.length&&(t.aux.length=r._capacity);let i=1/0,s=-1/0;for(const{depth:c}of n)c>s&&(s=c),c<i&&(i=c);const o=s-i,a=(2**32-1)/o;for(const c of n)c.depthSort=(c.depth-i)*a;St.radixSort(n,t)}}function ot(r,t){return r.depth-t.depth}function at(r,t){return t.depth-r.depth}class wt{constructor(){this.array=[],this.pool=[]}push(t,e){const n=this.pool,i=this.array,s=i.length;s>=n.length&&n.push({depth:null,index:null,depthSort:null});const o=n[s];o.depth=t,o.index=e,i.push(o)}reset(){this.array.length=0}}const Q=new u.Frustum,C=new wt,B=new u.Matrix4,P=new u.Matrix4,et=new u.Vector3,z=new u.Vector3,N=new u.Vector3,Et=new u.Vector3,I=new u.Sphere;f.prototype.performFrustumCulling=function(r,t=r){const e=this._parentLOD??this,n=e.LODinfo;let i;if(n){i=r!==t?n.shadowRender??n.render:n.render;for(const o of n.objects)o.count=0}else(e._perObjectFrustumCulled||e._sortObjects)&&(e.count=0);e._instancesArrayCount!==0&&(i?.levels.length>0?e.frustumCullingLOD(i,r,t):e.frustumCulling(r))};f.prototype.updateLastRenderInfo=function(r,t,e){const n=this._lastRenderInfo;n.frame=r,n.camera=t,n.shadowCamera=e};f.prototype.frustumCullingAlreadyPerformed=function(r,t,e){const n=this._lastRenderInfo;return n.frame===r&&n.camera===t&&n.shadowCamera===e?!0:(this.updateLastRenderInfo(r,t,e),!1)};f.prototype.frustumCulling=function(r){const t=this._sortObjects,e=this._perObjectFrustumCulled,n=this.instanceIndex.array;if(this.instanceIndex._needsUpdate=!0,!e&&!t){this.updateIndexArray();return}if(t&&(P.copy(this.matrixWorld).invert(),z.setFromMatrixPosition(r.matrixWorld).applyMatrix4(P),et.set(0,0,-1).transformDirection(r.matrixWorld).transformDirection(P)),e?(B.multiplyMatrices(r.projectionMatrix,r.matrixWorldInverse).multiply(this.matrixWorld),this.bvh?this.BVHCulling(r):this.linearCulling(r)):this.updateRenderList(),t){const i=this.customSort;i===null?C.array.sort(this.material?.transparent?at:ot):i(C.array);const s=C.array,o=s.length;for(let a=0;a<o;a++)n[a]=s[a].index;this.count=o,C.reset()}};f.prototype.updateIndexArray=function(){if(!this._indexArrayNeedsUpdate)return;const r=this.instanceIndex.array,t=this._instancesArrayCount;let e=0;for(let n=0;n<t;n++)this.getActiveAndVisibilityAt(n)&&(r[e++]=n);this.count=e,this._indexArrayNeedsUpdate=!1};f.prototype.updateRenderList=function(){const r=this._instancesArrayCount;for(let t=0;t<r;t++)if(this.getActiveAndVisibilityAt(t)){const e=this.getPositionAt(t).sub(z).dot(et);C.push(e,t)}};f.prototype.BVHCulling=function(r){const t=this.instanceIndex.array,e=this._instancesArrayCount,n=this._sortObjects,i=this.onFrustumEnter;let s=0;this.bvh.frustumCulling(B,o=>{const a=o.object;if(a<e&&this.getVisibilityAt(a)&&(!i||i(a,r)))if(n){const c=this.getPositionAt(a).sub(z).dot(et);C.push(c,a)}else t[s++]=a}),this.count=s};f.prototype.linearCulling=function(r){const t=this.instanceIndex.array;this.geometry.boundingSphere||this.geometry.computeBoundingSphere();const e=this._geometry.boundingSphere,n=e.radius,i=e.center,s=this._instancesArrayCount,o=i.x===0&&i.y===0&&i.z===0,a=this._sortObjects,c=this.onFrustumEnter;let h=0;Q.setFromProjectionMatrix(B);for(let l=0;l<s;l++)if(this.getActiveAndVisibilityAt(l)){if(o){const d=this.getPositionAndMaxScaleOnAxisAt(l,I.center);I.radius=n*d}else this.applyMatrixAtToSphere(l,I,i,n);if(Q.intersectsSphere(I)&&(!c||c(l,r)))if(a){const d=Et.subVectors(I.center,z).dot(et);C.push(d,l)}else t[h++]=l}this.count=h};f.prototype.frustumCullingLOD=function(r,t,e){const{count:n,levels:i}=r;for(let c=0;c<i.length;c++){if(!i[c].object.instanceIndex)return;n[c]=0,i[c].object.instanceIndex._needsUpdate=!0}const o=!(t!==e)&&this._sortObjects;B.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse).multiply(this.matrixWorld),P.copy(this.matrixWorld).invert(),z.setFromMatrixPosition(t.matrixWorld).applyMatrix4(P),N.setFromMatrixPosition(e.matrixWorld).applyMatrix4(P);const a=r.levels.map(c=>c.object.instanceIndex.array);if(this.bvh?this.BVHCullingLOD(r,a,o,t,e):this.linearCullingLOD(r,a,o,t,e),o){const c=this.customSort,h=C.array;let l=0,d=i[1].distance;c===null?h.sort(i[0].object.material?.transparent?at:ot):c(h);for(let p=0,x=h.length;p<x;p++){const m=h[p];m.depth>d&&(l++,d=i[l+1]?.distance??1/0),a[l][n[l]++]=m.index}C.reset()}for(let c=0;c<i.length;c++){const h=i[c].object;h.count=n[c]}};f.prototype.BVHCullingLOD=function(r,t,e,n,i){const{count:s,levels:o}=r,a=this._instancesArrayCount,c=this.onFrustumEnter;e?this.bvh.frustumCulling(B,h=>{const l=h.object;if(l<a&&this.getVisibilityAt(l)&&(!c||c(l,n,i))){const d=this.getPositionAt(l).distanceToSquared(N);C.push(d,l)}}):this.bvh.frustumCullingLOD(B,N,o,(h,l)=>{const d=h.object;if(d<a&&this.getVisibilityAt(d)){if(l===null){const p=this.getPositionAt(d).distanceToSquared(N);l=this.getObjectLODIndexForDistance(o,p)}(!c||c(d,n,i,l))&&(t[l][s[l]++]=d)}})};f.prototype.linearCullingLOD=function(r,t,e,n,i){const{count:s,levels:o}=r;this.geometry.boundingSphere||this.geometry.computeBoundingSphere();const a=this._geometry.boundingSphere,c=a.radius,h=a.center,l=this._instancesArrayCount,d=h.x===0&&h.y===0&&h.z===0,p=this.onFrustumEnter;Q.setFromProjectionMatrix(B);for(let x=0;x<l;x++)if(this.getActiveAndVisibilityAt(x)){if(d){const m=this.getPositionAndMaxScaleOnAxisAt(x,I.center);I.radius=c*m}else this.applyMatrixAtToSphere(x,I,h,c);if(Q.intersectsSphere(I))if(e){if(!p||p(x,n,i)){const m=I.center.distanceToSquared(N);C.push(m,x)}}else{const m=I.center.distanceToSquared(N),_=this.getObjectLODIndexForDistance(o,m);(!p||p(x,n,i,_))&&(t[_][s[_]++]=x)}}};f.prototype.clearTempInstance=function(r){const t=this._tempInstance;return t.id=r,this.clearInstance(t)};f.prototype.clearTempInstancePosition=function(r){const t=this._tempInstance;return t.id=r,t.position.set(0,0,0),t};f.prototype.clearInstance=function(r){return r.position.set(0,0,0),r.scale.set(1,1,1),r.quaternion.identity(),r};f.prototype.updateInstances=function(r){const t=this._instancesArrayCount,e=this.instances;for(let n=0;n<t;n++){if(!this.getActiveAt(n))continue;const i=e?e[n]:this.clearTempInstance(n);r(i,n),i.updateMatrix()}return this};f.prototype.updateInstancesPosition=function(r){const t=this._instancesArrayCount,e=this.instances;for(let n=0;n<t;n++){if(!this.getActiveAt(n))continue;const i=e?e[n]:this.clearTempInstancePosition(n);r(i,n),i.updateMatrixPosition()}return this};f.prototype.createEntities=function(r){const t=this._instancesArrayCount;if(!this.instances)this.instances=new Array(t);else if(this.instances.length<t)this.instances.length=t;else return this;const e=this.instances;for(let n=r;n<t;n++)e[n]||(e[n]=new st(this,n,this._allowsEuler));return this};f.prototype.addInstances=function(r,t){!t&&this.bvh&&console.warn("InstancedMesh2: if `computeBVH()` has already been called, it is better to valorize the instances in the `onCreation` callback for better performance.");const e=this._freeIds;if(e.length>0){let s=-1;const o=Math.min(e.length,r),a=e.length-o;for(let c=e.length-1;c>=a;c--){const h=e[c];h>s&&(s=h),this.addInstance(h,t)}e.length-=o,r-=o,this._instancesArrayCount=Math.max(s+1,this._instancesArrayCount)}const n=this._instancesArrayCount,i=n+r;this.setInstancesArrayCount(i);for(let s=n;s<i;s++)this.addInstance(s,t);return this};f.prototype.addInstance=function(r,t){this._instancesCount++,this.setActiveAndVisibilityAt(r,!0);const e=this.instances?this.clearInstance(this.instances[r]):this.clearTempInstance(r);t?(t(e,r),e.updateMatrix()):e.setMatrixIdentity(),this.bvh?.insert(r)};f.prototype.removeInstances=function(...r){const t=this._freeIds,e=this.bvh;for(const n of r)n<this._instancesArrayCount&&this.getActiveAt(n)&&(this.setActiveAt(n,!1),t.push(n),e?.delete(n),this._instancesCount--);for(let n=this._instancesArrayCount-1;n>=0&&!this.getActiveAt(n);n--)this._instancesArrayCount--;return this};f.prototype.clearInstances=function(){if(this._instancesCount=0,this._instancesArrayCount=0,this._freeIds.length=0,this.bvh?.clear(),this.LODinfo)for(const r of this.LODinfo.objects)r.count=0;return this};f.prototype.getObjectLODIndexForDistance=function(r,t){for(let e=r.length-1;e>0;e--){const n=r[e],i=n.distance-n.distance*n.hysteresis;if(t>=i)return e}return 0};f.prototype.setFirstLODDistance=function(r){if(this._parentLOD)throw new Error("Cannot create LOD for this InstancedMesh2.");return this.LODinfo||(this.LODinfo={render:null,shadowRender:null,objects:[this]}),this.LODinfo.render||(this.LODinfo.render={levels:[{distance:r,hysteresis:0,object:this}],count:[0]}),this};f.prototype.addLOD=function(r,t,e=0,n=0){if(this._parentLOD)throw new Error("Cannot create LOD for this InstancedMesh2.");if(!this.LODinfo?.render&&e===0)throw new Error('Cannot set distance to 0 for the first LOD. Call "setFirstLODDistance" method before use "addLOD".');return this.setFirstLODDistance(0),this.addLevel(this.LODinfo.render,r,t,e,n),this};f.prototype.addShadowLOD=function(r,t=0,e=0){if(this._parentLOD)throw new Error("Cannot create LOD for this InstancedMesh2.");this.LODinfo||(this.LODinfo={render:null,shadowRender:null,objects:[this]}),this.LODinfo.shadowRender||(this.LODinfo.shadowRender={levels:[],count:[]});const n=this.addLevel(this.LODinfo.shadowRender,r,null,t,e);return n.castShadow=!0,this.castShadow=!0,this};f.prototype.addLevel=function(r,t,e,n,i){const s=this.LODinfo.objects,o=r.levels;let a,c;n=n**2;const h=s.findIndex(l=>l.geometry===t);if(h===-1){const l={capacity:this._capacity,renderer:this._renderer};c=new f(t,e??new u.ShaderMaterial,l,this),c.frustumCulled=!1,this.patchLevel(c),s.push(c),this.add(c)}else c=s[h],e&&(c.material=e);for(a=0;a<o.length&&!(n<o[a].distance);a++);return o.splice(a,0,{distance:n,hysteresis:i,object:c}),r.count.push(0),c};f.prototype.updateLevel=function(r,t,e,n){if(!r)throw new Error("Render list is invalid.");const i=r.levels[t];if(!i)throw new Error("Cannot update an empty LOD.");if(e!=null&&!Number.isNaN(e)){const s=e**2;i.distance=s}return n!=null&&!Number.isNaN(n)&&(i.hysteresis=n),this};f.prototype.updateLOD=function(r,t,e){const n=this?.LODinfo?.render;if(r===0)throw new Error("Cannot change distance for LOD0. It is the main mesh and must stay at 0.");return this.updateLevel(n,r,t,e)};f.prototype.updateShadowLOD=function(r,t,e){return this.updateLevel(this.LODinfo?.shadowRender,r,t,e)};f.prototype.updateAllLevels=function(r,t,e){if(!r?.levels)throw new Error("Invalid LOD list.");const n=r.levels,i=this.LODinfo?.render===r,s=i?1:0;i&&(n[0].distance=0);const o=t?.length>0;let a=[];o&&(a=i&&t[0]===0?t.slice(1,Math.min(n.length,t.length)):t.slice(0,Math.min(n.length-s,t.length)),a.every((h,l)=>{if(l>0&&h<=a[l-1])throw new Error(`LOD distances must be strictly increasing: d[${l-1}]=${a[l-1]} < d[${l}]=${h}`);return!0}));const c=o?a.length:n.length-s;for(let h=0;h<c;h++){const l=o?a[h]:void 0,d=Array.isArray(e)?e[h]:e;this.updateLevel(r,s+h,l,d)}return this};f.prototype.updateAllLOD=function(r,t){return this.updateAllLevels(this.LODinfo?.render,r,t)};f.prototype.updateAllShadowLOD=function(r,t){return this.updateAllLevels(this.LODinfo?.shadowRender,r,t)};f.prototype.disposeLOD=function(r){r.geometry.dispose();const t=r.material;if(Array.isArray(t))for(const e of t)e.dispose();else t.dispose()};f.prototype.removeLOD=function(r,t=!0){const e=this.LODinfo,n=e?.render;if(!n?.levels)throw new Error("Invalid LOD list.");const i=n.levels.length;if(r<0||r>=i)throw new Error("Level index OOB");if(i>1&&r===0)throw new Error("Cannot remove LOD0 while others exist");const[s]=n.levels.splice(r,1);n.count?.splice?.(r,1),n.levels.length<=1&&(e.render=null);const o=s.object,a=this.LODinfo?.shadowRender;if(a?.levels&&r<a.levels.length&&(a.levels.splice(r,1),a.count?.splice?.(r,1),a.levels.length===0&&(this.LODinfo.shadowRender=null)),t&&o!==this)try{this.remove(o);const c=e.objects?.indexOf(o)??-1;c!==-1&&e.objects.splice(c,1),this.disposeLOD(o)}catch(c){console.error(c)}return this};f.prototype.patchLevel=function(r){Object.defineProperty(r,"renderOrder",{get(){return this._parentLOD.renderOrder}}),Object.defineProperty(r,"_lastRenderInfo",{get(){return this._parentLOD._lastRenderInfo}}),Object.defineProperty(r,"matricesTexture",{get(){return this._parentLOD.matricesTexture}}),Object.defineProperty(r,"colorsTexture",{get(){return this._parentLOD.colorsTexture}}),Object.defineProperty(r,"uniformsTexture",{get(){return this._parentLOD.uniformsTexture}}),Object.defineProperty(r,"morphTexture",{get(){return this._parentLOD.morphTexture}}),Object.defineProperty(r,"boneTexture",{get(){return this._parentLOD.boneTexture}}),Object.defineProperty(r,"skeleton",{get(){return this._parentLOD.skeleton}}),Object.defineProperty(r,"bindMatrixInverse",{get(){return this._parentLOD.bindMatrixInverse}}),Object.defineProperty(r,"bindMatrix",{get(){return this._parentLOD.bindMatrix}})};const Rt=new u.Mesh;f.prototype.getMorphAt=function(r,t=Rt){const e=t.morphTargetInfluences,n=this.morphTexture.source.data.data,i=e.length+1,s=r*i+1;for(let o=0;o<e.length;o++)e[o]=n[s+o];return t};f.prototype.setMorphAt=function(r,t){const e=t.morphTargetInfluences,n=e.length+1;this.morphTexture===null&&!this._parentLOD&&(this.morphTexture=new u.DataTexture(new Float32Array(n*this._capacity),n,this._capacity,u.RedFormat,u.FloatType));const i=this.morphTexture.source.data.data;let s=0;for(const c of e)s+=c;const o=this._geometry.morphTargetsRelative?1:1-s,a=n*r;i[a]=o,i.set(e,a+1),this.morphTexture.needsUpdate=!0};const it=[],J=new u.Mesh,Pt=new u.Ray,_t=new u.Vector3,gt=new u.Vector3,yt=new u.Matrix4,bt=new u.Sphere;f.prototype.raycast=function(r,t){if(this._parentLOD||!this.material||this._instancesArrayCount===0||!this.instanceIndex)return;J.geometry=this._geometry,J.material=this.material;const e=r.ray,n=r.near,i=r.far;yt.copy(this.matrixWorld).invert(),gt.setFromMatrixScale(this.matrixWorld),_t.copy(r.ray.direction).multiply(gt);const s=_t.length();r.ray=Pt.copy(r.ray).applyMatrix4(yt),r.near/=s,r.far/=s,this.raycastInstances(r,t),r.ray=e,r.near=n,r.far=i};f.prototype.raycastInstances=function(r,t){if(this.bvh)this.bvh.raycast(r,e=>this.checkObjectIntersection(r,e,t));else{if(this.boundingSphere===null&&this.computeBoundingSphere(),bt.copy(this.boundingSphere),!r.ray.intersectsSphere(bt))return;const e=this.instanceIndex.array,i=this.raycastOnlyFrustum&&this._perObjectFrustumCulled?this.count:this._instancesArrayCount;for(let s=0;s<i;s++)this.checkObjectIntersection(r,e[s],t)}};f.prototype.checkObjectIntersection=function(r,t,e){if(!(t>this._instancesArrayCount||!this.getActiveAndVisibilityAt(t))){this.getMatrixAt(t,J.matrixWorld),J.raycast(r,it);for(const n of it)n.instanceId=t,n.object=this,e.push(n);it.length=0}};f.prototype.initSkeleton=function(r,t=!0){if(r&&this.skeleton!==r&&!this._parentLOD){const e=r.bones;if(this.skeleton=r,this.bindMatrix=new u.Matrix4,this.bindMatrixInverse=new u.Matrix4,this.boneTexture=new j(Float32Array,4,4*e.length,this._capacity),t)for(const n of e)n.matrixAutoUpdate=!1,n.matrixWorldAutoUpdate=!1;this.materialsNeedsUpdate()}};f.prototype.setBonesAt=function(r,t=!0,e){const n=this.skeleton;if(!n)throw new Error('"setBonesAt" cannot be called before "initSkeleton"');const i=n.bones,s=n.boneInverses;for(let o=0,a=i.length;o<a;o++){const c=i[o];t&&(e?.has(c.name)||c.updateMatrix(),c.matrixWorld.multiplyMatrices(c.parent.matrixWorld,c.matrix)),this.multiplyBoneMatricesAt(r,o,c.matrixWorld,s[o])}this.boneTexture.enqueueUpdate(r)};f.prototype.multiplyBoneMatricesAt=function(r,t,e,n){const i=(r*this.skeleton.bones.length+t)*16,s=e.elements,o=n.elements,a=this.boneTexture._data,c=s[0],h=s[4],l=s[8],d=s[12],p=s[1],x=s[5],m=s[9],_=s[13],g=s[2],v=s[6],w=s[10],S=s[14],M=s[3],O=s[7],L=s[11],T=s[15],y=o[0],b=o[4],A=o[8],U=o[12],F=o[1],E=o[5],R=o[9],$=o[13],V=o[2],G=o[6],k=o[10],q=o[14],W=o[3],K=o[7],Y=o[11],H=o[15];a[i+0]=c*y+h*F+l*V+d*W,a[i+4]=c*b+h*E+l*G+d*K,a[i+8]=c*A+h*R+l*k+d*Y,a[i+12]=c*U+h*$+l*q+d*H,a[i+1]=p*y+x*F+m*V+_*W,a[i+5]=p*b+x*E+m*G+_*K,a[i+9]=p*A+x*R+m*k+_*Y,a[i+13]=p*U+x*$+m*q+_*H,a[i+2]=g*y+v*F+w*V+S*W,a[i+6]=g*b+v*E+w*G+S*K,a[i+10]=g*A+v*R+w*k+S*Y,a[i+14]=g*U+v*$+w*q+S*H,a[i+3]=M*y+O*F+L*V+T*W,a[i+7]=M*b+O*E+L*G+T*K,a[i+11]=M*A+O*R+L*k+T*Y,a[i+15]=M*U+O*$+L*q+T*H};f.prototype.getUniformAt=function(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)};f.prototype.setUniformAt=function(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)};f.prototype.initUniformsPerInstance=function(r){if(!this._parentLOD){const{channels:t,pixelsPerInstance:e,uniformMap:n,fetchInFragmentShader:i}=this.getUniformSchemaResult(r);this.uniformsTexture=new j(Float32Array,t,e,this._capacity,n,i),this.materialsNeedsUpdate()}};f.prototype.getUniformSchemaResult=function(r){let t=0;const e=new Map,n=[],i=r.vertex??{},s=r.fragment??{};let o=!0;for(const l in i){const d=i[l],p=this.getUniformSize(d);t+=p,n.push({name:l,type:d,size:p}),o=!1}for(const l in s)if(!i[l]){const d=s[l],p=this.getUniformSize(d);t+=p,n.push({name:l,type:d,size:p})}n.sort((l,d)=>d.size-l.size);const a=[];for(const{name:l,size:d,type:p}of n){const x=this.getUniformOffset(d,a);e.set(l,{offset:x,size:d,type:p})}const c=Math.ceil(t/4);return{channels:Math.min(t,4),pixelsPerInstance:c,uniformMap:e,fetchInFragmentShader:o}};f.prototype.getUniformOffset=function(r,t){if(r<4){for(let n=0;n<t.length;n++)if(t[n]+r<=4){const i=n*4+t[n];return t[n]+=r,i}}const e=t.length*4;for(;r>0;r-=4)t.push(r);return e};f.prototype.getUniformSize=function(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}`)}};var Nt=`#ifdef USE_INSTANCING_INDIRECT\r attribute uint instanceIndex;\r uniform highp sampler2D matricesTexture; mat4 getInstancedMatrix() {\r int size = textureSize( matricesTexture, 0 ).x;\r int j = int( instanceIndex ) * 4;\r int x = j % size;\r int y = j / size;\r vec4 v1 = texelFetch( matricesTexture, ivec2( x, y ), 0 );\r vec4 v2 = texelFetch( matricesTexture, ivec2( x + 1, y ), 0 );\r vec4 v3 = texelFetch( matricesTexture, ivec2( x + 2, y ), 0 );\r vec4 v4 = texelFetch( matricesTexture, ivec2( x + 3, y ), 0 );\r return mat4( v1, v2, v3, v4 );\r }\r #endif`,jt=`#ifdef USE_INSTANCING_COLOR_INDIRECT\r uniform highp sampler2D colorsTexture; vec4 getColorTexture() {\r int size = textureSize( colorsTexture, 0 ).x;\r int j = int( instanceIndex );\r int x = j % size;\r int y = j / size;\r return texelFetch( colorsTexture, ivec2( x, y ), 0 );\r }\r #endif`,zt=`#ifdef USE_INSTANCING_INDIRECT\r mat4 instanceMatrix = getInstancedMatrix(); #ifdef USE_INSTANCING_COLOR_INDIRECT\r vColor *= getColorTexture();\r #endif\r #endif`,$t=`#ifdef USE_INSTANCING_COLOR_INDIRECT\r #ifdef USE_VERTEX_COLOR\r vColor = vec4( color );\r #else\r vColor = vec4( 1.0 );\r #endif\r #endif`,Vt=`#ifdef USE_SKINNING\r uniform mat4 bindMatrix;\r uniform mat4 bindMatrixInverse;\r uniform highp sampler2D boneTexture; #ifdef USE_INSTANCING_SKINNING\r uniform int bonesPerInstance;\r #endif mat4 getBoneMatrix( const in float i ) {\r int size = textureSize( boneTexture, 0 ).x; #ifdef USE_INSTANCING_SKINNING\r int j = ( bonesPerInstance * int( instanceIndex ) + int( i ) ) * 4;\r #else\r int j = int( i ) * 4;\r #endif int x = j % size;\r int y = j / size;\r vec4 v1 = texelFetch( boneTexture, ivec2( x, y ), 0 );\r vec4 v2 = texelFetch( boneTexture, ivec2( x + 1, y ), 0 );\r vec4 v3 = texelFetch( boneTexture, ivec2( x + 2, y ), 0 );\r vec4 v4 = texelFetch( boneTexture, ivec2( x + 3, y ), 0 );\r return mat4( v1, v2, v3, v4 );\r }\r #endif`;u.ShaderChunk.instanced_pars_vertex=Nt;u.ShaderChunk.instanced_color_pars_vertex=jt;u.ShaderChunk.instanced_vertex=zt;u.ShaderChunk.instanced_color_vertex=$t;function nt(r){return r.replace("#ifdef USE_INSTANCING","#if defined USE_INSTANCING || defined USE_INSTANCING_INDIRECT")}u.ShaderChunk.project_vertex=nt(u.ShaderChunk.project_vertex);u.ShaderChunk.worldpos_vertex=nt(u.ShaderChunk.worldpos_vertex);u.ShaderChunk.defaultnormal_vertex=nt(u.ShaderChunk.defaultnormal_vertex);u.ShaderChunk.batching_pars_vertex=u.ShaderChunk.batching_pars_vertex.concat(` #include <instanced_pars_vertex>`);u.ShaderChunk.color_pars_vertex=u.ShaderChunk.color_pars_vertex.concat(` #include <instanced_color_pars_vertex>`);u.ShaderChunk.batching_vertex=u.ShaderChunk.batching_vertex.concat(` #include <instanced_vertex>`);u.ShaderChunk.skinning_pars_vertex=Vt;u.ShaderChunk.morphinstance_vertex&&(u.ShaderChunk.morphinstance_vertex=u.ShaderChunk.morphinstance_vertex.replaceAll("gl_InstanceID","instanceIndex"));function Gt(r,t={}){if(r.isSkinnedMesh)return e(r);if(r.isInstancedMesh)return n(r);return new f(r.geometry,r.material,t);function e(i){const s=new f(i.geometry.clone(),i.material,t);return s.initSkeleton(i.skeleton),s}function n(i){t.capacity=Math.max(i.count,t.capacity);const s=i.geometry.clone();s.deleteAttribute("instanceIndex"),l();const o=new f(s,i.material,t);return o.position.copy(i.position),o.quaternion.copy(i.quaternion),o.scale.copy(i.scale),a(),c(),h(),o;function a(){o.setInstancesArrayCount(i.count),o._instancesCount=i.count,o.availabilityArray.fill(!0,0,i.count*2)}function c(){o.matricesTexture.image.data.set(i.instanceMatrix.array)}function h(){if(i.instanceColor){o.initColorsTexture();const d=i.instanceColor.array,p=o.colorsTexture.image.data;for(let x=0,m=0;x<d.length;x+=3,m+=4)p[m]=d[x],p[m+1]=d[x+1],p[m+2]=d[x+2],p[m+3]=1}}function l(){const d=s.attributes;for(const p in d)d[p].isInstancedBufferAttribute&&console.warn(`InstancedBufferAttribute "${p}" is not supported. It will be ignored.`)}}}exports.GLInstancedBufferAttribute=vt;exports.InstancedEntity=st;exports.InstancedMesh2=f;exports.InstancedMeshBVH=At;exports.InstancedRenderList=wt;exports.SquareDataTexture=j;exports.createInstancedMesh2From=Gt;exports.createRadixSort=Ft;exports.getSquareTextureInfo=Ct;exports.getSquareTextureSize=rt;exports.patchProperties=Tt;exports.patchShader=nt;exports.sortOpaque=ot;exports.sortTransparent=at;exports.unpatchProperties=It; //# sourceMappingURL=index.cjs.map