x_ite
Version:
X_ITE X3D Browser, view and manipulate X3D, VRML, glTF and other 3D sources in HTML.
2 lines • 68.8 kB
JavaScript
/* X_ITE v11.6.6 */
const e=window[Symbol.for("X_ITE.X3D-11.6.6")];(()=>{var t={n:e=>{var i=e&&e.__esModule?()=>e.default:()=>e;return t.d(i,{a:i}),i},d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const i=e.Components;var n=t.n(i);const o=e.Fields;var s=t.n(o);const r=e.X3DFieldDefinition;var a=t.n(r);const c=e.FieldDefinitionArray;var d=t.n(c);const l=e.X3DNode;var u=t.n(l);const h=e.GeometryType;var m=t.n(h);const p=e.X3DConstants;var f=t.n(p);const _=e.Namespace;var x=t.n(_);const g=x().add("Line3.glsl","\n#if defined(X3D_BOUNDED_VOLUME)||defined(X3D_VOLUME_EMITTER)\nstruct Line3{vec3 point;vec3 direction;};bool intersects(const in Line3 line,const in vec3 a,const in vec3 b,const in vec3 c,out vec3 r){vec3 edge1=b-a;vec3 edge2=c-a;vec3 pvec=cross(line.direction,edge2);float det=dot(edge1,pvec);if(det==0.)return false;float inv_det=1./det;vec3 tvec=line.point-a;float u=dot(tvec,pvec)*inv_det;if(u<0.||u>1.)return false;vec3 qvec=cross(tvec,edge1);float v=dot(line.direction,qvec)*inv_det;if(v<0.||u+v>1.)return false;r=vec3(u,v,1.-u-v);return true;}\n#endif\n"),v=x().add("Plane3.glsl","\n#if defined(X3D_BOUNDED_VOLUME)||defined(X3D_VOLUME_EMITTER)\nstruct Plane3{vec3 normal;float distanceFromOrigin;};Plane3 plane3(const in vec3 point,const in vec3 normal){return Plane3(normal,dot(normal,point));}float plane_distance(const in Plane3 plane,const in vec3 point){return dot(point,plane.normal)-plane.distanceFromOrigin;}bool intersects(const in Plane3 plane,const in Line3 line,out vec3 point){float theta=dot(line.direction,plane.normal);if(theta==0.)return false;float t=(plane.distanceFromOrigin-dot(plane.normal,line.point))/theta;point=line.point+line.direction*t;return true;}void sort(inout vec4 points[ARRAY_SIZE],const in int count,const in Plane3 plane){const float shrink=1./1.3;int gap=count;bool exchanged=true;while(exchanged){gap=int(float(gap)*shrink);if(gap<=1){exchanged=false;gap=1;}for(int i=0,l=count-gap;i<l;++i){int j=gap+i;if(plane_distance(plane,points[i].xyz)>plane_distance(plane,points[j].xyz)){vec4 tmp1=points[i];points[i]=points[j];points[j]=tmp1;exchanged=true;}}}}int min_index(const in vec4 points[ARRAY_SIZE],const in int count,const in float value,const in Plane3 plane){int index=-1;float dist=1000000.;for(int i=0;i<count;++i){float d=plane_distance(plane,points[i].xyz);if(d>=value&&d<dist){dist=d;index=i;}}return index;}\n#endif\n"),y=x().add("Box3.glsl","\n#if defined(X3D_VOLUME_EMITTER)||defined(X3D_BOUNDED_VOLUME)\nbool intersects(const in vec3 min,const in vec3 max,const in Line3 line){vec3 intersection;if(intersects(plane3(max,vec3(0.,0.,1.)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.xy,max.xy),vec4(min.xy,intersection.xy))))return true;}if(intersects(plane3(min,vec3(0.,0.,-1.)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.xy,max.xy),vec4(min.xy,intersection.xy))))return true;}if(intersects(plane3(max,vec3(0.,1.,0.)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.xz,max.xz),vec4(min.xz,intersection.xz))))return true;}if(intersects(plane3(min,vec3(0.,-1.,0.)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.xz,max.xz),vec4(min.xz,intersection.xz))))return true;}if(intersects(plane3(max,vec3(1.,0.,0.)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.yz,max.yz),vec4(min.yz,intersection.yz))))return true;}return false;}\n#endif\n"),T=x().add("BVH.glsl","\n#if defined(X3D_VOLUME_EMITTER)||defined(X3D_BOUNDED_VOLUME)\n#define BVH_NODE 0\n#define BVH_TRIANGLE 1\n#define BVH_STACK_SIZE 32\nint bvhNodeIndex=0;void setBVHIndex(const in int index){bvhNodeIndex=index;}int getBVHRoot(const in sampler2D volume,const in int hierarchyIndex,const in int rootIndex){return int(texelFetch(volume,rootIndex,0).x)+hierarchyIndex;}int getBVHType(const in sampler2D volume){return int(texelFetch(volume,bvhNodeIndex,0).x);}vec3 getBVHMin(const in sampler2D volume){return texelFetch(volume,bvhNodeIndex+1,0).xyz;}vec3 getBVHMax(const in sampler2D volume){return texelFetch(volume,bvhNodeIndex+2,0).xyz;}int getBVHLeft(const in sampler2D volume,const in int hierarchyIndex){return int(texelFetch(volume,bvhNodeIndex,0).y)+hierarchyIndex;}int getBVHRight(const in sampler2D volume,const in int hierarchyIndex){return int(texelFetch(volume,bvhNodeIndex,0).z)+hierarchyIndex;}int getBVHTriangle(const in sampler2D volume){return int(texelFetch(volume,bvhNodeIndex,0).y);}\n#if defined(X3D_VOLUME_EMITTER)\nint getIntersections(const in sampler2D volume,const in int verticesIndex,const in int hierarchyIndex,const in int rootIndex,const in Line3 line,out vec4 points[ARRAY_SIZE]){int current=getBVHRoot(volume,hierarchyIndex,rootIndex);int count=0;int stackIndex=-1;int stack[BVH_STACK_SIZE];while(stackIndex>=0||current>=0){if(current>=0){setBVHIndex(current);if(getBVHType(volume)==BVH_NODE){if(intersects(getBVHMin(volume),getBVHMax(volume),line)){stack[++stackIndex]=current;current=getBVHLeft(volume,hierarchyIndex);}else{current=-1;}}else{int t=getBVHTriangle(volume);int v=verticesIndex+t;vec3 r=vec3(0);vec3 a=texelFetch(volume,v,0).xyz;vec3 b=texelFetch(volume,v+1,0).xyz;vec3 c=texelFetch(volume,v+2,0).xyz;if(intersects(line,a,b,c,r))points[count++]=vec4(r.z*a+r.x*b+r.y*c,1.);current=-1;}}else{setBVHIndex(stack[stackIndex--]);current=getBVHRight(volume,hierarchyIndex);}}return count;}\n#endif\n#if defined(X3D_BOUNDED_VOLUME)\nint getIntersections(const in sampler2D volume,const in int verticesIndex,const in int normalsIndex,const in int hierarchyIndex,const in int rootIndex,const in Line3 line,out vec4 points[ARRAY_SIZE],out vec3 normals[ARRAY_SIZE]){int current=getBVHRoot(volume,hierarchyIndex,rootIndex);int count=0;int stackIndex=-1;int stack[BVH_STACK_SIZE];while(stackIndex>=0||current>=0){if(current>=0){setBVHIndex(current);if(getBVHType(volume)==BVH_NODE){if(intersects(getBVHMin(volume),getBVHMax(volume),line)){stack[++stackIndex]=current;current=getBVHLeft(volume,hierarchyIndex);}else{current=-1;}}else{int t=getBVHTriangle(volume);int v=verticesIndex+t;vec3 r=vec3(0);vec3 a=texelFetch(volume,v,0).xyz;vec3 b=texelFetch(volume,v+1,0).xyz;vec3 c=texelFetch(volume,v+2,0).xyz;if(intersects(line,a,b,c,r)){points[count]=vec4(r.z*a+r.x*b+r.y*c,1.);int n=normalsIndex+t;vec3 n0=texelFetch(volume,n,0).xyz;vec3 n1=texelFetch(volume,n+1,0).xyz;vec3 n2=texelFetch(volume,n+2,0).xyz;normals[count]=r.z*n0+r.x*n1+r.y*n2;++count;}current=-1;}}else{setBVHIndex(stack[stackIndex--]);current=getBVHRight(volume,hierarchyIndex);}}return count;}\n#endif\n#endif\n");function R(e){u().call(this,e),this.addType(f().X3DParticleEmitterNode),this.addChildObjects(f().outputOnly,"bbox_changed",new(s().SFTime)),this._speed.setUnit("speed"),this._mass.setUnit("mass"),this._surfaceArea.setUnit("area"),this.defines=[],this.samplers=[],this.uniforms=new Map,this.callbacks=[],this.functions=[],this.programs=new Map}Object.assign(Object.setPrototypeOf(R.prototype,u().prototype),{initialize(){u().prototype.initialize.call(this);const e=this.getBrowser().getContext();this.transformFeedback=e.createTransformFeedback(),this._on.addInterest("set_on__",this),this._speed.addInterest("set_speed__",this),this._variation.addInterest("set_variation__",this),this._mass.addInterest("set_mass__",this),this._surfaceArea.addInterest("set_surfaceArea__",this),this.addSampler("forces"),this.addSampler("boundedVolume"),this.addSampler("colorRamp"),this.addSampler("texCoordRamp"),this.addUniform("speed","uniform float speed;"),this.addUniform("variation","uniform float variation;"),this.addCallback(this.set_speed__),this.addCallback(this.set_variation__),this.addFunction(g),this.addFunction(v),this.addFunction(y),this.addFunction(T),this.set_on__(),this.set_mass__(),this.set_surfaceArea__()},isExplosive:()=>!1,getMass(){return this.mass},getSurfaceArea(){return this.surfaceArea},set_on__(){this.on=this._on.getValue()},set_speed__(){this.setUniform("uniform1f","speed",Math.max(this._speed.getValue(),0))},set_variation__(){this.setUniform("uniform1f","variation",Math.max(this._variation.getValue(),0))},set_mass__(){this.mass=Math.max(this._mass.getValue(),0)},set_surfaceArea__(){this.surfaceArea=Math.max(this._surfaceArea.getValue(),0)},getRandomValue:(e,t)=>Math.random()*(t-e)+e,getRandomNormal(e){const t=this.getRandomValue(-1,1)*Math.PI,i=this.getRandomValue(-1,1),n=Math.acos(i),o=Math.sin(n);return e.set(Math.sin(t)*o,Math.cos(t)*o,i)},animate(e,t){const i=this.getBrowser(),n=i.getContext(),o=this.getProgram(e),s=e.inputParticles;if(n.useProgram(o),n.uniform1i(o.randomSeed,4294967295*Math.random()),n.uniform1f(o.particleLifetime,e.particleLifetime),n.uniform1f(o.lifetimeVariation,e.lifetimeVariation),n.uniform1f(o.deltaTime,t),n.uniform2f(o.particleSize,e._particleSize.x,e._particleSize.y),e.numForces&&(n.activeTexture(n.TEXTURE0+o.forcesTextureUnit),n.bindTexture(n.TEXTURE_2D,e.forcesTexture)),e.boundedHierarchyRoot>-1&&(n.uniform1i(o.boundedVerticesIndex,e.boundedVerticesIndex),n.uniform1i(o.boundedNormalsIndex,e.boundedNormalsIndex),n.uniform1i(o.boundedHierarchyIndex,e.boundedHierarchyIndex),n.uniform1i(o.boundedHierarchyRoot,e.boundedHierarchyRoot),n.activeTexture(n.TEXTURE0+o.boundedVolumeTextureUnit),n.bindTexture(n.TEXTURE_2D,e.boundedTexture)),e.numColors&&(n.activeTexture(n.TEXTURE0+o.colorRampTextureUnit),n.bindTexture(n.TEXTURE_2D,e.colorRampTexture)),e.numTexCoords&&(n.uniform1i(o.texCoordCount,e.texCoordCount),n.activeTexture(n.TEXTURE0+o.texCoordRampTextureUnit),n.bindTexture(n.TEXTURE_2D,e.texCoordRampTexture)),this.activateTextures(n,o),s.vertexArrayObject.enable(o)){const{particlesStride:t,particleOffsets:i}=e;for(const[e,r]of o.inputs)n.bindBuffer(n.ARRAY_BUFFER,s),n.enableVertexAttribArray(r),n.vertexAttribPointer(r,4,n.FLOAT,!1,t,i[e])}n.bindFramebuffer(n.FRAMEBUFFER,i.getDefaultFramebuffer()),n.bindBuffer(n.ARRAY_BUFFER,null),n.bindTransformFeedback(n.TRANSFORM_FEEDBACK,this.transformFeedback),n.bindBufferBase(n.TRANSFORM_FEEDBACK_BUFFER,0,e.outputParticles),n.enable(n.RASTERIZER_DISCARD),n.beginTransformFeedback(n.POINTS),n.drawArrays(n.POINTS,0,e.numParticles),n.endTransformFeedback(),n.disable(n.RASTERIZER_DISCARD),n.bindTransformFeedback(n.TRANSFORM_FEEDBACK,null)},addDefine(e){this.defines.push(e)},addSampler(e){this.samplers.push(e)},addUniform(e,t){this.uniforms.set(e,t)},setUniform(e,t,i,n,o){const s=this.getBrowser().getContext();for(const r of this.programs.values())s.useProgram(r),s[e](r[t],i,n,o)},addCallback(e){this.callbacks.push(e)},addFunction(e){this.functions.push(e)},getProgram(e){const{geometryType:t,createParticles:i,numColors:n,numTexCoords:o,numForces:s,boundedHierarchyRoot:r}=e;let a="";return a+=t,a+=i&&this.on?1:0,a+=".",a+=n,a+=".",a+=o,a+=".",a+=s,a+=".",a+=r,this.programs.get(a)??this.createProgram(a,e)},createProgram(e,t){const i=this.getBrowser(),n=i.getContext(),o=this.defines.slice();o.push(`#define X3D_GEOMETRY_TYPE ${t.geometryType}`),o.push(""+(t.createParticles&&this.on?"#define X3D_CREATE_PARTICLES":"")),o.push(`#define X3D_NUM_COLORS ${t.numColors}`),o.push(`#define X3D_NUM_TEX_COORDS ${t.numTexCoords}`),o.push(`#define X3D_NUM_FORCES ${t.numForces}`),o.push(""+(t.boundedHierarchyRoot>-1?"#define X3D_BOUNDED_VOLUME":""));const s=`#version 300 es\nprecision highp float;precision highp int;precision highp sampler2D;\n${o.join("\n")}\nuniform int randomSeed;uniform float particleLifetime;uniform float lifetimeVariation;uniform float deltaTime;uniform vec2 particleSize;\n#if X3D_NUM_FORCES>0\nuniform sampler2D forces;\n#endif\n#if defined(X3D_BOUNDED_VOLUME)\nuniform int boundedVerticesIndex;uniform int boundedNormalsIndex;uniform int boundedHierarchyIndex;uniform int boundedHierarchyRoot;uniform sampler2D boundedVolume;\n#endif\n#if X3D_NUM_COLORS>0\nuniform sampler2D colorRamp;\n#endif\n#if X3D_NUM_TEX_COORDS>0\nuniform int texCoordCount;uniform sampler2D texCoordRamp;\n#endif\n${Array.from(this.uniforms.values()).join("\n")}\nin vec4 input0;in vec4 input2;in vec4 input6;out vec4 output0;out vec4 output1;out vec4 output2;out vec4 output3;out vec4 output4;out vec4 output5;out vec4 output6;\n${Object.entries(m()).map(([e,t])=>`#define ${e} ${t}`).join("\n")}\nconst int ARRAY_SIZE=32;const float M_PI=3.14159265359;uniform float NaN;vec4 texelFetch(const in sampler2D sampler,const in int index,const in int lod){int x=textureSize(sampler,lod).x;ivec2 p=ivec2(index % x,index/x);vec4 t=texelFetch(sampler,p,lod);return t;}vec3 save_normalize(const in vec3 vector){float l=length(vector);if(l==0.)return vec3(0);return vector/l;}vec4 Quaternion(const in vec3 fromVector,const in vec3 toVector){vec3 from=save_normalize(fromVector);vec3 to=save_normalize(toVector);float cos_angle=dot(from,to);vec3 cross_vec=cross(from,to);float cross_len=length(cross_vec);if(cross_len==0.){if(cos_angle>0.){return vec4(0.,0.,0.,1.);}else{vec3 t=cross(from,vec3(1.,0.,0.));if(dot(t,t)==0.)t=cross(from,vec3(0.,1.,0.));t=save_normalize(t);return vec4(t,0.);}}else{float s=sqrt(abs(1.-cos_angle)*.5);cross_vec=save_normalize(cross_vec);return vec4(cross_vec*s,sqrt(abs(1.+cos_angle)*.5));}}vec3 multVecQuat(const in vec3 v,const in vec4 q){float a=q.w*q.w-q.x*q.x-q.y*q.y-q.z*q.z;float b=2.*(v.x*q.x+v.y*q.y+v.z*q.z);float c=2.*q.w;vec3 r=a*v.xyz+b*q.xyz+c*(q.yzx*v.zxy-q.zxy*v.yzx);return r;}mat3 Matrix3(const in vec4 quaternion){float x=quaternion.x;float y=quaternion.y;float z=quaternion.z;float w=quaternion.w;float A=y*y;float B=z*z;float C=x*y;float D=z*w;float E=z*x;float F=y*w;float G=x*x;float H=y*z;float I=x*w;return mat3(1.-2.*(A+B),2.*(C+D),2.*(E-F),2.*(C-D),1.-2.*(B+G),2.*(H+I),2.*(E+F),2.*(H-I),1.-2.*(A+G));}uint seed=1u;void srand(const in int value){seed=uint(value);}float random(){seed=seed*1103515245u+12345u;return float(seed)/4294967295.;}float getRandomValue(const in float min,const in float max){return min+random()*(max-min);}float getRandomLifetime(){float v=particleLifetime*lifetimeVariation;float min_=max(0.,particleLifetime-v);float max_=particleLifetime+v;return getRandomValue(min_,max_);}float getRandomSpeed(){float v=speed*variation;float min_=max(0.,speed-v);float max_=speed+v;return getRandomValue(min_,max_);}vec3 getRandomNormal(){float theta=getRandomValue(-M_PI,M_PI);float cphi=getRandomValue(-1.,1.);float r=sqrt(1.-cphi*cphi);return vec3(sin(theta)*r,cos(theta)*r,cphi);}vec3 getRandomNormalWithAngle(const in float angle){float theta=getRandomValue(-M_PI,M_PI);float cphi=getRandomValue(cos(angle),1.);float r=sqrt(1.-cphi*cphi);return vec3(sin(theta)*r,cos(theta)*r,cphi);}vec3 getRandomNormalWithDirectionAndAngle(const in vec3 direction,const in float angle){vec4 rotation=Quaternion(vec3(0.,0.,1.),direction);vec3 normal=getRandomNormalWithAngle(angle);return multVecQuat(normal,rotation);}vec3 getRandomSurfaceNormal(const in vec3 direction){float theta=getRandomValue(-M_PI,M_PI);float cphi=pow(random(),1./3.);float r=sqrt(1.-cphi*cphi);vec3 normal=vec3(sin(theta)*r,cos(theta)*r,cphi);vec4 rotation=Quaternion(vec3(0.,0.,1.),direction);return multVecQuat(normal,rotation);}vec3 getRandomSphericalVelocity(){vec3 normal=getRandomNormal();float speed=getRandomSpeed();return normal*speed;}int upperBound(const in sampler2D sampler,in int count,const in float value){int first=0;int step=0;while(count>0){int index=first;step=count>>1;index+=step;if(value<texelFetch(sampler,index,0).x){count=step;}else{first=++index;count-=step+1;}}return first;}\n#if X3D_NUM_COLORS>0||defined(X3D_POLYLINE_EMITTER)||defined(X3D_SURFACE_EMITTER)||defined(X3D_VOLUME_EMITTER)\nvoid interpolate(const in sampler2D sampler,const in int count,const in float fraction,out int index0,out int index1,out float weight){if(count==1||fraction<=texelFetch(sampler,0,0).x){index0=0;index1=0;weight=0.;}else if(fraction>=texelFetch(sampler,count-1,0).x){index0=count-2;index1=count-1;weight=1.;}else{int index=upperBound(sampler,count,fraction);if(index<count){index1=index;index0=index-1;float key0=texelFetch(sampler,index0,0).x;float key1=texelFetch(sampler,index1,0).x;weight=clamp((fraction-key0)/(key1-key0),0.,1.);}else{index0=0;index1=0;weight=0.;}}}\n#endif\n#if X3D_NUM_TEX_COORDS>0\nvoid interpolate(const in sampler2D sampler,const in int count,const in float fraction,out int index0){if(count==1||fraction<=texelFetch(sampler,0,0).x){index0=0;}else if(fraction>=texelFetch(sampler,count-1,0).x){index0=count-2;}else{int index=upperBound(sampler,count,fraction);if(index<count)index0=index-1;else index0=0;}}\n#endif\n#if defined(X3D_SURFACE_EMITTER)||defined(X3D_VOLUME_EMITTER)\nvec3 getRandomBarycentricCoord(){float u=random();float v=random();if(u+v>1.){u=1.-u;v=1.-v;}float t=1.-u-v;return vec3(t,u,v);}void getRandomPointOnSurface(const in sampler2D surface,const in int verticesIndex,const in int normalsIndex,out vec4 position,out vec3 normal){float lastAreaSoFar=texelFetch(surface,verticesIndex-1,0).x;float fraction=random()*lastAreaSoFar;int index0;int index1;int index2;float weight;interpolate(surface,verticesIndex,fraction,index0,index1,weight);index0*=3;index1=index0+1;index2=index0+2;vec4 vertex0=texelFetch(surface,verticesIndex+index0,0);vec4 vertex1=texelFetch(surface,verticesIndex+index1,0);vec4 vertex2=texelFetch(surface,verticesIndex+index2,0);vec3 normal0=texelFetch(surface,normalsIndex+index0,0).xyz;vec3 normal1=texelFetch(surface,normalsIndex+index1,0).xyz;vec3 normal2=texelFetch(surface,normalsIndex+index2,0).xyz;vec3 r=getRandomBarycentricCoord();position=r.z*vertex0+r.x*vertex1+r.y*vertex2;normal=save_normalize(r.z*normal0+r.x*normal1+r.y*normal2);}\n#endif\n${this.functions.join("\n")}\n#if X3D_NUM_COLORS>0\nvec4 getColor(const in float lifetime,const in float elapsedTime){float fraction=elapsedTime/lifetime;int index0;int index1;float weight;interpolate(colorRamp,X3D_NUM_COLORS,fraction,index0,index1,weight);vec4 color0=texelFetch(colorRamp,X3D_NUM_COLORS+index0,0);vec4 color1=texelFetch(colorRamp,X3D_NUM_COLORS+index1,0);return mix(color0,color1,weight);}\n#else\n#define getColor(lifetime,elapsedTime)(vec4(1))\n#endif\n#if defined(X3D_BOUNDED_VOLUME)\nvoid bounce(const in float deltaTime,const in vec4 fromPosition,inout vec4 toPosition,inout vec3 velocity){Line3 line=Line3(fromPosition.xyz,save_normalize(velocity));vec4 points[ARRAY_SIZE];vec3 normals[ARRAY_SIZE];int numIntersections=getIntersections(boundedVolume,boundedVerticesIndex,boundedNormalsIndex,boundedHierarchyIndex,boundedHierarchyRoot,line,points,normals);if(numIntersections==0)return;Plane3 plane1=plane3(line.point,line.direction);int index=min_index(points,numIntersections,0.,plane1);if(index==-1)return;vec3 point=points[index].xyz;vec3 normal=save_normalize(normals[index]);Plane3 plane2=plane3(point,normal);if(sign(plane_distance(plane2,fromPosition.xyz))==sign(plane_distance(plane2,toPosition.xyz)))return;float damping=length(normals[index]);velocity=reflect(velocity,normal);toPosition=vec4(point+save_normalize(velocity)*.0001,1.);velocity*=damping;}\n#endif\n#if X3D_NUM_TEX_COORDS>0\nint getTexCoordIndex0(const in float lifetime,const in float elapsedTime){float fraction=elapsedTime/lifetime;int index0=0;interpolate(texCoordRamp,X3D_NUM_TEX_COORDS,fraction,index0);return X3D_NUM_TEX_COORDS+index0*texCoordCount;}\n#else\n#define getTexCoordIndex0(lifetime,elapsedTime)(-1)\n#endif\nvoid main(){int life=int(input0[0]);float lifetime=input0[1];float elapsedTime=input0[2]+deltaTime;srand((gl_VertexID+randomSeed)*randomSeed);if(elapsedTime>lifetime){lifetime=getRandomLifetime();elapsedTime=0.;output0=vec4(max(life+1,1),lifetime,elapsedTime,getTexCoordIndex0(lifetime,elapsedTime));\n#if defined(X3D_CREATE_PARTICLES)\noutput1=getColor(lifetime,elapsedTime);output2=vec4(getRandomVelocity(),0.);output6=getRandomPosition();\n#else\noutput1=vec4(0);output2=vec4(0);output6=vec4(NaN);\n#endif\n}else{vec3 velocity=input2.xyz;vec4 position=input6;\n#if X3D_NUM_FORCES>0\nfor(int i=0;i<X3D_NUM_FORCES;++i){vec4 force=texelFetch(forces,i,0);float turbulence=force.w;vec3 normal=getRandomNormalWithDirectionAndAngle(force.xyz,turbulence);float speed=length(force.xyz);velocity+=normal*speed;}\n#endif\nposition.xyz+=velocity*deltaTime;\n#if defined(X3D_BOUNDED_VOLUME)\nbounce(deltaTime,input6,position,velocity);\n#endif\noutput0=vec4(life,lifetime,elapsedTime,getTexCoordIndex0(lifetime,elapsedTime));output1=getColor(lifetime,elapsedTime);output2=vec4(velocity,0.);output6=position;}\n#if X3D_GEOMETRY_TYPE==POINT||X3D_GEOMETRY_TYPE==SPRITE||X3D_GEOMETRY_TYPE==GEOMETRY\noutput3=vec4(1.,0.,0.,0.);output4=vec4(0.,1.,0.,0.);output5=vec4(0.,0.,1.,0.);\n#elif X3D_GEOMETRY_TYPE==LINE\nmat3 m=Matrix3(Quaternion(vec3(0.,0.,1.),output2.xyz));output3=vec4(m[0],0.);output4=vec4(m[1],0.);output5=vec4(m[2],0.);\n#else\noutput3=vec4(particleSize.x,0.,0.,0.);output4=vec4(0.,particleSize.y,0.,0.);output5=vec4(0.,0.,1.,0.);\n#endif\n}`,r=n.createShader(n.VERTEX_SHADER);n.shaderSource(r,s),n.compileShader(r),n.getShaderParameter(r,n.COMPILE_STATUS)||console.error(n.getShaderInfoLog(r));const a=n.createShader(n.FRAGMENT_SHADER);n.shaderSource(a,"#version 300 es\nprecision highp float;void main(){}"),n.compileShader(a),n.getShaderParameter(a,n.COMPILE_STATUS)||console.error(n.getShaderInfoLog(a));const c=n.createProgram();n.attachShader(c,r),n.attachShader(c,a),n.transformFeedbackVaryings(c,Array.from({length:7},(e,t)=>"output"+t),n.INTERLEAVED_ATTRIBS),n.linkProgram(c),n.getProgramParameter(c,n.LINK_STATUS)||console.error(`Couldn't initialize particle shader: ${n.getProgramInfoLog(c)}`),this.programs.set(e,c),n.useProgram(c),c.inputs=[[0,n.getAttribLocation(c,"input0")],[2,n.getAttribLocation(c,"input2")],[6,n.getAttribLocation(c,"input6")]],c.randomSeed=n.getUniformLocation(c,"randomSeed"),c.particleLifetime=n.getUniformLocation(c,"particleLifetime"),c.lifetimeVariation=n.getUniformLocation(c,"lifetimeVariation"),c.deltaTime=n.getUniformLocation(c,"deltaTime"),c.particleSize=n.getUniformLocation(c,"particleSize"),c.forces=n.getUniformLocation(c,"forces"),c.boundedVerticesIndex=n.getUniformLocation(c,"boundedVerticesIndex"),c.boundedNormalsIndex=n.getUniformLocation(c,"boundedNormalsIndex"),c.boundedHierarchyIndex=n.getUniformLocation(c,"boundedHierarchyIndex"),c.boundedHierarchyRoot=n.getUniformLocation(c,"boundedHierarchyRoot"),c.boundedVolume=n.getUniformLocation(c,"boundedVolume"),c.colorRamp=n.getUniformLocation(c,"colorRamp"),c.texCoordCount=n.getUniformLocation(c,"texCoordCount"),c.texCoordRamp=n.getUniformLocation(c,"texCoordRamp");for(const e of this.uniforms.keys())c[e]=n.getUniformLocation(c,e);n.uniform1f(n.getUniformLocation(c,"NaN"),NaN);for(const e of this.samplers){const t=n.getUniformLocation(c,e);n.uniform1i(t,c[e+"TextureUnit"]=i.getTextureUnit())}i.resetTextureUnits();for(const e of this.callbacks)e.call(this);return c},activateTextures(){},createTexture(){const e=this.getBrowser().getContext(),t=e.createTexture();return e.bindTexture(e.TEXTURE_2D,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texImage2D(e.TEXTURE_2D,0,e.RGBA32F,1,1,0,e.RGBA,e.FLOAT,new Float32Array(4)),t},getTextureUnit(e,t,i){const n=t[i];return void 0===n?t[i]=e.getTextureUnit():n}}),Object.defineProperties(R,u().getStaticProperties("X3DParticleEmitterNode","ParticleSystems",1));const E=R,b=x().add("X3DParticleEmitterNode",E),I=e.Vector3;var w=t.n(I);function F(e){b.call(this,e),this.addType(f().PointEmitter),this._position.setUnit("length")}Object.assign(Object.setPrototypeOf(F.prototype,b.prototype),{initialize(){b.prototype.initialize.call(this),this._position.addInterest("set_position__",this),this._direction.addInterest("set_direction__",this),this.addDefine("#define X3D_POINT_EMITTER"),this.addUniform("position","uniform vec3 position;"),this.addUniform("direction","uniform vec3 direction;"),this.addCallback(this.set_position__),this.addCallback(this.set_direction__),this.addFunction("vec3 getRandomVelocity ()\n {\n if (direction == vec3 (0.0))\n return getRandomSphericalVelocity ();\n\n else\n return direction * getRandomSpeed ();\n }"),this.addFunction("vec4 getRandomPosition ()\n {\n return vec4 (position, 1.0);\n }")},getBBox:(()=>{const e=new(w());return function(t,{particleLifetime:i,lifetimeVariation:n}){const o=i*(1+n)*(this._speed.getValue()*(1+this._variation.getValue()))*2;return t.set(e.set(o,o,o),this._position.getValue())}})(),set_position__(){const{x:e,y:t,z:i}=this._position.getValue();this.setUniform("uniform3f","position",e,t,i),this._bbox_changed.addEvent()},set_direction__:(()=>{const e=new(w());return function(){const{x:t,y:i,z:n}=e.assign(this._direction.getValue()).normalize();this.setUniform("uniform3f","direction",t,i,n)}})()}),Object.defineProperties(F,{...u().getStaticProperties("PointEmitter","ParticleSystems",1,"emitter","3.2"),fieldDefinitions:{value:new(d())([new(a())(f().inputOutput,"metadata",new(s().SFNode)),new(a())(f().inputOutput,"on",new(s().SFBool)(!0)),new(a())(f().inputOutput,"position",new(s().SFVec3f)),new(a())(f().inputOutput,"direction",new(s().SFVec3f)(0,1,0)),new(a())(f().inputOutput,"speed",new(s().SFFloat)),new(a())(f().inputOutput,"variation",new(s().SFFloat)(.25)),new(a())(f().inputOutput,"mass",new(s().SFFloat)),new(a())(f().inputOutput,"surfaceArea",new(s().SFFloat))]),enumerable:!0}});const O=F,S=x().add("PointEmitter",O),A=Symbol();function P(){}Object.assign(P.prototype,{getDefaultEmitter(){return this[A]??=(()=>{const e=new S(this.getPrivateScene());return e.setup(),e})()}});const N=P,D=x().add("X3DParticleSystemsContext",N);function C(e){u().call(this,e),this.addType(f().X3DParticlePhysicsModelNode)}Object.assign(Object.setPrototypeOf(C.prototype,u().prototype),{addForce(){}}),Object.defineProperties(C,u().getStaticProperties("X3DParticlePhysicsModelNode","ParticleSystems",1));const V=C,B=x().add("X3DParticlePhysicsModelNode",V),U=e.X3DCast;var M=t.n(U);function z(e){B.call(this,e),this.addType(f().BoundedPhysicsModel)}Object.assign(Object.setPrototypeOf(z.prototype,B.prototype),{initialize(){B.prototype.initialize.call(this),this._geometry.addInterest("set_geometry__",this),this.set_geometry__()},getBBox(){return this.geometryNode?.getBBox()},set_geometry__(){this.geometryNode?._rebuild.removeInterest("addNodeEvent",this),this.geometryNode=M()(f().X3DGeometryNode,this._geometry),this.geometryNode?._rebuild.addInterest("addNodeEvent",this)},addGeometry(e,t){if(!this.geometryNode)return;if(!this._enabled.getValue())return;const i=this._damping.getValue(),n=this.geometryNode.getNormals().getValue(),o=this.geometryNode.getVertices().getValue();for(const t of n)e.push(t*i);for(const e of o)t.push(e)}}),Object.defineProperties(z,{...u().getStaticProperties("BoundedPhysicsModel","ParticleSystems",2,"physics","3.2"),fieldDefinitions:{value:new(d())([new(a())(f().inputOutput,"metadata",new(s().SFNode)),new(a())(f().inputOutput,"enabled",new(s().SFBool)(!0)),new(a())(f().inputOutput,"damping",new(s().SFFloat)(1)),new(a())(f().inputOutput,"geometry",new(s().SFNode))]),enumerable:!0}});const L=z,X=x().add("BoundedPhysicsModel",L);function k(e){b.call(this,e),this.addType(f().ConeEmitter),this._position.setUnit("length"),this._angle.setUnit("angle")}Object.assign(Object.setPrototypeOf(k.prototype,b.prototype),{initialize(){b.prototype.initialize.call(this),this._position.addInterest("set_position__",this),this._direction.addInterest("set_direction__",this),this._angle.addInterest("set_angle__",this),this.addDefine("#define X3D_CONE_EMITTER"),this.addUniform("position","uniform vec3 position;"),this.addUniform("direction","uniform vec3 direction;"),this.addUniform("angle","uniform float angle;"),this.addCallback(this.set_position__),this.addCallback(this.set_direction__),this.addCallback(this.set_angle__),this.addFunction("vec3 getRandomVelocity ()\n {\n if (direction == vec3 (0.0))\n {\n return getRandomSphericalVelocity ();\n }\n else\n {\n vec3 normal = getRandomNormalWithDirectionAndAngle (direction, angle);\n float speed = getRandomSpeed ();\n\n return normal * speed;\n }\n }"),this.addFunction("vec4 getRandomPosition ()\n {\n return vec4 (position, 1.0);\n }")},getBBox:(()=>{const e=new(w());return function(t,{particleLifetime:i,lifetimeVariation:n}){const o=i*(1+n)*(this._speed.getValue()*(1+this._variation.getValue()))*2;return t.set(e.set(o,o,o),this._position.getValue())}})(),set_position__(){const{x:e,y:t,z:i}=this._position.getValue();this.setUniform("uniform3f","position",e,t,i),this._bbox_changed.addEvent()},set_direction__(){const{x:e,y:t,z:i}=this._direction.getValue();this.setUniform("uniform3f","direction",e,t,i)},set_angle__(){this.setUniform("uniform1f","angle",this._angle.getValue())}}),Object.defineProperties(k,{...u().getStaticProperties("ConeEmitter","ParticleSystems",1,"emitter","3.2"),fieldDefinitions:{value:new(d())([new(a())(f().inputOutput,"metadata",new(s().SFNode)),new(a())(f().inputOutput,"on",new(s().SFBool)(!0)),new(a())(f().inputOutput,"position",new(s().SFVec3f)),new(a())(f().inputOutput,"direction",new(s().SFVec3f)(0,1,0)),new(a())(f().inputOutput,"angle",new(s().SFFloat)(.785398)),new(a())(f().inputOutput,"speed",new(s().SFFloat)),new(a())(f().inputOutput,"variation",new(s().SFFloat)(.25)),new(a())(f().inputOutput,"mass",new(s().SFFloat)),new(a())(f().inputOutput,"surfaceArea",new(s().SFFloat))]),enumerable:!0}});const j=k,G=x().add("ConeEmitter",j);function H(e){b.call(this,e),this.addType(f().ExplosionEmitter),this._position.setUnit("length")}Object.assign(Object.setPrototypeOf(H.prototype,b.prototype),{initialize(){b.prototype.initialize.call(this),this._position.addInterest("set_position__",this),this.addDefine("#define X3D_EXPLOSION_EMITTER"),this.addUniform("position","uniform vec3 position;"),this.addCallback(this.set_position__),this.addFunction("vec3 getRandomVelocity ()\n {\n return getRandomSphericalVelocity ();\n }"),this.addFunction("vec4 getRandomPosition ()\n {\n return vec4 (position, 1.0);\n }")},getBBox:(()=>{const e=new(w());return function(t,{particleLifetime:i,lifetimeVariation:n}){const o=i*(1+n)*(this._speed.getValue()*(1+this._variation.getValue()))*2;return t.set(e.set(o,o,o),this._position.getValue())}})(),isExplosive:()=>!0,set_position__(){const{x:e,y:t,z:i}=this._position.getValue();this.setUniform("uniform3f","position",e,t,i),this._bbox_changed.addEvent()}}),Object.defineProperties(H,{...u().getStaticProperties("ExplosionEmitter","ParticleSystems",1,"emitter","3.2"),fieldDefinitions:{value:new(d())([new(a())(f().inputOutput,"metadata",new(s().SFNode)),new(a())(f().inputOutput,"on",new(s().SFBool)(!0)),new(a())(f().inputOutput,"position",new(s().SFVec3f)),new(a())(f().inputOutput,"speed",new(s().SFFloat)),new(a())(f().inputOutput,"variation",new(s().SFFloat)(.25)),new(a())(f().inputOutput,"mass",new(s().SFFloat)),new(a())(f().inputOutput,"surfaceArea",new(s().SFFloat))]),enumerable:!0}});const Y=H,q=x().add("ExplosionEmitter",Y);function W(e){B.call(this,e),this.addType(f().ForcePhysicsModel),this._force.setUnit("force")}Object.assign(Object.setPrototypeOf(W.prototype,B.prototype),{addForce:(()=>{const e=new(w());return function(t,i,n,o){return!!this._enabled.getValue()&&(o.set(e.assign(this._force.getValue()).multiply(n),4*t),o[4*t+3]=0,!0)}})()}),Object.defineProperties(W,{...u().getStaticProperties("ForcePhysicsModel","ParticleSystems",1,"physics","3.2"),fieldDefinitions:{value:new(d())([new(a())(f().inputOutput,"metadata",new(s().SFNode)),new(a())(f().inputOutput,"enabled",new(s().SFBool)(!0)),new(a())(f().inputOutput,"force",new(s().SFVec3f)(0,-9.8,0))]),enumerable:!0}});const K=W,Z=x().add("ForcePhysicsModel",K),Q=e.X3DShapeNode;var $=t.n(Q);const J=e.GeometryContext;var ee=t.n(J);const te=e.VertexArray;var ie=t.n(te);const ne=e.AlphaMode;var oe=t.n(ne);const se=e.LineSet;var re=t.n(se);const ae=e.Coordinate;var ce=t.n(ae);const de=e.Matrix4;var le=t.n(de);const ue=e.Matrix3;var he=t.n(ue);const me=e.Plane3;var pe=t.n(me);const fe=e.QuickSort;var _e=t.n(fe);const xe=new(w()),ge=new(w()),ve=new(w()),ye={u:0,v:0,t:0},Te=[new(w())(0,0,1),new(w())(0,0,-1),new(w())(0,1,0),new(w())(0,-1,0),new(w())(1,0,0)];function Re(e,t){this.vertices=e.vertices,this.normals=e.normals,this.triangle=t,this.i4=12*t,this.i3=9*t}function Ee(e,t,i,n){this.min=new(w()),this.max=new(w()),this.planes=[],this.intersection=new(w());const o=e.vertices,s=this.min,r=this.max,a=i+n;let c=12*t[i];s.set(o[c],o[c+1],o[c+2]),r.assign(s);for(let e=i;e<a;++e)c=12*t[e],xe.set(o[c],o[c+1],o[c+2]),ge.set(o[c+4],o[c+5],o[c+6]),ve.set(o[c+8],o[c+9],o[c+10]),s.min(xe,ge,ve),r.max(xe,ge,ve);for(let e=0;e<5;++e)this.planes[e]=new(pe())(e%2?s:r,Te[e]);if(n>2){e.sorter.compare.axis=this.getLongestAxis(s,r),e.sorter.sort(i,a);var d=n>>>1}else d=1;const l=n-d;this.left=d>1?new Ee(e,t,i,d):new Re(e,t[i]),this.right=l>1?new Ee(e,t,i+d,l):new Re(e,t[i+d])}function be(e,t){const i=e.length/12;switch(this.vertices=e,this.normals=t,i){case 0:this.root=null;break;case 1:this.root=new Re(this,0);break;default:{const t=[];for(let e=0;e<i;++e)t.push(e);this.sorter=new(_e())(t,function(e,t){return function(i,n){return Math.min(e[i+t],e[i+4+t],e[i+8+t])<Math.min(e[n+t],e[n+4+t],e[n+8+t])}}(e,0)),this.root=new Ee(this,t,0,i);break}}}Object.assign(Re.prototype,{intersectsLine(e,t,i){const n=this.vertices,o=this.normals,s=this.i4,r=this.i3;if(xe.x=n[s],xe.y=n[s+1],xe.z=n[s+2],ge.x=n[s+4],ge.y=n[s+5],ge.z=n[s+6],ve.x=n[s+8],ve.y=n[s+9],ve.z=n[s+10],e.intersectsTriangle(xe,ge,ve,ye)){const{u:e,v:a,t:c}=ye,d=t.size++;d>=t.length&&t.push(new(w())),t[d].set(e*n[s]+a*n[s+4]+c*n[s+8],e*n[s+1]+a*n[s+5]+c*n[s+9],e*n[s+2]+a*n[s+6]+c*n[s+10]),i&&(d>=i.length&&i.push(new(w())),i[d].set(e*o[r]+a*o[r+3]+c*o[r+6],e*o[r+1]+a*o[r+4]+c*o[r+7],e*o[r+2]+a*o[r+5]+c*o[r+8]))}},toArray(e){const t=e.length/4;return e.push(1,3*this.triangle,0,0),t}}),Object.assign(Ee.prototype,{intersectsLine(e,t,i){this.intersectsBBox(e)&&(this.left.intersectsLine(e,t,i),this.right.intersectsLine(e,t,i))},intersectsBBox(e){const t=this.planes,i=this.min,n=this.max,o=i.x,s=n.x,r=i.y,a=n.y,c=i.z,d=n.z,l=this.intersection;return!!(t[0].intersectsLine(e,l)&&l.x>=o&&l.x<=s&&l.y>=r&&l.y<=a)||(!!(t[1].intersectsLine(e,l)&&l.x>=o&&l.x<=s&&l.y>=r&&l.y<=a)||(!!(t[2].intersectsLine(e,l)&&l.x>=o&&l.x<=s&&l.z>=c&&l.z<=d)||(!!(t[3].intersectsLine(e,l)&&l.x>=o&&l.x<=s&&l.z>=c&&l.z<=d)||!!(t[4].intersectsLine(e,l)&&l.y>=r&&l.y<=a&&l.z>=c&&l.z<=d))))},getLongestAxis(e,t){const i=t.x-e.x,n=t.y-e.y,o=t.z-e.z;return i<n?n<o?2:1:i<o?2:0},toArray(e){const t=this.left.toArray(e),i=this.right.toArray(e),n=this.min,o=this.max,s=e.length/4;return e.push(0,t,i,0,n.x,n.y,n.z,0,o.x,o.y,o.z,0),s}}),Object.assign(be.prototype,{intersectsLine(e,t,i){return t.size=0,this.root?(this.root.intersectsLine(e,t,i),t.size):0},toArray(e){if(this.root){const t=this.root.toArray(e);e.push(t,0,0,0)}return e}});const Ie=be,we=x().add("BVH",Ie),Fe=new Float32Array([0,0,0,1]),Oe=new Float32Array([0,0,0,1,1,0,0,1,1,1,0,1,0,0,0,1,1,1,0,1,0,1,0,1,0,0,1,-.5,-.5,0,1,.5,-.5,0,1,.5,.5,0,1,-.5,-.5,0,1,.5,.5,0,1,-.5,.5,0,1]);function Se(e){$().call(this,e),this.addType(f().ParticleSystem),this._particleSize.setUnit("length"),e.getSpecificationVersion()<=3.3&&(this.addAlias("colorRamp",this._color),this.addAlias("texCoordRamp",this._texCoord));const t=this.getBrowser();this.maxParticles=0,this.numParticles=0,this.forcePhysicsModelNodes=[],this.forces=new Float32Array(4),this.boundedPhysicsModelNodes=[],this.boundedNormals=[],this.boundedVertices=[],this.colorRamp=new Float32Array,this.texCoordRamp=new Float32Array,this.geometryContext=new(ee())({textureCoordinateNode:t.getDefaultTextureCoordinate()}),this.creationTime=0,this.pauseTime=0,this.deltaTime=0,this.particlesStride=7*Float32Array.BYTES_PER_ELEMENT*4,this.particleOffsets=Array.from({length:7},(e,t)=>4*Float32Array.BYTES_PER_ELEMENT*t),this.particleOffset=this.particleOffsets[0],this.colorOffset=this.particleOffsets[1],this.velocityOffset=this.particleOffsets[2],this.matrixOffset=this.particleOffsets[3],this.texCoordOffset=0,this.instancesStride=this.particlesStride}Object.assign(Object.setPrototypeOf(Se.prototype,$().prototype),{initialize(){$().prototype.initialize.call(this);const e=this.getBrowser(),t=e.getContext();this.getLive().addInterest("set_live__",this),this._enabled.addInterest("set_enabled__",this),this._geometryType.addInterest("set_geometryType__",this),this._geometryType.addInterest("set_texCoord__",this),this._maxParticles.addInterest("set_enabled__",this),this._particleLifetime.addInterest("set_particleLifetime__",this),this._particleLifetime.addInterest("set_bbox__",this),this._lifetimeVariation.addInterest("set_lifetimeVariation__",this),this._lifetimeVariation.addInterest("set_bbox__",this),this._particleSize.addInterest("set_particleSize__",this),this._emitter.addInterest("set_emitter__",this),this._emitter.addInterest("set_bbox__",this),this._physics.addInterest("set_physics__",this),this._colorKey.addInterest("set_color__",this),this._color.addInterest("set_colorRamp__",this),this._texCoordKey.addInterest("set_texCoord__",this),this._texCoord.addInterest("set_texCoordRamp__",this),this.inputParticles=Object.assign(t.createBuffer(),{vertexArrayObject:new(ie())(t),thickLinesVertexArrayObject:new(ie())(t)}),this.outputParticles=Object.assign(t.createBuffer(),{vertexArrayObject:new(ie())(t),thickLinesVertexArrayObject:new(ie())(t)}),this.forcesTexture=this.createTexture(),this.boundedTexture=this.createTexture(),this.colorRampTexture=this.createTexture(),this.texCoordRampTexture=this.createTexture(),this.geometryBuffer=this.createBuffer(),this.texCoordBuffers=new Array(e.getMaxTexCoords()).fill(this.geometryBuffer),this.lineGeometryNode=new(re())(this.getExecutionContext()),this.lineCoordinateNode=new(ce())(this.getExecutionContext()),this.lineCoordinateNode._point=[0,0,-.5,0,0,.5],this.lineGeometryNode._vertexCount=[2],this.lineGeometryNode._coord=this.lineCoordinateNode,this.lineCoordinateNode.setup(),this.lineGeometryNode.setup(),this.set_emitter__(),this.set_enabled__(),this.set_geometryType__(),this.set_particleLifetime__(),this.set_lifetimeVariation__(),this.set_particleSize__(),this.set_physics__(),this.set_colorRamp__(),this.set_texCoordRamp__(),this.set_bbox__()},getShapeKey(){return this.numTexCoords?2:1},getGeometryContext(){return this.geometryType===m().GEOMETRY?this.getGeometry():this.geometryContext},getGeometryType(){return this.geometryType},getNumInstances(){return this.numParticles},getInstances(){return this.outputParticles},set_bbox__(){if(this.isDefaultBBoxSize())if(this.boundedPhysicsModelNodes.length){this.bbox.set();for(const e of this.boundedPhysicsModelNodes){const t=e.getBBox();t&&this.bbox.add(t)}}else this.emitterNode?.getBBox(this.bbox,this);else this.bbox.set(this._bboxSize.getValue(),this._bboxCenter.getValue());this.bboxSize.assign(this.bbox.size),this.bboxCenter.assign(this.bbox.center)},set_transparent__(){const e=this.appearanceNode.getAlphaMode();e===oe().AUTO?(this.setTransparent(this.getAppearance().isTransparent()||this.colorRampNode?.isTransparent()||this.geometryType===m().GEOMETRY&&this.geometryNode?.isTransparent()),this.setAlphaMode(this.isTransparent()?oe().BLEND:oe().OPAQUE)):(this.setTransparent(e===oe().BLEND),this.setAlphaMode(e))},set_live__(){this.getLive().getValue()?this._isActive.getValue()&&this._maxParticles.getValue()&&(this.getBrowser().sensorEvents().addInterest("animateParticles",this),this.pauseTime&&(this.creationTime+=Date.now()/1e3-this.pauseTime,this.pauseTime=0)):this._isActive.getValue()&&this._maxParticles.getValue()&&(this.getBrowser().sensorEvents().removeInterest("animateParticles",this),0===this.pauseTime&&(this.pauseTime=Date.now()/1e3))},set_enabled__(){this._enabled.getValue()&&this._maxParticles.getValue()?this._isActive.getValue()||(this.getLive().getValue()?(this.getBrowser().sensorEvents().addInterest("animateParticles",this),this.pauseTime=0):this.pauseTime=Date.now()/1e3,this._isActive=!0,delete this.traverse):this._isActive.getValue()&&(this.getLive().getValue()&&this.getBrowser().sensorEvents().removeInterest("animateParticles",this),this._isActive=!1,this.numParticles=0,this.traverse=Function.prototype),this.set_maxParticles__()},set_geometryType__(){const e=this.getBrowser().getContext();switch(this.geometryType=m().get(this._geometryType.getValue())??m().QUAD,this.geometryType){case m().POINT:this.geometryContext.geometryType=0,this.geometryContext.hasNormals=!1,this.texCoordCount=0,this.vertexCount=1,this.hasNormals=!1,this.verticesOffset=0,this.primitiveMode=e.POINTS,e.bindBuffer(e.ARRAY_BUFFER,this.geometryBuffer),e.bufferData(e.ARRAY_BUFFER,Fe,e.DYNAMIC_DRAW);break;case m().LINE:this.geometryContext.geometryType=1,this.geometryContext.hasNormals=!1,this.texCoordCount=0;break;case m().TRIANGLE:case m().QUAD:case m().SPRITE:this.geometryContext.geometryType=2,this.geometryContext.hasNormals=!0,this.texCoordCount=4,this.vertexCount=6,this.hasNormals=!0,this.texCoordsOffset=0,this.normalOffset=24*Float32Array.BYTES_PER_ELEMENT,this.verticesOffset=27*Float32Array.BYTES_PER_ELEMENT,this.primitiveMode=e.TRIANGLES,e.bindBuffer(e.ARRAY_BUFFER,this.geometryBuffer),e.bufferData(e.ARRAY_BUFFER,Oe,e.DYNAMIC_DRAW);break;case m().GEOMETRY:this.texCoordCount=0}this.geometryContext.updateGeometryKey(),this.updateVertexArrays(),this.set_objects__()},set_maxParticles__(){const e=this.numParticles,t=Math.max(0,this._maxParticles.getValue());this.maxParticles=t,this.numParticles=Math.min(e,t),this.emitterNode.isExplosive()||(this.creationTime=Date.now()/1e3),this.resizeBuffers(e),this.updateVertexArrays(),this.set_objects__()},set_particleLifetime__(){this.particleLifetime=Math.max(this._particleLifetime.getValue(),0)},set_lifetimeVariation__(){this.lifetimeVariation=Math.max(this._lifetimeVariation.getValue(),0)},set_particleSize__(){this.lineCoordinateNode._point[0].z=-this._particleSize.y/2,this.lineCoordinateNode._point[1].z=+this._particleSize.y/2},set_emitter__(){this.emitterNode?._bbox_changed.removeInterest("set_bbox__",this),this.emitterNode=M()(f().X3DParticleEmitterNode,this._emitter)??this.getBrowser().getDefaultEmitter(),this.emitterNode._bbox_changed.addInterest("set_bbox__",this)},set_physics__(){const e=this._physics.getValue(),t=this.forcePhysicsModelNodes,i=this.boundedPhysicsModelNodes;for(const e of i)e.removeInterest("set_boundedPhysics__",this),e.removeInterest("set_bbox__",this);t.length=0,i.length=0;for(let n=0,o=e.length;n<o;++n)try{const o=e[n].getValue().getInnerNode(),s=o.getType();for(let e=s.length-1;e>=0;--e){switch(s[e]){case f().ForcePhysicsModel:case f().WindPhysicsModel:t.push(o);break;case f().BoundedPhysicsModel:i.push(o);break;default:continue}break}}catch{}for(const e of i)e.addInterest("set_boundedPhysics__",this),e.addInterest("set_bbox__",this);this.set_boundedPhysics__()},set_boundedPhysics__(){const e=this.getBrowser().getContext(),t=this.boundedPhysicsModelNodes,i=this.boundedNormals,n=this.boundedVertices;i.length=0,n.length=0;for(let e=0,o=t.length;e<o;++e)t[e].addGeometry(i,n);const o=new we(n,i).toArray([]),s=n.length/4,r=i.length/3,a=o.length/4,c=Math.ceil(Math.sqrt(s+r+a)),d=new Float32Array(c*c*4);this.boundedVerticesIndex=0,this.boundedNormalsIndex=s,this.boundedHierarchyIndex=this.boundedNormalsIndex+r,this.boundedHierarchyRoot=this.boundedHierarchyIndex+a-1,d.set(n);for(let e=4*this.boundedNormalsIndex,t=0,n=i.length;t<n;e+=4,t+=3)d[e+0]=i[t+0],d[e+1]=i[t+1],d[e+2]=i[t+2];d.set(o,4*this.boundedHierarchyIndex),c&&(e.bindTexture(e.TEXTURE_2D,this.boundedTexture),e.texImage2D(e.TEXTURE_2D,0,e.RGBA32F,c,c,0,e.RGBA,e.FLOAT,d))},set_colorRamp__(){this.colorRampNode&&this.colorRampNode.removeInterest("set_color__",this),this.colorRampNode=M()(f().X3DColorNode,this._color),this.colorRampNode&&this.colorRampNode.addInterest("set_color__",this),this.set_color__(),this.set_transparent__()},set_color__(){const e=this.getBrowser().getContext(),t=this._colorKey,i=t.length,n=Math.ceil(Math.sqrt(2*i));let o=this.colorRamp;n*n*4>o.length&&(o=this.colorRamp=new Float32Array(n*n*4));for(let e=0;e<i;++e)o[4*e]=t[e];this.colorRampNode?o.set(this.colorRampNode.addColors([],i).slice(0,4*i),4*i):o.fill(1,4*i),n&&(e.bindTexture(e.TEXTURE_2D,this.colorRampTexture),e.texImage2D(e.TEXTURE_2D,0,e.RGBA32F,n,n,0,e.RGBA,e.FLOAT,o)),this.numColors=i,this.geometryContext.colorMaterial=!(!i||!this.colorRampNode),this.geometryContext.updateGeometryKey(),this.updateVertexArrays()},set_texCoordRamp__(){this.texCoordRampNode&&this.texCoordRampNode.removeInterest("set_texCoord__",this),this.texCoordRampNode=M()(f().X3DTextureCoordinateNode,this._texCoord),this.texCoordRampNode&&this.texCoordRampNode.addInterest("set_texCoord__",this),this.set_texCoord__()},set_texCoord__(){const e=this.getBrowser().getContext(),t=this._texCoordKey,i=t.length,n=Math.ceil(Math.sqrt(i+i*this.texCoordCount));let o=this.texCoordRamp;n*n*4>o.length?o=this.texCoordRamp=new Float32Array(n*n*4):o.fill(0);for(let e=0;e<i;++e)o[4*e]=t[e];this.texCoordRampNode&&o.set(this.texCoordRampNode.addPoints([]).slice(0,i*this.texCoordCount*4),4*i),n&&(e.bindTexture(e.TEXTURE_2D,this.texCoordRampTexture),e.texImage2D(e.TEXTURE_2D,0,e.RGBA32F,n,n,0,e.RGBA,e.FLOAT,o)),this.numTexCoords=this.texCoordRampNode?i:0,this.updateVertexArrays()},updateVertexArrays(){this.inputParticles.vertexArrayObject.update(),this.outputParticles.vertexArrayObject.update(),this.inputParticles.thickLinesVertexArrayObject.update(),this.outputParticles.thickLinesVertexArrayObject.update()},createTexture(){const e=this.getBrowser().getContext(),t=e.createTexture();return e.bindTexture(e.TEXTURE_2D,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texImage2D(e.TEXTURE_2D,0,e.RGBA32F,1,1,0,e.RGBA,e.FLOAT,new Float32Array(4)),t},createBuffer(){const e=this.getBrowser().getContext(),t=e.createBuffer();return e.bindBuffer(e.ARRAY_BUFFER,t),e.bufferData(e.ARRAY_BUFFER,new Uint32Array,e.DYNAMIC_DRAW),t},resizeBuffers(e){const t=this.getBrowser().getContext(),i=this.maxParticles,n=this.particlesStride,o=Object.assign(t.createBuffer(),this.outputParticles),s=new Uint8Array(i*n);t.bindBuffer(t.ARRAY_BUFFER,this.inputParticles),t.bufferData(t.ARRAY_BUFFER,s,t.DYNAMIC_DRAW),t.bindBuffer(t.COPY_READ_BUFFER,this.outputParticles),t.bindBuffer(t.ARRAY_BUFFER,o),t.bufferData(t.ARRAY_BUFFER,s,t.DYNAMIC_DRAW),t.copyBufferSubData(t.COPY_READ_BUFFER,t.ARRAY_BUFFER,0,0,Math.min(i*n,e*n)),t.deleteBuffer(this.outputParticles),this.outputParticles=o},animateParticles(){const e=this.getBrowser(),t=e.getContext(),i=this.emitterNode,n=1/Math.max(10,this.getBrowser().getCurrentFrameRate());let o=this.deltaTime=(14*this.deltaTime+n)/15;if(i.isExplosive()){const e=Date.now()/1e3,t=this.particleLifetime+this.particleLifetime*this.lifetimeVariation;e-this.creationTime>t?(this.creationTime=e,this.numParticles=this.maxParticles,this.createParticles=this._createParticles.getValue(),o=Number.POSITIVE_INFINITY,this.set_objects__()):this.createParticles=!1}else if(this.createParticles=this._createParticles.getValue(),this.numParticles<this.maxParticles){const e=Date.now()/1e3,t=Math.max(0,Math.floor((e-this.creationTime)*this.maxParticles/this.particleLifetime));t&&(this.creationTime=e),this.numParticles=Math.min(this.maxParticles,this.numParticles+t),this.set_objects__()}if(i.getMass()){const e=this.forcePhysicsModelNodes;let n=e.length,s=this.forces,r=o/i.getMass();4*n>s.length&&(s=this.forces=new Float32Array(4*n));let a=0;for(let t=0;t<n;++t)a+=!e[t].addForce(t-a,i,r,s);this.numForces=n-=a,n&&(t.bindTexture(t.TEXTURE_2D,this.forcesTexture),t.texImage2D(t.TEXTURE_2D,0,t.RGBA32F,n,1,0,t.RGBA,t.FLOAT,s))}else this.numForces=0;const s=this.outputParticles;this.outputParticles=this.inputParticles,this.inputParticles=s,i.animate(this,o),e.addBrowserEvent()},updateSprite:(()=>{const e=new Float32Array(Oe),t=[new(w())(-.5,-.5,0),new(w())(.5,-.5,0),new(w())(.5,.5,0),new(w())(-.5,-.5,0),new(w())(.5,.5,0),new(w())(-.5,.5,0)],i=new(w()),n=new(w());return function(o,s){for(let t=0;t<3;++t)e[24+t]=s[6+t];n.set(this._particleSize.x,this._particleSize.y,1);for(let o=0;o<6;++o){const r=27+4*o;s.multVecMatrix(i.assign(t[o]).multVec(n)),e[r+0]=i.x,e[r+1]=i.y,e[r+2]=i.z}o.bindBuffer(o.ARRAY_BUFFER,this.geometryBuffer),o.bufferData(o.ARRAY_BUFFER,e,o.DYNAMIC_DRAW)}})(),intersectsBox(e,t){},displaySimple(e,t,i){switch(this.geometryType){case m().LINE:this.lineGeometryNode.displaySimpleInstanced(e,i,this);break;case m().GEOMETRY:this.getGeometry().displaySimpleInstanced(e,i,this);break;case m().SPRITE:this.updateSprite(e,this.getScreenAlignedRotation(t.modelViewMatrix));default:{const t=this.outputParticles;if(t.vertexArrayObject.enable(i.getProgram())){const n=this.particlesStride;i.enableParticleAttribute(e,t,n,this.particleOffset,1),i.enableInstanceMatrixAttribute(e,t,n,this.matrixOffset,1),i.enableVertexAttribute(e,this.geometryBuffer,0,this.verticesOffset)}e.drawArraysInstanced(this.primitiveMode,0,this.vertexCount,this.numParticles);break}}},display(e,t){switch(this.geometryType){case m().LINE:this.lineGeometryNode.displayInstanced(e,t,this);break;case m().GEOMETRY:this.getGeometry().displayInstanced(e,t,this);break;case m().SPRITE:this.updateSprite(e,this.getScreenAlignedRotation(t.modelViewMatrix));case m().QUAD:case m().TRIANGLE:{const i=le().prototype.determinant3.call(t.modelViewMatrix)>0;e.frontFace(i?e.CCW:e.CW),e.enable(e.CULL_FACE)}default:{const i=this.get