UNPKG

x_ite

Version:

X_ITE X3D Browser, view and manipulate X3D, VRML, glTF and other 3D sources in HTML.

1,025 lines (814 loc) 142 kB
/* X_ITE v12.2.3 */ const __X_ITE_X3D__ = window [Symbol .for ("X_ITE.X3D-12.2.3")]; /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ // The require scope /******/ var __webpack_require__ = {}; /******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? /******/ () => (module['default']) : /******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /************************************************************************/ // UNUSED EXPORTS: default ;// external "__X_ITE_X3D__ .Components" const external_X_ITE_X3D_Components_namespaceObject = __X_ITE_X3D__ .Components; var external_X_ITE_X3D_Components_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_Components_namespaceObject); ;// external "__X_ITE_X3D__ .Fields" const external_X_ITE_X3D_Fields_namespaceObject = __X_ITE_X3D__ .Fields; var external_X_ITE_X3D_Fields_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_Fields_namespaceObject); ;// external "__X_ITE_X3D__ .X3DFieldDefinition" const external_X_ITE_X3D_X3DFieldDefinition_namespaceObject = __X_ITE_X3D__ .X3DFieldDefinition; var external_X_ITE_X3D_X3DFieldDefinition_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_X3DFieldDefinition_namespaceObject); ;// external "__X_ITE_X3D__ .FieldDefinitionArray" const external_X_ITE_X3D_FieldDefinitionArray_namespaceObject = __X_ITE_X3D__ .FieldDefinitionArray; var external_X_ITE_X3D_FieldDefinitionArray_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_FieldDefinitionArray_namespaceObject); ;// external "__X_ITE_X3D__ .X3DNode" const external_X_ITE_X3D_X3DNode_namespaceObject = __X_ITE_X3D__ .X3DNode; var external_X_ITE_X3D_X3DNode_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_X3DNode_namespaceObject); ;// external "__X_ITE_X3D__ .Namespace" const external_X_ITE_X3D_Namespace_namespaceObject = __X_ITE_X3D__ .Namespace; var external_X_ITE_X3D_Namespace_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_Namespace_namespaceObject); ;// ./src/x_ite/Browser/ParticleSystems/ParticleSampler.js const ParticleSampler = { forces: Symbol (), colors: Symbol (), texCoords: Symbol (), scales: Symbol (), }; const __default__ = ParticleSampler; ; /* harmony default export */ const ParticleSystems_ParticleSampler = (external_X_ITE_X3D_Namespace_default().add ("ParticleSampler", __default__)); ;// external "__X_ITE_X3D__ .GeometryType" const external_X_ITE_X3D_GeometryType_namespaceObject = __X_ITE_X3D__ .GeometryType; var external_X_ITE_X3D_GeometryType_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_GeometryType_namespaceObject); ;// external "__X_ITE_X3D__ .X3DConstants" const external_X_ITE_X3D_X3DConstants_namespaceObject = __X_ITE_X3D__ .X3DConstants; var external_X_ITE_X3D_X3DConstants_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_X3DConstants_namespaceObject); ;// ./src/x_ite/Browser/ParticleSystems/Line3.glsl.js const Line3_glsl_default_ = /* glsl */ ` #if defined(X3D_BOUNDED_VOLUME)||defined(X3D_VOLUME_EMITTER) struct 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;} #endif ` ; /* harmony default export */ const Line3_glsl = (external_X_ITE_X3D_Namespace_default().add ("Line3.glsl", Line3_glsl_default_)); ;// ./src/x_ite/Browser/ParticleSystems/Plane3.glsl.js const Plane3_glsl_default_ = /* glsl */ ` #if defined(X3D_BOUNDED_VOLUME)||defined(X3D_VOLUME_EMITTER) struct 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;} #endif ` ; /* harmony default export */ const Plane3_glsl = (external_X_ITE_X3D_Namespace_default().add ("Plane3.glsl", Plane3_glsl_default_)); ;// ./src/x_ite/Browser/ParticleSystems/Box3.glsl.js const Box3_glsl_default_ = /* glsl */ ` #if defined(X3D_VOLUME_EMITTER)||defined(X3D_BOUNDED_VOLUME) bool 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;} #endif ` ; /* harmony default export */ const Box3_glsl = (external_X_ITE_X3D_Namespace_default().add ("Box3.glsl", Box3_glsl_default_)); ;// ./src/x_ite/Browser/ParticleSystems/BVH.glsl.js const BVH_glsl_default_ = /* glsl */ ` #if defined(X3D_VOLUME_EMITTER)||defined(X3D_BOUNDED_VOLUME) #define BVH_NODE 0 #define BVH_TRIANGLE 1 #define BVH_STACK_SIZE 32 int 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);} #if defined(X3D_VOLUME_EMITTER) int 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;} #endif #if defined(X3D_BOUNDED_VOLUME) int 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;} #endif #endif ` ; /* harmony default export */ const BVH_glsl = (external_X_ITE_X3D_Namespace_default().add ("BVH.glsl", BVH_glsl_default_)); ;// ./src/x_ite/Components/ParticleSystems/X3DParticleEmitterNode.js function X3DParticleEmitterNode (executionContext) { external_X_ITE_X3D_X3DNode_default().call (this, executionContext); this .addType ((external_X_ITE_X3D_X3DConstants_default()).X3DParticleEmitterNode); this .addChildObjects ((external_X_ITE_X3D_X3DConstants_default()).outputOnly, "bbox_changed", new (external_X_ITE_X3D_Fields_default()).SFTime ()); // Units this ._speed .setUnit ("speed"); this ._mass .setUnit ("mass"); this ._surfaceArea .setUnit ("area"); // Private properties this .defines = [ ]; this .samplers = [ ]; this .uniforms = new Map (); this .callbacks = [ ]; this .functions = [ ]; this .programs = new Map (); } Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (external_X_ITE_X3D_X3DNode_default()).prototype), { initialize () { external_X_ITE_X3D_X3DNode_default().prototype .initialize .call (this); const gl = this .getBrowser () .getContext (); // Create program. this .transformFeedback = gl .createTransformFeedback (); // Initialize fields. 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 ("boundedVolume"); for (const key in ParticleSystems_ParticleSampler) this .addSampler (key); this .addUniform ("speed", "uniform float speed;"); this .addUniform ("variation", "uniform float variation;"); this .addCallback (this .set_speed__); this .addCallback (this .set_variation__); this .addFunction (Line3_glsl); this .addFunction (Plane3_glsl); this .addFunction (Box3_glsl); this .addFunction (BVH_glsl); this .set_on__ (); this .set_mass__ (); this .set_surfaceArea__ (); }, isExplosive () { return false; }, 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 (min, max) { return Math .random () * (max - min) + min; }, getRandomNormal (normal) { const theta = this .getRandomValue (-1, 1) * Math .PI, cphi = this .getRandomValue (-1, 1), phi = Math .acos (cphi), r = Math .sin (phi); return normal .set (Math .sin (theta) * r, Math .cos (theta) * r, cphi); }, animate (particleSystem, deltaTime) { const browser = this .getBrowser (), gl = browser .getContext (), program = this .getProgram (particleSystem), inputParticles = particleSystem .inputParticles; // Start gl .useProgram (program); // Uniforms gl .uniform1i (program .randomSeed, Math .random () * 0xffffffff); gl .uniform1f (program .particleLifetime, particleSystem .particleLifetime); gl .uniform1f (program .lifetimeVariation, particleSystem .lifetimeVariation); gl .uniform1f (program .deltaTime, deltaTime); gl .uniform2f (program .particleSize, particleSystem ._particleSize .x, particleSystem ._particleSize .y); // Bounded Physics if (particleSystem .boundedHierarchyRoot > -1) { gl .uniform1i (program .boundedVerticesIndex, particleSystem .boundedVerticesIndex); gl .uniform1i (program .boundedNormalsIndex, particleSystem .boundedNormalsIndex); gl .uniform1i (program .boundedHierarchyIndex, particleSystem .boundedHierarchyIndex); gl .uniform1i (program .boundedHierarchyRoot, particleSystem .boundedHierarchyRoot); gl .activeTexture (gl .TEXTURE0 + program .boundedVolumeTextureUnit); gl .bindTexture (gl .TEXTURE_2D, particleSystem .boundedTexture); } // Forces, Colors, TexCoords, Scales for (const sampler of particleSystem .samplers) { gl .activeTexture (gl .TEXTURE0 + program [sampler]); gl .bindTexture (gl .TEXTURE_2D, particleSystem [sampler]); } // Other textures this .activateTextures (gl, program); // Input attributes if (inputParticles .vertexArrayObject .enable (program)) { const { particlesStride, particleOffsets } = particleSystem; for (const [i, attribute] of program .inputs) { gl .bindBuffer (gl .ARRAY_BUFFER, inputParticles); gl .enableVertexAttribArray (attribute); gl .vertexAttribPointer (attribute, 4, gl .FLOAT, false, particlesStride, particleOffsets [i]); } } // Transform particles. gl .bindFramebuffer (gl .FRAMEBUFFER, browser .getDefaultFramebuffer ()); // Prevent texture feedback loop error, see NYC in Firefox. gl .bindBuffer (gl .ARRAY_BUFFER, null); gl .bindTransformFeedback (gl .TRANSFORM_FEEDBACK, this .transformFeedback); gl .bindBufferBase (gl .TRANSFORM_FEEDBACK_BUFFER, 0, particleSystem .outputParticles); gl .enable (gl .RASTERIZER_DISCARD); gl .beginTransformFeedback (gl .POINTS); gl .drawArrays (gl .POINTS, 0, particleSystem .numParticles); gl .endTransformFeedback (); gl .disable (gl .RASTERIZER_DISCARD); gl .bindTransformFeedback (gl .TRANSFORM_FEEDBACK, null); // DEBUG // const data = new Float32Array (particleSystem .numParticles * (particleSystem .particlesStride / 4)); // gl .bindBuffer (gl .ARRAY_BUFFER, particleSystem .outputParticles); // gl .getBufferSubData (gl .ARRAY_BUFFER, 0, data); // console .log (data .slice (0, particleSystem .particlesStride / 4)); }, addDefine (define) { this .defines .push (define); }, addSampler (name) { this .samplers .push (name); }, addUniform (name, uniform) { this .uniforms .set (name, uniform); }, setUniform (func, name, value1, value2, value3) { const gl = this .getBrowser () .getContext (); for (const program of this .programs .values ()) { gl .useProgram (program); gl [func] (program [name], value1, value2, value3); } }, addCallback (callback) { this .callbacks .push (callback); }, addFunction (func) { this .functions .push (func); }, getProgram (particleSystem) { const { geometryType, createParticles, numColors, numTexCoords, texCoordCount, numScales, numForces, boundedHierarchyRoot } = particleSystem; let key = ""; key += geometryType; key += createParticles && this .on ? 1 : 0; key += "."; key += numColors key += "."; key += numTexCoords; key += "."; key += texCoordCount; key += "."; key += numScales; key += "."; key += numForces key += "."; key += boundedHierarchyRoot; return this .programs .get (key) ?? this .createProgram (key, particleSystem); }, createProgram (key, particleSystem) { const browser = this .getBrowser (), gl = browser .getContext (), defines = this .defines .slice (); defines .push (`#define X3D_GEOMETRY_TYPE ${particleSystem .geometryType}`) defines .push (`${particleSystem .createParticles && this .on ? "#define X3D_CREATE_PARTICLES" : ""}`); defines .push (`#define X3D_NUM_COLORS ${particleSystem .numColors}`); defines .push (`#define X3D_NUM_TEX_COORDS ${particleSystem .numTexCoords}`); defines .push (`#define X3D_TEX_COORDS_COUNT ${particleSystem .texCoordCount}`); defines .push (`#define X3D_NUM_SCALES ${particleSystem .numScales}`); defines .push (`#define X3D_NUM_FORCES ${particleSystem .numForces}`); defines .push (`${particleSystem .boundedHierarchyRoot > -1 ? "#define X3D_BOUNDED_VOLUME" : ""}`); const vertexShaderSource = /* glsl */ `#version 300 es precision highp float;precision highp int;precision highp sampler2D; ${defines .join ("\n")} uniform int randomSeed;uniform float particleLifetime;uniform float lifetimeVariation;uniform float deltaTime;uniform vec2 particleSize; #if X3D_NUM_FORCES>0 uniform sampler2D forces; #endif #if defined(X3D_BOUNDED_VOLUME) uniform int boundedVerticesIndex;uniform int boundedNormalsIndex;uniform int boundedHierarchyIndex;uniform int boundedHierarchyRoot;uniform sampler2D boundedVolume; #endif #if X3D_NUM_COLORS>0 uniform sampler2D colors; #endif #if X3D_NUM_TEX_COORDS>0 uniform sampler2D texCoords; #endif #if X3D_NUM_SCALES>0 uniform sampler2D scales; #endif ${Array .from (this .uniforms .values ()) .join ("\n")} in 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; ${Object .entries ((external_X_ITE_X3D_GeometryType_default())) .map (([k, v]) => `#define ${k} ${v}`) .join ("\n")} const 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;} #if X3D_NUM_TEX_COORDS>0 void 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;}} #endif #if X3D_NUM_COLORS>0||X3D_NUM_SCALES>0||defined(X3D_POLYLINE_EMITTER)||defined(X3D_SURFACE_EMITTER)||defined(X3D_VOLUME_EMITTER) void 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.;}}} #endif #if defined(X3D_SURFACE_EMITTER)||defined(X3D_VOLUME_EMITTER) vec3 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);} #endif ${this .functions .join ("\n")} #if X3D_NUM_TEX_COORDS>0 int getTexCoordIndex0(const in float fraction){int index0=0;interpolate(texCoords,X3D_NUM_TEX_COORDS,fraction,index0);return X3D_NUM_TEX_COORDS+index0*X3D_TEX_COORDS_COUNT;} #else #define getTexCoordIndex0(fraction)(-1) #endif #if X3D_NUM_COLORS>0 vec4 getColor(const in float fraction){int index0;int index1;float weight;interpolate(colors,X3D_NUM_COLORS,fraction,index0,index1,weight);vec4 color0=texelFetch(colors,X3D_NUM_COLORS+index0,0);vec4 color1=texelFetch(colors,X3D_NUM_COLORS+index1,0);return mix(color0,color1,weight);} #else #define getColor(fraction)(vec4(1)) #endif #if X3D_NUM_SCALES>0 vec3 getScale(const in float fraction){int index0;int index1;float weight;interpolate(scales,X3D_NUM_SCALES,fraction,index0,index1,weight);vec3 scale0=texelFetch(scales,X3D_NUM_SCALES+index0,0).xyz;vec3 scale1=texelFetch(scales,X3D_NUM_SCALES+index1,0).xyz;return mix(scale0,scale1,weight);} #else #define getScale(fraction)(vec3(1)) #endif #if defined(X3D_BOUNDED_VOLUME) void 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;} #endif void main(){int life=int(input0[0]);float lifetime=input0[1];float elapsedTime=input0[2]+deltaTime;float fraction=elapsedTime/lifetime;srand((gl_VertexID+randomSeed)*randomSeed);if(elapsedTime>lifetime){lifetime=getRandomLifetime();elapsedTime=0.;fraction=0.;output0=vec4(max(life+1,1),lifetime,elapsedTime,getTexCoordIndex0(fraction)); #if defined(X3D_CREATE_PARTICLES) output1=getColor(fraction);output2=vec4(getRandomVelocity(),0.);output6=getRandomPosition(); #else output1=vec4(0);output2=vec4(0);output6=vec4(NaN); #endif }else{vec3 velocity=input2.xyz;vec4 position=input6; #if X3D_NUM_FORCES>0 for(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;} #endif position.xyz+=velocity*deltaTime; #if defined(X3D_BOUNDED_VOLUME) bounce(deltaTime,input6,position,velocity); #endif output0=vec4(life,lifetime,elapsedTime,getTexCoordIndex0(fraction));output1=getColor(fraction);output2=vec4(velocity,0.);output6=position;}vec3 scale=getScale(fraction); #if X3D_GEOMETRY_TYPE==POINT||X3D_GEOMETRY_TYPE==SPRITE||X3D_GEOMETRY_TYPE==GEOMETRY output3=vec4(scale.x,0.,0.,0.);output4=vec4(0.,scale.y,0.,0.);output5=vec4(0.,0.,scale.z,0.); #elif X3D_GEOMETRY_TYPE==LINE mat3 m=Matrix3(Quaternion(vec3(0.,0.,1.),output2.xyz)); #if X3D_NUM_SCALES>0 m*=mat3(scale.x,0.,0.,0.,scale.y,0.,0.,0.,scale.z); #endif output3=vec4(m[0],0.);output4=vec4(m[1],0.);output5=vec4(m[2],0.); #else vec2 s=particleSize*scale.xy;output3=vec4(s.x,0.,0.,0.);output4=vec4(0.,s.y,0.,0.);output5=vec4(0.,0.,scale.z,0.); #endif }` const fragmentShaderSource = /* glsl */ `#version 300 es precision highp float;void main(){}` // Vertex shader const vertexShader = gl .createShader (gl .VERTEX_SHADER); gl .shaderSource (vertexShader, vertexShaderSource); gl .compileShader (vertexShader); if (!gl .getShaderParameter (vertexShader, gl .COMPILE_STATUS)) console .error (gl .getShaderInfoLog (vertexShader)); // Fragment shader const fragmentShader = gl .createShader (gl .FRAGMENT_SHADER); gl .shaderSource (fragmentShader, fragmentShaderSource); gl .compileShader (fragmentShader); if (!gl .getShaderParameter (fragmentShader, gl .COMPILE_STATUS)) console .error (gl .getShaderInfoLog (fragmentShader)); // Program const program = gl .createProgram (); gl .attachShader (program, vertexShader); gl .attachShader (program, fragmentShader); gl .transformFeedbackVaryings (program, Array .from ({length: 7}, (_, i) => "output" + i), gl .INTERLEAVED_ATTRIBS); gl .linkProgram (program); if (!gl .getProgramParameter (program, gl .LINK_STATUS)) { console .error (`Couldn't initialize particle shader: ${gl .getProgramInfoLog (program)}`); // console .error (vertexShaderSource); } this .programs .set (key, program); gl .useProgram (program); // Attributes program .inputs = [ [0, gl .getAttribLocation (program, "input0")], [2, gl .getAttribLocation (program, "input2")], [6, gl .getAttribLocation (program, "input6")], ]; // Uniforms program .randomSeed = gl .getUniformLocation (program, "randomSeed"); program .particleLifetime = gl .getUniformLocation (program, "particleLifetime"); program .lifetimeVariation = gl .getUniformLocation (program, "lifetimeVariation"); program .deltaTime = gl .getUniformLocation (program, "deltaTime"); program .particleSize = gl .getUniformLocation (program, "particleSize"); program .boundedVerticesIndex = gl .getUniformLocation (program, "boundedVerticesIndex"); program .boundedNormalsIndex = gl .getUniformLocation (program, "boundedNormalsIndex"); program .boundedHierarchyIndex = gl .getUniformLocation (program, "boundedHierarchyIndex"); program .boundedHierarchyRoot = gl .getUniformLocation (program, "boundedHierarchyRoot"); program .boundedVolume = gl .getUniformLocation (program, "boundedVolume"); for (const key in ParticleSystems_ParticleSampler) program [key] = gl .getUniformLocation (program, key); for (const name of this .uniforms .keys ()) program [name] = gl .getUniformLocation (program, name); gl .uniform1f (gl .getUniformLocation (program, "NaN"), NaN); // Samplers for (const name of this .samplers) { const location = gl .getUniformLocation (program, name); gl .uniform1i (location, program [name + "TextureUnit"] = browser .popTextureUnit ()); } for (const [key, symbol] of Object .entries (ParticleSystems_ParticleSampler)) program [symbol] = program [key + "TextureUnit"]; browser .resetTextureUnits (); // Field uniforms for (const callback of this .callbacks) callback .call (this); // Return return program; }, activateTextures () { }, createTexture () { const gl = this .getBrowser () .getContext (), texture = gl .createTexture (); gl .bindTexture (gl .TEXTURE_2D, texture); gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_WRAP_S, gl .CLAMP_TO_EDGE); gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_WRAP_T, gl .CLAMP_TO_EDGE); gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_MAG_FILTER, gl .NEAREST); gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_MIN_FILTER, gl .NEAREST); gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, 1, 1, 0, gl .RGBA, gl .FLOAT, new Float32Array (4)); return texture; }, popTextureUnit (browser, object, property) { const textureUnit = object [property]; if (textureUnit === undefined) return object [property] = browser .popTextureUnit (); return textureUnit; }, }); Object .defineProperties (X3DParticleEmitterNode, external_X_ITE_X3D_X3DNode_default().getStaticProperties ("X3DParticleEmitterNode", "ParticleSystems", 1)); const X3DParticleEmitterNode_default_ = X3DParticleEmitterNode; ; /* harmony default export */ const ParticleSystems_X3DParticleEmitterNode = (external_X_ITE_X3D_Namespace_default().add ("X3DParticleEmitterNode", X3DParticleEmitterNode_default_)); ;// external "__X_ITE_X3D__ .Vector3" const external_X_ITE_X3D_Vector3_namespaceObject = __X_ITE_X3D__ .Vector3; var external_X_ITE_X3D_Vector3_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_Vector3_namespaceObject); ;// ./src/x_ite/Components/ParticleSystems/PointEmitter.js function PointEmitter (executionContext) { ParticleSystems_X3DParticleEmitterNode .call (this, executionContext); this .addType ((external_X_ITE_X3D_X3DConstants_default()).PointEmitter); // Units this ._position .setUnit ("length"); } Object .assign (Object .setPrototypeOf (PointEmitter .prototype, ParticleSystems_X3DParticleEmitterNode .prototype), { initialize () { ParticleSystems_X3DParticleEmitterNode .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 (/* glsl */ `vec3 getRandomVelocity () { if (direction == vec3 (0.0)) return getRandomSphericalVelocity (); else return direction * getRandomSpeed (); }`); this .addFunction (/* glsl */ `vec4 getRandomPosition () { return vec4 (position, 1.0); }`); }, getBBox: (() => { const bboxSize = new (external_X_ITE_X3D_Vector3_default()) (); return function (bbox, { particleLifetime, lifetimeVariation }) { const maxParticleLifetime = particleLifetime * (1 + lifetimeVariation), maxSpeed = this ._speed .getValue () * (1 + this ._variation .getValue ()), s = maxParticleLifetime * maxSpeed * 2; return bbox .set (bboxSize .set (s, s, s), this ._position .getValue ()); }; })(), set_position__ () { const { x, y, z } = this ._position .getValue (); this .setUniform ("uniform3f", "position", x, y, z); this ._bbox_changed .addEvent (); }, set_direction__: (() => { const direction = new (external_X_ITE_X3D_Vector3_default()) (); return function () { const { x, y, z } = direction .assign (this ._direction .getValue ()) .normalize (); this .setUniform ("uniform3f", "direction", x, y, z); }; })(), }); Object .defineProperties (PointEmitter, { ... external_X_ITE_X3D_X3DNode_default().getStaticProperties ("PointEmitter", "ParticleSystems", 1, "emitter", "3.2"), fieldDefinitions: { value: new (external_X_ITE_X3D_FieldDefinitionArray_default()) ([ new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "metadata", new (external_X_ITE_X3D_Fields_default()).SFNode ()), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "on", new (external_X_ITE_X3D_Fields_default()).SFBool (true)), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "position", new (external_X_ITE_X3D_Fields_default()).SFVec3f ()), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "direction", new (external_X_ITE_X3D_Fields_default()).SFVec3f (0, 1, 0)), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "speed", new (external_X_ITE_X3D_Fields_default()).SFFloat ()), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "variation", new (external_X_ITE_X3D_Fields_default()).SFFloat (0.25)), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "mass", new (external_X_ITE_X3D_Fields_default()).SFFloat ()), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "surfaceArea", new (external_X_ITE_X3D_Fields_default()).SFFloat ()), ]), enumerable: true, }, }); const PointEmitter_default_ = PointEmitter; ; /* harmony default export */ const ParticleSystems_PointEmitter = (external_X_ITE_X3D_Namespace_default().add ("PointEmitter", PointEmitter_default_)); ;// ./src/x_ite/Browser/ParticleSystems/X3DParticleSystemsContext.js const _defaultEmitter = Symbol (); function X3DParticleSystemsContext () { } Object .assign (X3DParticleSystemsContext .prototype, { getDefaultEmitter () { return this [_defaultEmitter] ??= (() => { const defaultEmitter = new ParticleSystems_PointEmitter (this .getPrivateScene ()); defaultEmitter .setup (); return defaultEmitter; })(); }, }); const X3DParticleSystemsContext_default_ = X3DParticleSystemsContext; ; /* harmony default export */ const ParticleSystems_X3DParticleSystemsContext = (external_X_ITE_X3D_Namespace_default().add ("X3DParticleSystemsContext", X3DParticleSystemsContext_default_)); ;// ./src/x_ite/Components/ParticleSystems/X3DParticlePhysicsModelNode.js function X3DParticlePhysicsModelNode (executionContext) { external_X_ITE_X3D_X3DNode_default().call (this, executionContext); this .addType ((external_X_ITE_X3D_X3DConstants_default()).X3DParticlePhysicsModelNode); } Object .assign (Object .setPrototypeOf (X3DParticlePhysicsModelNode .prototype, (external_X_ITE_X3D_X3DNode_default()).prototype), { addForce () { }, }); Object .defineProperties (X3DParticlePhysicsModelNode, external_X_ITE_X3D_X3DNode_default().getStaticProperties ("X3DParticlePhysicsModelNode", "ParticleSystems", 1)); const X3DParticlePhysicsModelNode_default_ = X3DParticlePhysicsModelNode; ; /* harmony default export */ const ParticleSystems_X3DParticlePhysicsModelNode = (external_X_ITE_X3D_Namespace_default().add ("X3DParticlePhysicsModelNode", X3DParticlePhysicsModelNode_default_)); ;// external "__X_ITE_X3D__ .X3DCast" const external_X_ITE_X3D_X3DCast_namespaceObject = __X_ITE_X3D__ .X3DCast; var external_X_ITE_X3D_X3DCast_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_X3DCast_namespaceObject); ;// ./src/x_ite/Components/ParticleSystems/BoundedPhysicsModel.js function BoundedPhysicsModel (executionContext) { ParticleSystems_X3DParticlePhysicsModelNode .call (this, executionContext); this .addType ((external_X_ITE_X3D_X3DConstants_default()).BoundedPhysicsModel); } Object .assign (Object .setPrototypeOf (BoundedPhysicsModel .prototype, ParticleSystems_X3DParticlePhysicsModelNode .prototype), { initialize () { ParticleSystems_X3DParticlePhysicsModelNode .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 = external_X_ITE_X3D_X3DCast_default() ((external_X_ITE_X3D_X3DConstants_default()).X3DGeometryNode, this ._geometry); this .geometryNode ?._rebuild .addInterest ("addNodeEvent", this); }, addGeometry (boundedNormals, boundedVertices) { if (!this .geometryNode) return; if (!this ._enabled .getValue ()) return; const damping = this ._damping .getValue (), normals = this .geometryNode .getNormals () .getValue (), vertices = this .geometryNode .getVertices () .getValue (); for (const value of normals) boundedNormals .push (value * damping); for (const value of vertices) boundedVertices .push (value); }, }); Object .defineProperties (BoundedPhysicsModel, { ... external_X_ITE_X3D_X3DNode_default().getStaticProperties ("BoundedPhysicsModel", "ParticleSystems", 2, "physics", "3.2"), fieldDefinitions: { value: new (external_X_ITE_X3D_FieldDefinitionArray_default()) ([ new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "metadata", new (external_X_ITE_X3D_Fields_default()).SFNode ()), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "enabled", new (external_X_ITE_X3D_Fields_default()).SFBool (true)), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "damping", new (external_X_ITE_X3D_Fields_default()).SFFloat (1)), // skip test new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "geometry", new (external_X_ITE_X3D_Fields_default()).SFNode ()), ]), enumerable: true, }, }); const BoundedPhysicsModel_default_ = BoundedPhysicsModel; ; /* harmony default export */ const ParticleSystems_BoundedPhysicsModel = (external_X_ITE_X3D_Namespace_default().add ("BoundedPhysicsModel", BoundedPhysicsModel_default_)); ;// ./src/x_ite/Components/ParticleSystems/ConeEmitter.js function ConeEmitter (executionContext) { ParticleSystems_X3DParticleEmitterNode .call (this, executionContext); this .addType ((external_X_ITE_X3D_X3DConstants_default()).ConeEmitter); // Units this ._position .setUnit ("length"); this ._angle .setUnit ("angle"); } Object .assign (Object .setPrototypeOf (ConeEmitter .prototype, ParticleSystems_X3DParticleEmitterNode .prototype), { initialize () { ParticleSystems_X3DParticleEmitterNode .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 (/* glsl */ `vec3 getRandomVelocity () { if (direction == vec3 (0.0)) { return getRandomSphericalVelocity (); } else { vec3 normal = getRandomNormalWithDirectionAndAngle (direction, angle); float speed = getRandomSpeed (); return normal * speed; } }`); this .addFunction (/* glsl */ `vec4 getRandomPosition () { return vec4 (position, 1.0); }`); }, getBBox: (() => { const bboxSize = new (external_X_ITE_X3D_Vector3_default()) (); return function (bbox, { particleLifetime, lifetimeVariation }) { const maxParticleLifetime = particleLifetime * (1 + lifetimeVariation), maxSpeed = this ._speed .getValue () * (1 + this ._variation .getValue ()), s = maxParticleLifetime * maxSpeed * 2; return bbox .set (bboxSize .set (s, s, s), this ._position .getValue ()); }; })(), set_position__ () { const { x, y, z } = this ._position .getValue (); this .setUniform ("uniform3f", "position", x, y, z ); this ._bbox_changed .addEvent (); }, set_direction__ () { const { x, y, z } = this ._direction .getValue (); this .setUniform ("uniform3f", "direction", x, y, z ); }, set_angle__ () { this .setUniform ("uniform1f", "angle", this ._angle .getValue ()); }, }); Object .defineProperties (ConeEmitter, { ... external_X_ITE_X3D_X3DNode_default().getStaticProperties ("ConeEmitter", "ParticleSystems", 1, "emitter", "3.2"), fieldDefinitions: { value: new (external_X_ITE_X3D_FieldDefinitionArray_default()) ([ new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "metadata", new (external_X_ITE_X3D_Fields_default()).SFNode ()), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "on", new (external_X_ITE_X3D_Fields_default()).SFBool (true)), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "position", new (external_X_ITE_X3D_Fields_default()).SFVec3f ()), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "direction", new (external_X_ITE_X3D_Fields_default()).SFVec3f (0, 1, 0)), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "angle", new (external_X_ITE_X3D_Fields_default()).SFFloat (0.785398)), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "speed", new (external_X_ITE_X3D_Fields_default()).SFFloat ()), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "variation", new (external_X_ITE_X3D_Fields_default()).SFFloat (0.25)), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "mass", new (external_X_ITE_X3D_Fields_default()).SFFloat ()), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "surfaceArea", new (external_X_ITE_X3D_Fields_default()).SFFloat ()), ]), enumerable: true, }, }); const ConeEmitter_default_ = ConeEmitter; ; /* harmony default export */ const ParticleSystems_ConeEmitter = (external_X_ITE_X3D_Namespace_default().add ("ConeEmitter", ConeEmitter_default_)); ;// ./src/x_ite/Components/ParticleSystems/ExplosionEmitter.js function ExplosionEmitter (executionContext) { ParticleSystems_X3DParticleEmitterNode .call (this, executionContext); this .addType ((external_X_ITE_X3D_X3DConstants_default()).ExplosionEmitter); // Units this ._position .setUnit ("length"); } Object .assign (Object .setPrototypeOf (ExplosionEmitter .prototype, ParticleSystems_X3DParticleEmitterNode .prototype), { initialize () { ParticleSystems_X3DParticleEmitterNode .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 (/* glsl */ `vec3 getRandomVelocity () { return getRandomSphericalVelocity (); }`); this .addFunction (/* glsl */ `vec4 getRandomPosition () { return vec4 (position, 1.0); }`); }, getBBox: (() => { const bboxSize = new (external_X_ITE_X3D_Vector3_default()) (); return function (bbox, { particleLifetime, lifetimeVariation }) { const maxParticleLifetime = particleLifetime * (1 + lifetimeVariation), maxSpeed = this ._speed .getValue () * (1 + this