x_ite 12.1.1 → 12.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +4 -4
  2. package/dist/assets/components/AnnotationComponent.js +2 -2
  3. package/dist/assets/components/AnnotationComponent.min.js +2 -2
  4. package/dist/assets/components/CADGeometryComponent.js +2 -2
  5. package/dist/assets/components/CADGeometryComponent.min.js +2 -2
  6. package/dist/assets/components/CubeMapTexturingComponent.js +2 -2
  7. package/dist/assets/components/CubeMapTexturingComponent.min.js +2 -2
  8. package/dist/assets/components/DISComponent.js +2 -2
  9. package/dist/assets/components/DISComponent.min.js +2 -2
  10. package/dist/assets/components/EventUtilitiesComponent.js +2 -2
  11. package/dist/assets/components/EventUtilitiesComponent.min.js +2 -2
  12. package/dist/assets/components/Geometry2DComponent.js +2 -2
  13. package/dist/assets/components/Geometry2DComponent.min.js +2 -2
  14. package/dist/assets/components/GeospatialComponent.js +16 -3
  15. package/dist/assets/components/GeospatialComponent.min.js +2 -2
  16. package/dist/assets/components/HAnimComponent.js +51 -61
  17. package/dist/assets/components/HAnimComponent.min.js +2 -2
  18. package/dist/assets/components/KeyDeviceSensorComponent.js +2 -2
  19. package/dist/assets/components/KeyDeviceSensorComponent.min.js +2 -2
  20. package/dist/assets/components/LayoutComponent.js +2 -2
  21. package/dist/assets/components/LayoutComponent.min.js +2 -2
  22. package/dist/assets/components/NURBSComponent.js +2 -2
  23. package/dist/assets/components/NURBSComponent.min.js +2 -2
  24. package/dist/assets/components/ParticleSystemsComponent.js +221 -113
  25. package/dist/assets/components/ParticleSystemsComponent.min.js +2 -2
  26. package/dist/assets/components/PickingComponent.js +2 -2
  27. package/dist/assets/components/PickingComponent.min.js +2 -2
  28. package/dist/assets/components/RigidBodyPhysicsComponent.js +2 -2
  29. package/dist/assets/components/RigidBodyPhysicsComponent.min.js +2 -2
  30. package/dist/assets/components/ScriptingComponent.js +3 -3
  31. package/dist/assets/components/ScriptingComponent.min.js +2 -2
  32. package/dist/assets/components/TextComponent.js +2 -2
  33. package/dist/assets/components/TextComponent.min.js +2 -2
  34. package/dist/assets/components/TextureProjectionComponent.js +2 -2
  35. package/dist/assets/components/TextureProjectionComponent.min.js +2 -2
  36. package/dist/assets/components/Texturing3DComponent.js +56 -56
  37. package/dist/assets/components/Texturing3DComponent.min.js +2 -2
  38. package/dist/assets/components/VolumeRenderingComponent.js +2 -2
  39. package/dist/assets/components/VolumeRenderingComponent.min.js +2 -2
  40. package/dist/assets/components/WebXRComponent.js +2 -2
  41. package/dist/assets/components/WebXRComponent.min.js +2 -2
  42. package/dist/assets/components/X_ITEComponent.js +2 -2
  43. package/dist/assets/components/X_ITEComponent.min.js +2 -2
  44. package/dist/example.html +1 -1
  45. package/dist/x_ite.css +1 -1
  46. package/dist/x_ite.d.ts +9 -3
  47. package/dist/x_ite.js +50148 -49521
  48. package/dist/x_ite.min.js +2 -2
  49. package/dist/x_ite.min.mjs +2 -2
  50. package/dist/x_ite.mjs +50774 -50148
  51. package/dist/x_ite.zip +0 -0
  52. package/package.json +3 -3
@@ -1,5 +1,5 @@
1
- /* X_ITE v12.1.1 */
2
- const __X_ITE_X3D__ = window [Symbol .for ("X_ITE.X3D-12.1.1")];
1
+ /* X_ITE v12.1.3 */
2
+ const __X_ITE_X3D__ = window [Symbol .for ("X_ITE.X3D-12.1.3")];
3
3
  /******/ (() => { // webpackBootstrap
4
4
  /******/ "use strict";
5
5
  /******/ // The require scope
@@ -54,24 +54,36 @@ var external_X_ITE_X3D_FieldDefinitionArray_default = /*#__PURE__*/__webpack_req
54
54
  ;// external "__X_ITE_X3D__ .X3DNode"
55
55
  const external_X_ITE_X3D_X3DNode_namespaceObject = __X_ITE_X3D__ .X3DNode;
56
56
  var external_X_ITE_X3D_X3DNode_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_X3DNode_namespaceObject);
57
+ ;// external "__X_ITE_X3D__ .Namespace"
58
+ const external_X_ITE_X3D_Namespace_namespaceObject = __X_ITE_X3D__ .Namespace;
59
+ var external_X_ITE_X3D_Namespace_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_Namespace_namespaceObject);
60
+ ;// ./src/x_ite/Browser/ParticleSystems/ParticleSampler.js
61
+ const ParticleSampler = {
62
+ forces: Symbol (),
63
+ colors: Symbol (),
64
+ texCoords: Symbol (),
65
+ scales: Symbol (),
66
+ };
67
+
68
+ const __default__ = ParticleSampler;
69
+ ;
70
+
71
+ /* harmony default export */ const ParticleSystems_ParticleSampler = (external_X_ITE_X3D_Namespace_default().add ("ParticleSampler", __default__));
57
72
  ;// external "__X_ITE_X3D__ .GeometryType"
58
73
  const external_X_ITE_X3D_GeometryType_namespaceObject = __X_ITE_X3D__ .GeometryType;
59
74
  var external_X_ITE_X3D_GeometryType_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_GeometryType_namespaceObject);
60
75
  ;// external "__X_ITE_X3D__ .X3DConstants"
61
76
  const external_X_ITE_X3D_X3DConstants_namespaceObject = __X_ITE_X3D__ .X3DConstants;
62
77
  var external_X_ITE_X3D_X3DConstants_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_X3DConstants_namespaceObject);
63
- ;// external "__X_ITE_X3D__ .Namespace"
64
- const external_X_ITE_X3D_Namespace_namespaceObject = __X_ITE_X3D__ .Namespace;
65
- var external_X_ITE_X3D_Namespace_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_Namespace_namespaceObject);
66
78
  ;// ./src/x_ite/Browser/ParticleSystems/Line3.glsl.js
67
- const __default__ = /* glsl */ `
79
+ const Line3_glsl_default_ = /* glsl */ `
68
80
  #if defined(X3D_BOUNDED_VOLUME)||defined(X3D_VOLUME_EMITTER)
69
81
  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;}
70
82
  #endif
71
83
  `
72
84
  ;
73
85
 
74
- /* harmony default export */ const Line3_glsl = (external_X_ITE_X3D_Namespace_default().add ("Line3.glsl", __default__));
86
+ /* harmony default export */ const Line3_glsl = (external_X_ITE_X3D_Namespace_default().add ("Line3.glsl", Line3_glsl_default_));
75
87
  ;// ./src/x_ite/Browser/ParticleSystems/Plane3.glsl.js
76
88
  const Plane3_glsl_default_ = /* glsl */ `
77
89
  #if defined(X3D_BOUNDED_VOLUME)||defined(X3D_VOLUME_EMITTER)
@@ -118,6 +130,7 @@ int getIntersections(const in sampler2D volume,const in int verticesIndex,const
118
130
 
119
131
 
120
132
 
133
+
121
134
  function X3DParticleEmitterNode (executionContext)
122
135
  {
123
136
  external_X_ITE_X3D_X3DNode_default().call (this, executionContext);
@@ -162,10 +175,10 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (exte
162
175
  this ._mass .addInterest ("set_mass__", this);
163
176
  this ._surfaceArea .addInterest ("set_surfaceArea__", this);
164
177
 
165
- this .addSampler ("forces");
166
178
  this .addSampler ("boundedVolume");
167
- this .addSampler ("colorRamp");
168
- this .addSampler ("texCoordRamp");
179
+
180
+ for (const key in ParticleSystems_ParticleSampler)
181
+ this .addSampler (key);
169
182
 
170
183
  this .addUniform ("speed", "uniform float speed;");
171
184
  this .addUniform ("variation", "uniform float variation;");
@@ -250,14 +263,6 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (exte
250
263
  gl .uniform1f (program .deltaTime, deltaTime);
251
264
  gl .uniform2f (program .particleSize, particleSystem ._particleSize .x, particleSystem ._particleSize .y);
252
265
 
253
- // Forces
254
-
255
- if (particleSystem .numForces)
256
- {
257
- gl .activeTexture (gl .TEXTURE0 + program .forcesTextureUnit);
258
- gl .bindTexture (gl .TEXTURE_2D, particleSystem .forcesTexture);
259
- }
260
-
261
266
  // Bounded Physics
262
267
 
263
268
  if (particleSystem .boundedHierarchyRoot > -1)
@@ -271,22 +276,12 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (exte
271
276
  gl .bindTexture (gl .TEXTURE_2D, particleSystem .boundedTexture);
272
277
  }
273
278
 
274
- // Colors
275
-
276
- if (particleSystem .numColors)
277
- {
278
- gl .activeTexture (gl .TEXTURE0 + program .colorRampTextureUnit);
279
- gl .bindTexture (gl .TEXTURE_2D, particleSystem .colorRampTexture);
280
- }
281
-
282
- // TexCoords
279
+ // Forces, Colors, TexCoords, Scales
283
280
 
284
- if (particleSystem .numTexCoords)
281
+ for (const sampler of particleSystem .samplers)
285
282
  {
286
- gl .uniform1i (program .texCoordCount, particleSystem .texCoordCount);
287
-
288
- gl .activeTexture (gl .TEXTURE0 + program .texCoordRampTextureUnit);
289
- gl .bindTexture (gl .TEXTURE_2D, particleSystem .texCoordRampTexture);
283
+ gl .activeTexture (gl .TEXTURE0 + program [sampler]);
284
+ gl .bindTexture (gl .TEXTURE_2D, particleSystem [sampler]);
290
285
  }
291
286
 
292
287
  // Other textures
@@ -359,7 +354,16 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (exte
359
354
  },
360
355
  getProgram (particleSystem)
361
356
  {
362
- const { geometryType, createParticles, numColors, numTexCoords, numForces, boundedHierarchyRoot } = particleSystem;
357
+ const {
358
+ geometryType,
359
+ createParticles,
360
+ numColors,
361
+ numTexCoords,
362
+ texCoordCount,
363
+ numScales,
364
+ numForces,
365
+ boundedHierarchyRoot
366
+ } = particleSystem;
363
367
 
364
368
  let key = "";
365
369
 
@@ -370,6 +374,10 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (exte
370
374
  key += ".";
371
375
  key += numTexCoords;
372
376
  key += ".";
377
+ key += texCoordCount;
378
+ key += ".";
379
+ key += numScales;
380
+ key += ".";
373
381
  key += numForces
374
382
  key += ".";
375
383
  key += boundedHierarchyRoot;
@@ -388,6 +396,8 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (exte
388
396
  defines .push (`${particleSystem .createParticles && this .on ? "#define X3D_CREATE_PARTICLES" : ""}`);
389
397
  defines .push (`#define X3D_NUM_COLORS ${particleSystem .numColors}`);
390
398
  defines .push (`#define X3D_NUM_TEX_COORDS ${particleSystem .numTexCoords}`);
399
+ defines .push (`#define X3D_TEX_COORDS_COUNT ${particleSystem .texCoordCount}`);
400
+ defines .push (`#define X3D_NUM_SCALES ${particleSystem .numScales}`);
391
401
  defines .push (`#define X3D_NUM_FORCES ${particleSystem .numForces}`);
392
402
  defines .push (`${particleSystem .boundedHierarchyRoot > -1 ? "#define X3D_BOUNDED_VOLUME" : ""}`);
393
403
 
@@ -402,41 +412,49 @@ uniform sampler2D forces;
402
412
  uniform int boundedVerticesIndex;uniform int boundedNormalsIndex;uniform int boundedHierarchyIndex;uniform int boundedHierarchyRoot;uniform sampler2D boundedVolume;
403
413
  #endif
404
414
  #if X3D_NUM_COLORS>0
405
- uniform sampler2D colorRamp;
415
+ uniform sampler2D colors;
406
416
  #endif
407
417
  #if X3D_NUM_TEX_COORDS>0
408
- uniform int texCoordCount;uniform sampler2D texCoordRamp;
418
+ uniform sampler2D texCoords;
419
+ #endif
420
+ #if X3D_NUM_SCALES>0
421
+ uniform sampler2D scales;
409
422
  #endif
410
423
  ${Array .from (this .uniforms .values ()) .join ("\n")}
411
424
  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;
412
425
  ${Object .entries ((external_X_ITE_X3D_GeometryType_default())) .map (([k, v]) => `#define ${k} ${v}`) .join ("\n")}
413
426
  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;}
414
- #if X3D_NUM_COLORS>0||defined(X3D_POLYLINE_EMITTER)||defined(X3D_SURFACE_EMITTER)||defined(X3D_VOLUME_EMITTER)
415
- 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.;}}}
416
- #endif
417
427
  #if X3D_NUM_TEX_COORDS>0
418
428
  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;}}
419
429
  #endif
430
+ #if X3D_NUM_COLORS>0||X3D_NUM_SCALES>0||defined(X3D_POLYLINE_EMITTER)||defined(X3D_SURFACE_EMITTER)||defined(X3D_VOLUME_EMITTER)
431
+ 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.;}}}
432
+ #endif
420
433
  #if defined(X3D_SURFACE_EMITTER)||defined(X3D_VOLUME_EMITTER)
421
434
  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);}
422
435
  #endif
423
436
  ${this .functions .join ("\n")}
437
+ #if X3D_NUM_TEX_COORDS>0
438
+ 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;}
439
+ #else
440
+ #define getTexCoordIndex0(fraction)(-1)
441
+ #endif
424
442
  #if X3D_NUM_COLORS>0
425
- vec4 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);}
443
+ 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);}
444
+ #else
445
+ #define getColor(fraction)(vec4(1))
446
+ #endif
447
+ #if X3D_NUM_SCALES>0
448
+ 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);}
426
449
  #else
427
- #define getColor(lifetime,elapsedTime)(vec4(1))
450
+ #define getScale(fraction)(vec3(1))
428
451
  #endif
429
452
  #if defined(X3D_BOUNDED_VOLUME)
430
453
  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;}
431
454
  #endif
432
- #if X3D_NUM_TEX_COORDS>0
433
- int 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;}
434
- #else
435
- #define getTexCoordIndex0(lifetime,elapsedTime)(-1)
436
- #endif
437
- void 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));
455
+ 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));
438
456
  #if defined(X3D_CREATE_PARTICLES)
439
- output1=getColor(lifetime,elapsedTime);output2=vec4(getRandomVelocity(),0.);output6=getRandomPosition();
457
+ output1=getColor(fraction);output2=vec4(getRandomVelocity(),0.);output6=getRandomPosition();
440
458
  #else
441
459
  output1=vec4(0);output2=vec4(0);output6=vec4(NaN);
442
460
  #endif
@@ -448,13 +466,17 @@ position.xyz+=velocity*deltaTime;
448
466
  #if defined(X3D_BOUNDED_VOLUME)
449
467
  bounce(deltaTime,input6,position,velocity);
450
468
  #endif
451
- output0=vec4(life,lifetime,elapsedTime,getTexCoordIndex0(lifetime,elapsedTime));output1=getColor(lifetime,elapsedTime);output2=vec4(velocity,0.);output6=position;}
469
+ output0=vec4(life,lifetime,elapsedTime,getTexCoordIndex0(fraction));output1=getColor(fraction);output2=vec4(velocity,0.);output6=position;}vec3 scale=getScale(fraction);
452
470
  #if X3D_GEOMETRY_TYPE==POINT||X3D_GEOMETRY_TYPE==SPRITE||X3D_GEOMETRY_TYPE==GEOMETRY
453
- output3=vec4(1.,0.,0.,0.);output4=vec4(0.,1.,0.,0.);output5=vec4(0.,0.,1.,0.);
471
+ output3=vec4(scale.x,0.,0.,0.);output4=vec4(0.,scale.y,0.,0.);output5=vec4(0.,0.,scale.z,0.);
454
472
  #elif X3D_GEOMETRY_TYPE==LINE
455
- mat3 m=Matrix3(Quaternion(vec3(0.,0.,1.),output2.xyz));output3=vec4(m[0],0.);output4=vec4(m[1],0.);output5=vec4(m[2],0.);
473
+ mat3 m=Matrix3(Quaternion(vec3(0.,0.,1.),output2.xyz));
474
+ #if X3D_NUM_SCALES>0
475
+ m*=mat3(scale.x,0.,0.,0.,scale.y,0.,0.,0.,scale.z);
476
+ #endif
477
+ output3=vec4(m[0],0.);output4=vec4(m[1],0.);output5=vec4(m[2],0.);
456
478
  #else
457
- output3=vec4(particleSize.x,0.,0.,0.);output4=vec4(0.,particleSize.y,0.,0.);output5=vec4(0.,0.,1.,0.);
479
+ 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.);
458
480
  #endif
459
481
  }`
460
482
 
@@ -516,18 +538,14 @@ precision highp float;void main(){}`
516
538
  program .deltaTime = gl .getUniformLocation (program, "deltaTime");
517
539
  program .particleSize = gl .getUniformLocation (program, "particleSize");
518
540
 
519
- program .forces = gl .getUniformLocation (program, "forces");
520
-
521
541
  program .boundedVerticesIndex = gl .getUniformLocation (program, "boundedVerticesIndex");
522
542
  program .boundedNormalsIndex = gl .getUniformLocation (program, "boundedNormalsIndex");
523
543
  program .boundedHierarchyIndex = gl .getUniformLocation (program, "boundedHierarchyIndex");
524
544
  program .boundedHierarchyRoot = gl .getUniformLocation (program, "boundedHierarchyRoot");
525
545
  program .boundedVolume = gl .getUniformLocation (program, "boundedVolume");
526
546
 
527
- program .colorRamp = gl .getUniformLocation (program, "colorRamp");
528
-
529
- program .texCoordCount = gl .getUniformLocation (program, "texCoordCount");
530
- program .texCoordRamp = gl .getUniformLocation (program, "texCoordRamp");
547
+ for (const key in ParticleSystems_ParticleSampler)
548
+ program [key] = gl .getUniformLocation (program, key);
531
549
 
532
550
  for (const name of this .uniforms .keys ())
533
551
  program [name] = gl .getUniformLocation (program, name);
@@ -543,6 +561,9 @@ precision highp float;void main(){}`
543
561
  gl .uniform1i (location, program [name + "TextureUnit"] = browser .getTextureUnit ());
544
562
  }
545
563
 
564
+ for (const [key, symbol] of Object .entries (ParticleSystems_ParticleSampler))
565
+ program [symbol] = program [key + "TextureUnit"];
566
+
546
567
  browser .resetTextureUnits ();
547
568
 
548
569
  // Field uniforms
@@ -1489,6 +1510,7 @@ const BVH_default_ = BVH;
1489
1510
 
1490
1511
 
1491
1512
 
1513
+
1492
1514
  const PointGeometry = new Float32Array ([0, 0, 0, 1]);
1493
1515
 
1494
1516
  // p4 ------ p3
@@ -1541,6 +1563,8 @@ function ParticleSystem (executionContext)
1541
1563
 
1542
1564
  this .maxParticles = 0;
1543
1565
  this .numParticles = 0;
1566
+ this .spriteSize = new (external_X_ITE_X3D_Vector3_default()) ();
1567
+ this .samplers = new Set ();
1544
1568
  this .forcePhysicsModelNodes = [ ];
1545
1569
  this .forces = new Float32Array (4);
1546
1570
  this .boundedPhysicsModelNodes = [ ];
@@ -1548,6 +1572,7 @@ function ParticleSystem (executionContext)
1548
1572
  this .boundedVertices = [ ];
1549
1573
  this .colorRamp = new Float32Array ();
1550
1574
  this .texCoordRamp = new Float32Array ();
1575
+ this .scaleRamp = new Float32Array ();
1551
1576
  this .geometryContext = new (external_X_ITE_X3D_GeometryContext_default()) ({ textureCoordinateNode: browser .getDefaultTextureCoordinate () });
1552
1577
  this .creationTime = 0;
1553
1578
  this .pauseTime = 0;
@@ -1592,6 +1617,8 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (external_X_I
1592
1617
  this ._color .addInterest ("set_colorRamp__", this);
1593
1618
  this ._texCoordKey .addInterest ("set_texCoord__", this);
1594
1619
  this ._texCoord .addInterest ("set_texCoordRamp__", this);
1620
+ this ._scaleKey .addInterest ("set_scale__", this);
1621
+ this ._scale .addInterest ("set_scaleRamp__", this);
1595
1622
 
1596
1623
  // Create particles stuff.
1597
1624
 
@@ -1607,12 +1634,12 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (external_X_I
1607
1634
  thickLinesVertexArrayObject: new (external_X_ITE_X3D_VertexArray_default()) (gl),
1608
1635
  });
1609
1636
 
1610
- // Create forces stuff.
1637
+ // Create textures for forces, colors, texCoords, scales.
1611
1638
 
1612
- this .forcesTexture = this .createTexture ();
1613
- this .boundedTexture = this .createTexture ();
1614
- this .colorRampTexture = this .createTexture ();
1615
- this .texCoordRampTexture = this .createTexture ();
1639
+ this .boundedTexture = this .createTexture ();
1640
+
1641
+ for (const symbol of Object .values (ParticleSystems_ParticleSampler))
1642
+ this [symbol] = this .createTexture ();
1616
1643
 
1617
1644
  // Create GL stuff.
1618
1645
 
@@ -1644,6 +1671,7 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (external_X_I
1644
1671
  this .set_physics__ ();
1645
1672
  this .set_colorRamp__ ();
1646
1673
  this .set_texCoordRamp__ ();
1674
+ this .set_scaleRamp__ ();
1647
1675
  this .set_bbox__ ();
1648
1676
  },
1649
1677
  getShapeKey ()
@@ -1839,7 +1867,6 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (external_X_I
1839
1867
 
1840
1868
  gl .bindBuffer (gl .ARRAY_BUFFER, this .geometryBuffer);
1841
1869
  gl .bufferData (gl .ARRAY_BUFFER, QuadGeometry, gl .DYNAMIC_DRAW);
1842
-
1843
1870
  break;
1844
1871
  }
1845
1872
  case (external_X_ITE_X3D_GeometryType_default()).GEOMETRY:
@@ -1883,6 +1910,8 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (external_X_I
1883
1910
  {
1884
1911
  this .lineCoordinateNode ._point [0] .z = -this ._particleSize .y / 2;
1885
1912
  this .lineCoordinateNode ._point [1] .z = +this ._particleSize .y / 2;
1913
+
1914
+ this .spriteSize .set (... this ._particleSize);
1886
1915
  },
1887
1916
  set_emitter__ ()
1888
1917
  {
@@ -2001,13 +2030,11 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (external_X_I
2001
2030
  },
2002
2031
  set_colorRamp__ ()
2003
2032
  {
2004
- if (this .colorRampNode)
2005
- this .colorRampNode .removeInterest ("set_color__", this);
2033
+ this .colorRampNode ?.removeInterest ("set_color__", this);
2006
2034
 
2007
2035
  this .colorRampNode = external_X_ITE_X3D_X3DCast_default() ((external_X_ITE_X3D_X3DConstants_default()).X3DColorNode, this ._color);
2008
2036
 
2009
- if (this .colorRampNode)
2010
- this .colorRampNode .addInterest ("set_color__", this);
2037
+ this .colorRampNode ?.addInterest ("set_color__", this);
2011
2038
 
2012
2039
  this .set_color__ ();
2013
2040
  this .set_transparent__ ();
@@ -2015,76 +2042,132 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (external_X_I
2015
2042
  set_color__ ()
2016
2043
  {
2017
2044
  const
2018
- gl = this .getBrowser () .getContext (),
2019
- colorKey = this ._colorKey,
2020
- numColors = colorKey .length,
2021
- textureSize = Math .ceil (Math .sqrt (numColors * 2));
2045
+ gl = this .getBrowser () .getContext (),
2046
+ key = this ._colorKey,
2047
+ numKeys = key .length,
2048
+ textureSize = Math .ceil (Math .sqrt (numKeys * 2));
2022
2049
 
2023
- let colorRamp = this .colorRamp;
2050
+ let ramp = this .colorRamp;
2024
2051
 
2025
- if (textureSize * textureSize * 4 > colorRamp .length)
2026
- colorRamp = this .colorRamp = new Float32Array (textureSize * textureSize * 4);
2052
+ if (textureSize * textureSize * 4 > ramp .length)
2053
+ ramp = this .colorRamp = new Float32Array (textureSize * textureSize * 4);
2027
2054
 
2028
- for (let i = 0; i < numColors; ++ i)
2029
- colorRamp [i * 4] = colorKey [i];
2055
+ for (let i = 0; i < numKeys; ++ i)
2056
+ ramp [i * 4] = key [i];
2030
2057
 
2031
2058
  if (this .colorRampNode)
2032
- colorRamp .set (this .colorRampNode .addColors ([ ], numColors) .slice (0, numColors * 4), numColors * 4);
2059
+ ramp .set (this .colorRampNode .addColors ([ ], numKeys) .slice (0, numKeys * 4), numKeys * 4);
2033
2060
  else
2034
- colorRamp .fill (1, numColors * 4);
2061
+ ramp .fill (1, numKeys * 4);
2035
2062
 
2036
2063
  if (textureSize)
2037
2064
  {
2038
- gl .bindTexture (gl .TEXTURE_2D, this .colorRampTexture);
2039
- gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, textureSize, textureSize, 0, gl .RGBA, gl .FLOAT, colorRamp);
2040
- }
2065
+ gl .bindTexture (gl .TEXTURE_2D, this [ParticleSystems_ParticleSampler .colors]);
2066
+ gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, textureSize, textureSize, 0, gl .RGBA, gl .FLOAT, ramp);
2067
+ }
2068
+
2069
+ this .numColors = numKeys;
2070
+ this .geometryContext .colorMaterial = !! (numKeys && this .colorRampNode);
2041
2071
 
2042
- this .numColors = numColors;
2043
- this .geometryContext .colorMaterial = !! (numColors && this .colorRampNode);
2072
+ if (numKeys)
2073
+ this .samplers .add (ParticleSystems_ParticleSampler .colors);
2074
+ else
2075
+ this .samplers .delete (ParticleSystems_ParticleSampler .colors);
2044
2076
 
2045
2077
  this .geometryContext .updateGeometryKey ();
2046
2078
  this .updateVertexArrays ();
2047
2079
  },
2048
2080
  set_texCoordRamp__ ()
2049
2081
  {
2050
- if (this .texCoordRampNode)
2051
- this .texCoordRampNode .removeInterest ("set_texCoord__", this);
2082
+ this .texCoordRampNode ?.removeInterest ("set_texCoord__", this);
2052
2083
 
2053
2084
  this .texCoordRampNode = external_X_ITE_X3D_X3DCast_default() ((external_X_ITE_X3D_X3DConstants_default()).X3DTextureCoordinateNode, this ._texCoord);
2054
2085
 
2055
- if (this .texCoordRampNode)
2056
- this .texCoordRampNode .addInterest ("set_texCoord__", this);
2086
+ this .texCoordRampNode ?.addInterest ("set_texCoord__", this);
2057
2087
 
2058
2088
  this .set_texCoord__ ();
2059
2089
  },
2060
2090
  set_texCoord__ ()
2061
2091
  {
2062
2092
  const
2063
- gl = this .getBrowser () .getContext (),
2064
- texCoordKey = this ._texCoordKey,
2065
- numTexCoords = texCoordKey .length,
2066
- textureSize = Math .ceil (Math .sqrt (numTexCoords + numTexCoords * this .texCoordCount));
2093
+ gl = this .getBrowser () .getContext (),
2094
+ key = this ._texCoordKey,
2095
+ numKeys = key .length,
2096
+ textureSize = Math .ceil (Math .sqrt (numKeys + numKeys * this .texCoordCount));
2067
2097
 
2068
- let texCoordRamp = this .texCoordRamp;
2098
+ let ramp = this .texCoordRamp;
2069
2099
 
2070
- if (textureSize * textureSize * 4 > texCoordRamp .length)
2071
- texCoordRamp = this .texCoordRamp = new Float32Array (textureSize * textureSize * 4);
2100
+ if (textureSize * textureSize * 4 > ramp .length)
2101
+ ramp = this .texCoordRamp = new Float32Array (textureSize * textureSize * 4);
2072
2102
  else
2073
- texCoordRamp .fill (0);
2103
+ ramp .fill (0);
2074
2104
 
2075
- for (let i = 0; i < numTexCoords; ++ i)
2076
- texCoordRamp [i * 4] = texCoordKey [i];
2105
+ for (let i = 0; i < numKeys; ++ i)
2106
+ ramp [i * 4] = key [i];
2077
2107
 
2078
2108
  if (this .texCoordRampNode)
2079
- texCoordRamp .set (this .texCoordRampNode .addPoints ([ ]) .slice (0, numTexCoords * this .texCoordCount * 4), numTexCoords * 4);
2109
+ ramp .set (this .texCoordRampNode .addPoints ([ ]) .slice (0, numKeys * this .texCoordCount * 4), numKeys * 4);
2080
2110
 
2081
2111
  if (textureSize)
2082
2112
  {
2083
- gl .bindTexture (gl .TEXTURE_2D, this .texCoordRampTexture);
2084
- gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, textureSize, textureSize, 0, gl .RGBA, gl .FLOAT, texCoordRamp);
2113
+ gl .bindTexture (gl .TEXTURE_2D, this [ParticleSystems_ParticleSampler .texCoords]);
2114
+ gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, textureSize, textureSize, 0, gl .RGBA, gl .FLOAT, ramp);
2085
2115
  }
2086
2116
 
2087
- this .numTexCoords = this .texCoordRampNode ? numTexCoords : 0;
2117
+ this .numTexCoords = this .texCoordRampNode ? numKeys : 0;
2118
+
2119
+ if (numKeys)
2120
+ this .samplers .add (ParticleSystems_ParticleSampler .texCoords);
2121
+ else
2122
+ this .samplers .delete (ParticleSystems_ParticleSampler .texCoords);
2123
+
2124
+ this .updateVertexArrays ();
2125
+ },
2126
+ set_scaleRamp__ ()
2127
+ {
2128
+ this .scaleRampNode ?.removeInterest ("set_scale__", this);
2129
+
2130
+ this .scaleRampNode = external_X_ITE_X3D_X3DCast_default() ((external_X_ITE_X3D_X3DConstants_default()).Coordinate, this ._scale);
2131
+
2132
+ this .scaleRampNode ?.addInterest ("set_scale__", this);
2133
+
2134
+ this .set_scale__ ();
2135
+ },
2136
+ set_scale__ ()
2137
+ {
2138
+ const
2139
+ gl = this .getBrowser () .getContext (),
2140
+ key = this ._scaleKey,
2141
+ numKeys = key .length,
2142
+ textureSize = Math .ceil (Math .sqrt (numKeys * 2)); // keys + values
2143
+
2144
+ let ramp = this .scaleRamp;
2145
+
2146
+ if (textureSize * textureSize * 4 > ramp .length)
2147
+ ramp = this .scaleRamp = new Float32Array (textureSize * textureSize * 4);
2148
+ else
2149
+ ramp .fill (0);
2150
+
2151
+ for (let i = 0; i < numKeys; ++ i)
2152
+ ramp [i * 4] = key [i];
2153
+
2154
+ if (this .scaleRampNode)
2155
+ ramp .set (this .scaleRampNode .addPoints ([ ], numKeys) .slice (0, numKeys * 4), numKeys * 4);
2156
+ else
2157
+ ramp .fill (1, numKeys * 4);
2158
+
2159
+ if (textureSize)
2160
+ {
2161
+ gl .bindTexture (gl .TEXTURE_2D, this [ParticleSystems_ParticleSampler .scales]);
2162
+ gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, textureSize, textureSize, 0, gl .RGBA, gl .FLOAT, ramp);
2163
+ }
2164
+
2165
+ this .numScales = numKeys;
2166
+
2167
+ if (numKeys)
2168
+ this .samplers .add (ParticleSystems_ParticleSampler .scales);
2169
+ else
2170
+ this .samplers .delete (ParticleSystems_ParticleSampler .scales);
2088
2171
 
2089
2172
  this .updateVertexArrays ();
2090
2173
  },
@@ -2159,7 +2242,7 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (external_X_I
2159
2242
 
2160
2243
  const
2161
2244
  DELAY = 15, // Delay in frames when dt fully applies.
2162
- dt = 1 / Math .max (10, this .getBrowser () .getCurrentFrameRate ());
2245
+ dt = 1 / Math .max (this .getBrowser () .getCurrentFrameRate (), 10);
2163
2246
 
2164
2247
  // let deltaTime is only for the emitter, this.deltaTime is for the forces.
2165
2248
  let deltaTime = this .deltaTime = ((DELAY - 1) * this .deltaTime + dt) / DELAY; // Moving average about DELAY frames.
@@ -2233,13 +2316,21 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (external_X_I
2233
2316
 
2234
2317
  if (numForces)
2235
2318
  {
2236
- gl .bindTexture (gl .TEXTURE_2D, this .forcesTexture);
2319
+ gl .bindTexture (gl .TEXTURE_2D, this [ParticleSystems_ParticleSampler .forces]);
2237
2320
  gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, numForces, 1, 0, gl .RGBA, gl .FLOAT, forces);
2321
+
2322
+ this .samplers .add (ParticleSystems_ParticleSampler .forces);
2323
+ }
2324
+ else
2325
+ {
2326
+ this .samplers .delete (ParticleSystems_ParticleSampler .forces);
2238
2327
  }
2239
2328
  }
2240
2329
  else
2241
2330
  {
2242
2331
  this .numForces = 0;
2332
+
2333
+ this .samplers .delete (ParticleSystems_ParticleSampler .forces);
2243
2334
  }
2244
2335
 
2245
2336
  // Swap buffers.
@@ -2267,9 +2358,7 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (external_X_I
2267
2358
  new (external_X_ITE_X3D_Vector3_default()) (-0.5, 0.5, 0),
2268
2359
  ];
2269
2360
 
2270
- const
2271
- vertex = new (external_X_ITE_X3D_Vector3_default()) (),
2272
- size = new (external_X_ITE_X3D_Vector3_default()) ();
2361
+ const vertex = new (external_X_ITE_X3D_Vector3_default()) ();
2273
2362
 
2274
2363
  return function (gl, rotation)
2275
2364
  {
@@ -2280,17 +2369,15 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (external_X_I
2280
2369
 
2281
2370
  // Vertices
2282
2371
 
2283
- size .set (this ._particleSize .x, this ._particleSize .y, 1);
2372
+ const size = this .spriteSize;
2284
2373
 
2285
2374
  for (let i = 0; i < 6; ++ i)
2286
2375
  {
2287
2376
  const index = 27 + i * 4;
2288
2377
 
2289
- rotation .multVecMatrix (vertex .assign (quad [i]) .multVec (size))
2378
+ rotation .multVecMatrix (vertex .assign (quad [i]) .multVec (size));
2290
2379
 
2291
- data [index + 0] = vertex .x;
2292
- data [index + 1] = vertex .y;
2293
- data [index + 2] = vertex .z;
2380
+ data .set (vertex, index);
2294
2381
  }
2295
2382
 
2296
2383
  gl .bindBuffer (gl .ARRAY_BUFFER, this .geometryBuffer);
@@ -2377,6 +2464,15 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (external_X_I
2377
2464
  shaderNode = appearanceNode .getShader (this .geometryContext, renderContext),
2378
2465
  primitiveMode = browser .getPrimitiveMode (this .primitiveMode);
2379
2466
 
2467
+ // Enable sample alpha to coverage if not transparent.
2468
+
2469
+ if (this .geometryType === (external_X_ITE_X3D_GeometryType_default()).POINT && !renderContext .transparent)
2470
+ {
2471
+ gl .enable (gl .SAMPLE_ALPHA_TO_COVERAGE);
2472
+ gl .enable (gl .BLEND);
2473
+ gl .blendFuncSeparate (gl .ONE, gl .ZERO, gl .ZERO, gl .ONE);
2474
+ }
2475
+
2380
2476
  // Set viewport.
2381
2477
 
2382
2478
  gl .viewport (... viewport);
@@ -2396,7 +2492,7 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (external_X_I
2396
2492
  const textureUnit = browser .getTextureUnit ();
2397
2493
 
2398
2494
  gl .activeTexture (gl .TEXTURE0 + textureUnit);
2399
- gl .bindTexture (gl .TEXTURE_2D, this .texCoordRampTexture);
2495
+ gl .bindTexture (gl .TEXTURE_2D, this [ParticleSystems_ParticleSampler .texCoords]);
2400
2496
  gl .uniform1i (shaderNode .x3d_TexCoordRamp, textureUnit);
2401
2497
  }
2402
2498
 
@@ -2440,6 +2536,16 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (external_X_I
2440
2536
  // Reset texture units.
2441
2537
 
2442
2538
  browser .resetTextureUnits ();
2539
+
2540
+ // Disable sample alpha to coverage if not transparent.
2541
+
2542
+ if (this .geometryType === (external_X_ITE_X3D_GeometryType_default()).POINT && !renderContext .transparent)
2543
+ {
2544
+ gl .disable (gl .SAMPLE_ALPHA_TO_COVERAGE);
2545
+ gl .disable (gl .BLEND);
2546
+ gl .blendFuncSeparate (gl .SRC_ALPHA, gl .ONE_MINUS_SRC_ALPHA, gl .ONE, gl .ONE_MINUS_SRC_ALPHA);
2547
+ }
2548
+
2443
2549
  break;
2444
2550
  }
2445
2551
  }
@@ -2486,8 +2592,8 @@ Object .defineProperties (ParticleSystem,
2486
2592
  value: new (external_X_ITE_X3D_FieldDefinitionArray_default()) ([
2487
2593
  new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "metadata", new (external_X_ITE_X3D_Fields_default()).SFNode ()),
2488
2594
  new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "enabled", new (external_X_ITE_X3D_Fields_default()).SFBool (true)),
2489
- new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "createParticles", new (external_X_ITE_X3D_Fields_default()).SFBool (true)),
2490
2595
  new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).initializeOnly, "geometryType", new (external_X_ITE_X3D_Fields_default()).SFString ("QUAD")),
2596
+ new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "createParticles", new (external_X_ITE_X3D_Fields_default()).SFBool (true)),
2491
2597
  new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "maxParticles", new (external_X_ITE_X3D_Fields_default()).SFInt32 (200)),
2492
2598
  new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "particleLifetime", new (external_X_ITE_X3D_Fields_default()).SFFloat (5)),
2493
2599
  new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "lifetimeVariation", new (external_X_ITE_X3D_Fields_default()).SFFloat (0.25)),
@@ -2498,6 +2604,8 @@ Object .defineProperties (ParticleSystem,
2498
2604
  new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).initializeOnly, "color", new (external_X_ITE_X3D_Fields_default()).SFNode ()),
2499
2605
  new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).initializeOnly, "texCoordKey", new (external_X_ITE_X3D_Fields_default()).MFFloat ()),
2500
2606
  new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).initializeOnly, "texCoord", new (external_X_ITE_X3D_Fields_default()).SFNode ()),
2607
+ new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).initializeOnly, "scaleKey", new (external_X_ITE_X3D_Fields_default()).MFFloat ()), // skip test
2608
+ new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).initializeOnly, "scale", new (external_X_ITE_X3D_Fields_default()).SFNode ()), // skip test
2501
2609
  new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).outputOnly, "isActive", new (external_X_ITE_X3D_Fields_default()).SFBool ()),
2502
2610
  new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "pointerEvents", new (external_X_ITE_X3D_Fields_default()).SFBool (true)), // skip test
2503
2611
  new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "castShadow", new (external_X_ITE_X3D_Fields_default()).SFBool (true)),