x_ite 9.5.2 → 9.6.1

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 (55) hide show
  1. package/README.md +83 -9
  2. package/dist/assets/components/Annotation.js +13 -13
  3. package/dist/assets/components/Annotation.min.js +1 -1
  4. package/dist/assets/components/CADGeometry.js +14 -14
  5. package/dist/assets/components/CADGeometry.min.js +1 -1
  6. package/dist/assets/components/CubeMapTexturing.js +25 -25
  7. package/dist/assets/components/CubeMapTexturing.min.js +1 -1
  8. package/dist/assets/components/DIS.js +13 -13
  9. package/dist/assets/components/DIS.min.js +1 -1
  10. package/dist/assets/components/EventUtilities.js +9 -9
  11. package/dist/assets/components/EventUtilities.min.js +1 -1
  12. package/dist/assets/components/Geometry2D.js +18 -18
  13. package/dist/assets/components/Geometry2D.min.js +1 -1
  14. package/dist/assets/components/Geospatial.js +33 -33
  15. package/dist/assets/components/Geospatial.min.js +1 -1
  16. package/dist/assets/components/HAnim.js +23 -23
  17. package/dist/assets/components/HAnim.min.js +1 -1
  18. package/dist/assets/components/KeyDeviceSensor.js +8 -8
  19. package/dist/assets/components/KeyDeviceSensor.min.js +1 -1
  20. package/dist/assets/components/Layout.js +27 -27
  21. package/dist/assets/components/Layout.min.js +1 -1
  22. package/dist/assets/components/NURBS.js +23 -23
  23. package/dist/assets/components/NURBS.min.js +1 -1
  24. package/dist/assets/components/ParticleSystems.js +693 -364
  25. package/dist/assets/components/ParticleSystems.min.js +1 -1
  26. package/dist/assets/components/Picking.js +18 -18
  27. package/dist/assets/components/Picking.min.js +1 -1
  28. package/dist/assets/components/RigidBodyPhysics.js +17 -17
  29. package/dist/assets/components/RigidBodyPhysics.min.js +1 -1
  30. package/dist/assets/components/Scripting.js +43 -43
  31. package/dist/assets/components/Scripting.min.js +1 -1
  32. package/dist/assets/components/Text.js +49 -50
  33. package/dist/assets/components/Text.min.js +1 -1
  34. package/dist/assets/components/TextureProjection.js +15 -15
  35. package/dist/assets/components/TextureProjection.min.js +1 -1
  36. package/dist/assets/components/Texturing3D.js +80 -37
  37. package/dist/assets/components/Texturing3D.min.js +1 -1
  38. package/dist/assets/components/VolumeRendering.js +19 -19
  39. package/dist/assets/components/VolumeRendering.min.js +1 -1
  40. package/dist/assets/components/X_ITE.js +14 -14
  41. package/dist/assets/components/X_ITE.min.js +1 -1
  42. package/dist/assets/fonts/DroidSerif Apache License.txt +201 -0
  43. package/dist/assets/fonts/Ubuntu LICENCE.txt +96 -0
  44. package/dist/assets/fonts/Ubuntu-B.ttf +0 -0
  45. package/dist/assets/fonts/Ubuntu-BI.ttf +0 -0
  46. package/dist/assets/fonts/Ubuntu-R.ttf +0 -0
  47. package/dist/assets/fonts/Ubuntu-RI.ttf +0 -0
  48. package/dist/x_ite.css +1 -1
  49. package/dist/x_ite.d.ts +7 -0
  50. package/dist/x_ite.js +745 -718
  51. package/dist/x_ite.min.js +1 -1
  52. package/dist/x_ite.min.mjs +1 -1
  53. package/dist/x_ite.mjs +745 -718
  54. package/dist/x_ite.zip +0 -0
  55. package/package.json +121 -115
@@ -1,11 +1,11 @@
1
- /* X_ITE v9.5.2 */(() => { // webpackBootstrap
1
+ /* X_ITE v9.6.1 */(() => { // webpackBootstrap
2
2
  /******/ "use strict";
3
3
  /******/ var __webpack_modules__ = ({
4
4
 
5
5
  /***/ 823:
6
6
  /***/ ((module) => {
7
7
 
8
- module.exports = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("lib/jquery");
8
+ module.exports = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("lib/jquery");
9
9
 
10
10
  /***/ })
11
11
 
@@ -73,52 +73,70 @@ var __webpack_exports__ = {};
73
73
  // UNUSED EXPORTS: default
74
74
 
75
75
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Components\")"
76
- const Components_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Components");
76
+ const Components_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Components");
77
77
  var Components_default = /*#__PURE__*/__webpack_require__.n(Components_namespaceObject);
78
78
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Fields\")"
79
- const Fields_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Fields");
79
+ const Fields_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Fields");
80
80
  var Fields_default = /*#__PURE__*/__webpack_require__.n(Fields_namespaceObject);
81
81
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Base/X3DFieldDefinition\")"
82
- const X3DFieldDefinition_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Base/X3DFieldDefinition");
82
+ const X3DFieldDefinition_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Base/X3DFieldDefinition");
83
83
  var X3DFieldDefinition_default = /*#__PURE__*/__webpack_require__.n(X3DFieldDefinition_namespaceObject);
84
84
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Base/FieldDefinitionArray\")"
85
- const FieldDefinitionArray_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Base/FieldDefinitionArray");
85
+ const FieldDefinitionArray_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Base/FieldDefinitionArray");
86
86
  var FieldDefinitionArray_default = /*#__PURE__*/__webpack_require__.n(FieldDefinitionArray_namespaceObject);
87
87
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Components/Core/X3DNode\")"
88
- const X3DNode_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Components/Core/X3DNode");
88
+ const X3DNode_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Components/Core/X3DNode");
89
89
  var X3DNode_default = /*#__PURE__*/__webpack_require__.n(X3DNode_namespaceObject);
90
90
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Browser/ParticleSystems/GeometryTypes\")"
91
- const GeometryTypes_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Browser/ParticleSystems/GeometryTypes");
91
+ const GeometryTypes_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Browser/ParticleSystems/GeometryTypes");
92
92
  var GeometryTypes_default = /*#__PURE__*/__webpack_require__.n(GeometryTypes_namespaceObject);
93
93
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Base/X3DConstants\")"
94
- const X3DConstants_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Base/X3DConstants");
94
+ const X3DConstants_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Base/X3DConstants");
95
95
  var X3DConstants_default = /*#__PURE__*/__webpack_require__.n(X3DConstants_namespaceObject);
96
96
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Namespace\")"
97
- const Namespace_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Namespace");
97
+ const Namespace_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Namespace");
98
98
  var Namespace_default = /*#__PURE__*/__webpack_require__.n(Namespace_namespaceObject);
99
99
  ;// CONCATENATED MODULE: ./src/x_ite/Browser/ParticleSystems/Line3.glsl.js
100
- const __default__ = /* glsl */ `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.0)return false;float inv_det=1.0/det;vec3 tvec=line.point-a;float u=dot(tvec,pvec)*inv_det;if(u<0.0||u>1.0)return false;vec3 qvec=cross(tvec,edge1);float v=dot(line.direction,qvec)*inv_det;if(v<0.0||u+v>1.0)return false;r=vec3(u,v,1.0-u-v);return true;}`
100
+ const __default__ = /* glsl */ `#if defined(X3D_BOUNDED_VOLUME)||defined(X3D_VOLUME_EMITTER)
101
+ 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.0)return false;float inv_det=1.0/det;vec3 tvec=line.point-a;float u=dot(tvec,pvec)*inv_det;if(u<0.0||u>1.0)return false;vec3 qvec=cross(tvec,edge1);float v=dot(line.direction,qvec)*inv_det;if(v<0.0||u+v>1.0)return false;r=vec3(u,v,1.0-u-v);return true;}
102
+ #endif
103
+ `
101
104
  ;
102
105
 
103
106
  Namespace_default().add ("Line3.glsl", "x_ite/Browser/ParticleSystems/Line3.glsl", __default__);
104
107
  /* harmony default export */ const Line3_glsl = (__default__);
105
108
  ;// CONCATENATED MODULE: ./src/x_ite/Browser/ParticleSystems/Plane3.glsl.js
106
- const Plane3_glsl_default_ = /* glsl */ `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.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.0/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.0;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;}`
109
+ const Plane3_glsl_default_ = /* glsl */ `#if defined(X3D_BOUNDED_VOLUME)||defined(X3D_VOLUME_EMITTER)
110
+ 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.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.0/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.0;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;}
111
+ #endif
112
+ `
107
113
  ;
108
114
 
109
115
  Namespace_default().add ("Plane3.glsl", "x_ite/Browser/ParticleSystems/Plane3.glsl", Plane3_glsl_default_);
110
116
  /* harmony default export */ const Plane3_glsl = (Plane3_glsl_default_);
111
117
  ;// CONCATENATED MODULE: ./src/x_ite/Browser/ParticleSystems/Box3.glsl.js
112
- const Box3_glsl_default_ = /* glsl */ `bool intersects(const in vec3 min,const in vec3 max,const in Line3 line){vec3 intersection;if(intersects(plane3(max,vec3(0.0,0.0,1.0)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.xy,max.xy),vec4(min.xy,intersection.xy))))return true;}if(intersects(plane3(min,vec3(0.0,0.0,-1.0)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.xy,max.xy),vec4(min.xy,intersection.xy))))return true;}if(intersects(plane3(max,vec3(0.0,1.0,0.0)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.xz,max.xz),vec4(min.xz,intersection.xz))))return true;}if(intersects(plane3(min,vec3(0.0,-1.0,0.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.0,0.0)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.yz,max.yz),vec4(min.yz,intersection.yz))))return true;}return false;}`
118
+ const Box3_glsl_default_ = /* glsl */ `#if defined(X3D_VOLUME_EMITTER)||defined(X3D_BOUNDED_VOLUME)
119
+ bool intersects(const in vec3 min,const in vec3 max,const in Line3 line){vec3 intersection;if(intersects(plane3(max,vec3(0.0,0.0,1.0)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.xy,max.xy),vec4(min.xy,intersection.xy))))return true;}if(intersects(plane3(min,vec3(0.0,0.0,-1.0)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.xy,max.xy),vec4(min.xy,intersection.xy))))return true;}if(intersects(plane3(max,vec3(0.0,1.0,0.0)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.xz,max.xz),vec4(min.xz,intersection.xz))))return true;}if(intersects(plane3(min,vec3(0.0,-1.0,0.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.0,0.0)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.yz,max.yz),vec4(min.yz,intersection.yz))))return true;}return false;}
120
+ #endif
121
+ `
113
122
  ;
114
123
 
115
124
  Namespace_default().add ("Box3.glsl", "x_ite/Browser/ParticleSystems/Box3.glsl", Box3_glsl_default_);
116
125
  /* harmony default export */ const Box3_glsl = (Box3_glsl_default_);
117
126
  ;// CONCATENATED MODULE: ./src/x_ite/Browser/ParticleSystems/BVH.glsl.js
118
- const BVH_glsl_default_ = /* glsl */ `#define BVH_NODE 0
127
+ const BVH_glsl_default_ = /* glsl */ `#if defined(X3D_VOLUME_EMITTER)||defined(X3D_BOUNDED_VOLUME)
128
+ #define BVH_NODE 0
119
129
  #define BVH_TRIANGLE 1
120
130
  #define BVH_STACK_SIZE 32
121
- 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);}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.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.0);current=-1;}}else{setBVHIndex(stack[stackIndex--]);current=getBVHRight(volume,hierarchyIndex);}}return count;}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.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.0);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;}`
131
+ 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);}
132
+ #if defined(X3D_VOLUME_EMITTER)
133
+ 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.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.0);current=-1;}}else{setBVHIndex(stack[stackIndex--]);current=getBVHRight(volume,hierarchyIndex);}}return count;}
134
+ #endif
135
+ #if defined(X3D_BOUNDED_VOLUME)
136
+ 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.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.0);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;}
137
+ #endif
138
+ #endif
139
+ `
122
140
  ;
123
141
 
124
142
  Namespace_default().add ("BVH.glsl", "x_ite/Browser/ParticleSystems/BVH.glsl", BVH_glsl_default_);
@@ -179,33 +197,25 @@ Namespace_default().add ("BVH.glsl", "x_ite/Browser/ParticleSystems/BVH.glsl", B
179
197
 
180
198
 
181
199
 
200
+
182
201
  function X3DParticleEmitterNode (executionContext)
183
202
  {
184
203
  X3DNode_default().call (this, executionContext);
185
204
 
186
205
  this .addType ((X3DConstants_default()).X3DParticleEmitterNode);
187
206
 
207
+ this .addChildObjects ((X3DConstants_default()).outputOnly, "bbox_changed", new (Fields_default()).SFTime ());
208
+
188
209
  this ._speed .setUnit ("speed");
189
210
  this ._mass .setUnit ("mass");
190
211
  this ._surfaceArea .setUnit ("area");
191
212
 
213
+ this .defines = [ ];
192
214
  this .samplers = [ ];
193
- this .uniforms = { };
215
+ this .uniforms = new Map ();
216
+ this .callbacks = [ ];
194
217
  this .functions = [ ];
195
- this .program = null;
196
-
197
- this .addSampler ("forces");
198
- this .addSampler ("boundedVolume");
199
- this .addSampler ("colorRamp");
200
- this .addSampler ("texCoordRamp");
201
-
202
- this .addUniform ("speed", "uniform float speed;");
203
- this .addUniform ("variation", "uniform float variation;");
204
-
205
- this .addFunction (Line3_glsl);
206
- this .addFunction (Plane3_glsl);
207
- this .addFunction (Box3_glsl);
208
- this .addFunction (BVH_glsl);
218
+ this .programs = new Map ();
209
219
  }
210
220
 
211
221
  Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (X3DNode_default()).prototype),
@@ -221,20 +231,35 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (X3DN
221
231
 
222
232
  // Create program.
223
233
 
224
- this .program = this .createProgram ();
225
234
  this .transformFeedback = gl .createTransformFeedback ();
226
235
 
227
236
  // Initialize fields.
228
237
 
229
- this ._on .addInterest ("set_on__", this);
230
- this ._speed .addInterest ("set_speed__", this);
231
- this ._variation .addInterest ("set_variation__", this);
232
- this ._mass .addInterest ("set_mass__", this);
238
+ this ._on .addInterest ("set_on__", this);
239
+ this ._speed .addInterest ("set_speed__", this);
240
+ this ._variation .addInterest ("set_variation__", this);
241
+ this ._mass .addInterest ("set_mass__", this);
242
+ this ._surfaceArea .addInterest ("set_surfaceArea__", this);
243
+
244
+ this .addSampler ("forces");
245
+ this .addSampler ("boundedVolume");
246
+ this .addSampler ("colorRamp");
247
+ this .addSampler ("texCoordRamp");
248
+
249
+ this .addUniform ("speed", "uniform float speed;");
250
+ this .addUniform ("variation", "uniform float variation;");
251
+
252
+ this .addCallback (this .set_speed__);
253
+ this .addCallback (this .set_variation__);
254
+
255
+ this .addFunction (Line3_glsl);
256
+ this .addFunction (Plane3_glsl);
257
+ this .addFunction (Box3_glsl);
258
+ this .addFunction (BVH_glsl);
233
259
 
234
260
  this .set_on__ ();
235
- this .set_speed__ ();
236
- this .set_variation__ ();
237
261
  this .set_mass__ ();
262
+ this .set_surfaceArea__ ();
238
263
  },
239
264
  isExplosive ()
240
265
  {
@@ -244,21 +269,29 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (X3DN
244
269
  {
245
270
  return this .mass;
246
271
  },
272
+ getSurfaceArea ()
273
+ {
274
+ return this .surfaceArea;
275
+ },
247
276
  set_on__ ()
248
277
  {
249
278
  this .on = this ._on .getValue ();
250
279
  },
251
280
  set_speed__ ()
252
281
  {
253
- this .setUniform ("uniform1f", "speed", this ._speed .getValue ());
282
+ this .setUniform ("uniform1f", "speed", Math .max (this ._speed .getValue (), 0));
254
283
  },
255
284
  set_variation__ ()
256
285
  {
257
- this .setUniform ("uniform1f", "variation", this ._variation .getValue ());
286
+ this .setUniform ("uniform1f", "variation", Math .max (this ._variation .getValue (), 0));
258
287
  },
259
288
  set_mass__ ()
260
289
  {
261
- this .mass = this ._mass .getValue ();
290
+ this .mass = Math .max (this ._mass .getValue (), 0);
291
+ },
292
+ set_surfaceArea__ ()
293
+ {
294
+ this .surfaceArea = Math .max (this ._surfaceArea .getValue (), 0);
262
295
  },
263
296
  getRandomValue (min, max)
264
297
  {
@@ -279,12 +312,10 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (X3DN
279
312
  animate (particleSystem, deltaTime)
280
313
  {
281
314
  const
282
- browser = this .getBrowser (),
283
- gl = browser .getContext (),
284
- inputParticles = particleSystem .inputParticles,
285
- particlesStride = particleSystem .particlesStride,
286
- particleOffsets = particleSystem .particleOffsets,
287
- program = this .program;
315
+ browser = this .getBrowser (),
316
+ gl = browser .getContext (),
317
+ program = this .getProgram (particleSystem),
318
+ inputParticles = particleSystem .inputParticles;
288
319
 
289
320
  // Start
290
321
 
@@ -293,8 +324,6 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (X3DN
293
324
  // Uniforms
294
325
 
295
326
  gl .uniform1i (program .randomSeed, Math .random () * 0xffffffff);
296
- gl .uniform1i (program .geometryType, particleSystem .geometryType);
297
- gl .uniform1i (program .createParticles, particleSystem .createParticles && this .on);
298
327
  gl .uniform1f (program .particleLifetime, particleSystem .particleLifetime);
299
328
  gl .uniform1f (program .lifetimeVariation, particleSystem .lifetimeVariation);
300
329
  gl .uniform1f (program .deltaTime, deltaTime);
@@ -302,8 +331,6 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (X3DN
302
331
 
303
332
  // Forces
304
333
 
305
- gl .uniform1i (program .numForces, particleSystem .numForces);
306
-
307
334
  if (particleSystem .numForces)
308
335
  {
309
336
  gl .activeTexture (gl .TEXTURE0 + program .forcesTextureUnit);
@@ -312,11 +339,7 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (X3DN
312
339
 
313
340
  // Bounded Physics
314
341
 
315
- if (particleSystem .boundedHierarchyRoot < 0)
316
- {
317
- gl .uniform1i (program .boundedHierarchyRoot, -1);
318
- }
319
- else
342
+ if (particleSystem .boundedHierarchyRoot > -1)
320
343
  {
321
344
  gl .uniform1i (program .boundedVerticesIndex, particleSystem .boundedVerticesIndex);
322
345
  gl .uniform1i (program .boundedNormalsIndex, particleSystem .boundedNormalsIndex);
@@ -329,8 +352,6 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (X3DN
329
352
 
330
353
  // Colors
331
354
 
332
- gl .uniform1i (program .numColors, particleSystem .numColors);
333
-
334
355
  if (particleSystem .numColors)
335
356
  {
336
357
  gl .activeTexture (gl .TEXTURE0 + program .colorRampTextureUnit);
@@ -339,8 +360,6 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (X3DN
339
360
 
340
361
  // TexCoords
341
362
 
342
- gl .uniform1i (program .numTexCoords, particleSystem .numTexCoords);
343
-
344
363
  if (particleSystem .numTexCoords)
345
364
  {
346
365
  gl .uniform1i (program .texCoordCount, particleSystem .texCoordCount);
@@ -357,6 +376,8 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (X3DN
357
376
 
358
377
  if (inputParticles .vertexArrayObject .enable (program))
359
378
  {
379
+ const { particlesStride, particleOffsets } = particleSystem;
380
+
360
381
  for (const [i, attribute] of program .inputs)
361
382
  {
362
383
  gl .bindBuffer (gl .ARRAY_BUFFER, inputParticles);
@@ -380,10 +401,14 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (X3DN
380
401
 
381
402
  // DEBUG
382
403
 
383
- // const data = new Float32Array (particleSystem .numParticles * (particlesStride / 4));
404
+ // const data = new Float32Array (particleSystem .numParticles * (particleSystem .particlesStride / 4));
384
405
  // gl .bindBuffer (gl .ARRAY_BUFFER, particleSystem .outputParticles);
385
406
  // gl .getBufferSubData (gl .ARRAY_BUFFER, 0, data);
386
- // console .log (data .slice (0, particlesStride / 4));
407
+ // console .log (data .slice (0, particleSystem .particlesStride / 4));
408
+ },
409
+ addDefine (define)
410
+ {
411
+ this .defines .push (define);
387
412
  },
388
413
  addSampler (name)
389
414
  {
@@ -391,35 +416,129 @@ Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (X3DN
391
416
  },
392
417
  addUniform (name, uniform)
393
418
  {
394
- this .uniforms [name] = uniform;
419
+ this .uniforms .set (name, uniform);
395
420
  },
396
421
  setUniform (func, name, value1, value2, value3)
397
422
  {
398
- const
399
- gl = this .getBrowser () .getContext (),
400
- program = this .program;
423
+ const gl = this .getBrowser () .getContext ();
401
424
 
402
- gl .useProgram (program);
403
- gl [func] (program [name], value1, value2, value3);
425
+ for (const program of this .programs .values ())
426
+ {
427
+ gl .useProgram (program);
428
+ gl [func] (program [name], value1, value2, value3);
429
+ }
430
+ },
431
+ addCallback (callback)
432
+ {
433
+ this .callbacks .push (callback);
404
434
  },
405
435
  addFunction (func)
406
436
  {
407
437
  this .functions .push (func);
408
438
  },
409
- createProgram ()
439
+ getProgram (particleSystem)
440
+ {
441
+ const { geometryType, createParticles, numColors, numTexCoords, numForces, boundedHierarchyRoot } = particleSystem;
442
+
443
+ let key = "";
444
+
445
+ key += geometryType;
446
+ key += createParticles && this .on ? 1 : 0;
447
+ key += ".";
448
+ key += numColors
449
+ key += ".";
450
+ key += numTexCoords;
451
+ key += ".";
452
+ key += numForces
453
+ key += ".";
454
+ key += boundedHierarchyRoot;
455
+
456
+ return this .programs .get (key) ??
457
+ this .createProgram (key, particleSystem);
458
+ },
459
+ createProgram (key, particleSystem)
410
460
  {
411
461
  const
412
462
  browser = this .getBrowser (),
413
- gl = browser .getContext ();
463
+ gl = browser .getContext (),
464
+ defines = this .defines .slice ();
465
+
466
+ defines .push (`#define X3D_GEOMETRY_TYPE ${particleSystem .geometryType}`)
467
+ defines .push (`${particleSystem .createParticles && this .on ? "#define X3D_CREATE_PARTICLES" : ""}`);
468
+ defines .push (`#define X3D_NUM_COLORS ${particleSystem .numColors}`);
469
+ defines .push (`#define X3D_NUM_TEX_COORDS ${particleSystem .numTexCoords}`);
470
+ defines .push (`#define X3D_NUM_FORCES ${particleSystem .numForces}`);
471
+ defines .push (`${particleSystem .boundedHierarchyRoot > -1 ? "#define X3D_BOUNDED_VOLUME" : ""}`);
414
472
 
415
473
  const vertexShaderSource = /* glsl */ `#version 300 es
416
- precision highp float;precision highp int;precision highp sampler2D;uniform int randomSeed;uniform int geometryType;uniform bool createParticles;uniform float particleLifetime;uniform float lifetimeVariation;uniform float deltaTime;uniform vec2 particleSize;uniform int numForces;uniform sampler2D forces;uniform int boundedVerticesIndex;uniform int boundedNormalsIndex;uniform int boundedHierarchyIndex;uniform int boundedHierarchyRoot;uniform sampler2D boundedVolume;uniform int numColors;uniform sampler2D colorRamp;uniform int texCoordCount;uniform int numTexCoords;uniform sampler2D texCoordRamp;
417
- ${Object .values (this .uniforms) .join ("\n")}
474
+ precision highp float;precision highp int;precision highp sampler2D;
475
+ ${defines .join ("\n")}
476
+ uniform int randomSeed;uniform float particleLifetime;uniform float lifetimeVariation;uniform float deltaTime;uniform vec2 particleSize;
477
+ #if X3D_NUM_FORCES>0
478
+ uniform sampler2D forces;
479
+ #endif
480
+ #if defined(X3D_BOUNDED_VOLUME)
481
+ uniform int boundedVerticesIndex;uniform int boundedNormalsIndex;uniform int boundedHierarchyIndex;uniform int boundedHierarchyRoot;uniform sampler2D boundedVolume;
482
+ #endif
483
+ #if X3D_NUM_COLORS>0
484
+ uniform sampler2D colorRamp;
485
+ #endif
486
+ #if X3D_NUM_TEX_COORDS>0
487
+ uniform int texCoordCount;uniform sampler2D texCoordRamp;
488
+ #endif
489
+
490
+ ${Array .from (this .uniforms .values ()) .join ("\n")}
418
491
  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;
419
492
  ${Object .entries ((GeometryTypes_default())) .map (([k, v]) => `#define ${k} ${v}`) .join ("\n")}
420
- 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.0)return vec3(0.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.0){if(cos_angle>0.0){return vec4(0.0,0.0,0.0,1.0);}else{vec3 t=cross(from,vec3(1.0,0.0,0.0));if(dot(t,t)==0.0)t=cross(from,vec3(0.0,1.0,0.0));t=save_normalize(t);return vec4(t,0.0);}}else{float s=sqrt(abs(1.0-cos_angle)*0.5);cross_vec=save_normalize(cross_vec);return vec4(cross_vec*s,sqrt(abs(1.0+cos_angle)*0.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.0*(v.x*q.x+v.y*q.y+v.z*q.z);float c=2.0*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.0-2.0*(A+B),2.0*(C+D),2.0*(E-F),2.0*(C-D),1.0-2.0*(B+G),2.0*(H+I),2.0*(E+F),2.0*(H-I),1.0-2.0*(A+G));}uint seed=1u;void srand(const in int value){seed=uint(value);}float random(){seed=seed*1103515245u+12345u;return float(seed)/4294967295.0;}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.0,particleLifetime-v);float max_=particleLifetime+v;return getRandomValue(min_,max_);}float getRandomSpeed(){float v=speed*variation;float min_=max(0.0,speed-v);float max_=speed+v;return getRandomValue(min_,max_);}vec3 getRandomNormal(){float theta=getRandomValue(-M_PI,M_PI);float cphi=getRandomValue(-1.0,1.0);float r=sqrt(1.0-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.0);float r=sqrt(1.0-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,0.0,1.0),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.0/3.0);float r=sqrt(1.0-cphi*cphi);vec3 normal=vec3(sin(theta)*r,cos(theta)*r,cphi);vec4 rotation=Quaternion(vec3(0.0,0.0,1.0),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;}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.0;}else if(fraction>=texelFetch(sampler,count-1,0).x){index0=count-2;index1=count-1;weight=1.0;}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.0,1.0);}else{index0=0;index1=0;weight=0.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;}}vec3 getRandomBarycentricCoord(){float u=random();float v=random();if(u+v>1.0){u=1.0-u;v=1.0-v;}float t=1.0-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);}
493
+ 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.0)return vec3(0.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.0){if(cos_angle>0.0){return vec4(0.0,0.0,0.0,1.0);}else{vec3 t=cross(from,vec3(1.0,0.0,0.0));if(dot(t,t)==0.0)t=cross(from,vec3(0.0,1.0,0.0));t=save_normalize(t);return vec4(t,0.0);}}else{float s=sqrt(abs(1.0-cos_angle)*0.5);cross_vec=save_normalize(cross_vec);return vec4(cross_vec*s,sqrt(abs(1.0+cos_angle)*0.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.0*(v.x*q.x+v.y*q.y+v.z*q.z);float c=2.0*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.0-2.0*(A+B),2.0*(C+D),2.0*(E-F),2.0*(C-D),1.0-2.0*(B+G),2.0*(H+I),2.0*(E+F),2.0*(H-I),1.0-2.0*(A+G));}uint seed=1u;void srand(const in int value){seed=uint(value);}float random(){seed=seed*1103515245u+12345u;return float(seed)/4294967295.0;}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.0,particleLifetime-v);float max_=particleLifetime+v;return getRandomValue(min_,max_);}float getRandomSpeed(){float v=speed*variation;float min_=max(0.0,speed-v);float max_=speed+v;return getRandomValue(min_,max_);}vec3 getRandomNormal(){float theta=getRandomValue(-M_PI,M_PI);float cphi=getRandomValue(-1.0,1.0);float r=sqrt(1.0-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.0);float r=sqrt(1.0-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,0.0,1.0),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.0/3.0);float r=sqrt(1.0-cphi*cphi);vec3 normal=vec3(sin(theta)*r,cos(theta)*r,cphi);vec4 rotation=Quaternion(vec3(0.0,0.0,1.0),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;}
494
+ #if X3D_NUM_COLORS>0||defined(X3D_POLYLINE_EMITTER)||defined(X3D_SURFACE_EMITTER)||defined(X3D_VOLUME_EMITTER)
495
+ 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.0;}else if(fraction>=texelFetch(sampler,count-1,0).x){index0=count-2;index1=count-1;weight=1.0;}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.0,1.0);}else{index0=0;index1=0;weight=0.0;}}}
496
+ #endif
497
+ #if X3D_NUM_TEX_COORDS>0
498
+ 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;}}
499
+ #endif
500
+ #if defined(X3D_SURFACE_EMITTER)||defined(X3D_VOLUME_EMITTER)
501
+ vec3 getRandomBarycentricCoord(){float u=random();float v=random();if(u+v>1.0){u=1.0-u;v=1.0-v;}float t=1.0-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);}
502
+ #endif
503
+
421
504
  ${this .functions .join ("\n")}
422
- vec4 getColor(const in float lifetime,const in float elapsedTime){if(numColors>0){float fraction=elapsedTime/lifetime;int index0;int index1;float weight;interpolate(colorRamp,numColors,fraction,index0,index1,weight);vec4 color0=texelFetch(colorRamp,numColors+index0,0);vec4 color1=texelFetch(colorRamp,numColors+index1,0);return mix(color0,color1,weight);}else{return vec4(1.0);}}void bounce(const in float deltaTime,const in vec4 fromPosition,inout vec4 toPosition,inout vec3 velocity){if(boundedHierarchyRoot<0)return;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.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)*0.0001,1.0);velocity*=damping;}int getTexCoordIndex0(const in float lifetime,const in float elapsedTime){if(numTexCoords==0){return-1;}else{float fraction=elapsedTime/lifetime;int index0=0;interpolate(texCoordRamp,numTexCoords,fraction,index0);return numTexCoords+index0*texCoordCount;}}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.0;output0=vec4(max(life+1,1),lifetime,elapsedTime,getTexCoordIndex0(lifetime,elapsedTime));if(createParticles){output1=getColor(lifetime,elapsedTime);output2=vec4(getRandomVelocity(),0.0);output6=getRandomPosition();}else{output1=vec4(0.0);output2=vec4(0.0);output6=vec4(NaN);}}else{vec3 velocity=input2.xyz;vec4 position=input6;for(int i=0;i<numForces;++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;}position.xyz+=velocity*deltaTime;bounce(deltaTime,input6,position,velocity);output0=vec4(life,lifetime,elapsedTime,getTexCoordIndex0(lifetime,elapsedTime));output1=getColor(lifetime,elapsedTime);output2=vec4(velocity,0.0);output6=position;}switch(geometryType){case POINT:case SPRITE:case GEOMETRY:{output3=vec4(1.0,0.0,0.0,0.0);output4=vec4(0.0,1.0,0.0,0.0);output5=vec4(0.0,0.0,1.0,0.0);break;}case LINE:{mat3 m=Matrix3(Quaternion(vec3(0.0,0.0,1.0),output2.xyz));output3=vec4(m[0],0.0);output4=vec4(m[1],0.0);output5=vec4(m[2],0.0);break;}default:{output3=vec4(particleSize.x,0.0,0.0,0.0);output4=vec4(0.0,particleSize.y,0.0,0.0);output5=vec4(0.0,0.0,1.0,0.0);break;}}}`
505
+
506
+ #if X3D_NUM_COLORS>0
507
+ 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);}
508
+ #else
509
+ #define getColor(lifetime,elapsedTime)(vec4(1.0))
510
+ #endif
511
+ #if defined(X3D_BOUNDED_VOLUME)
512
+ 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.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)*0.0001,1.0);velocity*=damping;}
513
+ #endif
514
+ #if X3D_NUM_TEX_COORDS>0
515
+ 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;}
516
+ #else
517
+ #define getTexCoordIndex0(lifetime,elapsedTime)(-1)
518
+ #endif
519
+ 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.0;output0=vec4(max(life+1,1),lifetime,elapsedTime,getTexCoordIndex0(lifetime,elapsedTime));
520
+ #if defined(X3D_CREATE_PARTICLES)
521
+ output1=getColor(lifetime,elapsedTime);output2=vec4(getRandomVelocity(),0.0);output6=getRandomPosition();
522
+ #else
523
+ output1=vec4(0.0);output2=vec4(0.0);output6=vec4(NaN);
524
+ #endif
525
+ }else{vec3 velocity=input2.xyz;vec4 position=input6;
526
+ #if X3D_NUM_FORCES>0
527
+ 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;}
528
+ #endif
529
+ position.xyz+=velocity*deltaTime;
530
+ #if defined(X3D_BOUNDED_VOLUME)
531
+ bounce(deltaTime,input6,position,velocity);
532
+ #endif
533
+ output0=vec4(life,lifetime,elapsedTime,getTexCoordIndex0(lifetime,elapsedTime));output1=getColor(lifetime,elapsedTime);output2=vec4(velocity,0.0);output6=position;}
534
+ #if X3D_GEOMETRY_TYPE==POINT||X3D_GEOMETRY_TYPE==SPRITE||X3D_GEOMETRY_TYPE==GEOMETRY
535
+ output3=vec4(1.0,0.0,0.0,0.0);output4=vec4(0.0,1.0,0.0,0.0);output5=vec4(0.0,0.0,1.0,0.0);
536
+ #elif X3D_GEOMETRY_TYPE==LINE
537
+ mat3 m=Matrix3(Quaternion(vec3(0.0,0.0,1.0),output2.xyz));output3=vec4(m[0],0.0);output4=vec4(m[1],0.0);output5=vec4(m[2],0.0);
538
+ #else
539
+ output3=vec4(particleSize.x,0.0,0.0,0.0);output4=vec4(0.0,particleSize.y,0.0,0.0);output5=vec4(0.0,0.0,1.0,0.0);
540
+ #endif
541
+ }`
423
542
 
424
543
  const fragmentShaderSource = /* glsl */ `#version 300 es
425
544
  precision highp float;void main(){}`
@@ -454,7 +573,16 @@ precision highp float;void main(){}`
454
573
  gl .linkProgram (program);
455
574
 
456
575
  if (!gl .getProgramParameter (program, gl .LINK_STATUS))
576
+ {
457
577
  console .error ("Couldn't initialize particle shader: " + gl .getProgramInfoLog (program));
578
+ // console .error (vertexShaderSource);
579
+ }
580
+
581
+ this .programs .set (key, program);
582
+
583
+ gl .useProgram (program);
584
+
585
+ // Attributes
458
586
 
459
587
  program .inputs = [
460
588
  [0, gl .getAttribLocation (program, "input0")],
@@ -462,16 +590,15 @@ precision highp float;void main(){}`
462
590
  [6, gl .getAttribLocation (program, "input6")],
463
591
  ];
464
592
 
593
+ // Uniforms
594
+
465
595
  program .randomSeed = gl .getUniformLocation (program, "randomSeed");
466
- program .geometryType = gl .getUniformLocation (program, "geometryType");
467
- program .createParticles = gl .getUniformLocation (program, "createParticles");
468
596
  program .particleLifetime = gl .getUniformLocation (program, "particleLifetime");
469
597
  program .lifetimeVariation = gl .getUniformLocation (program, "lifetimeVariation");
470
598
  program .deltaTime = gl .getUniformLocation (program, "deltaTime");
471
599
  program .particleSize = gl .getUniformLocation (program, "particleSize");
472
600
 
473
- program .numForces = gl .getUniformLocation (program, "numForces");
474
- program .forces = gl .getUniformLocation (program, "forces");
601
+ program .forces = gl .getUniformLocation (program, "forces");
475
602
 
476
603
  program .boundedVerticesIndex = gl .getUniformLocation (program, "boundedVerticesIndex");
477
604
  program .boundedNormalsIndex = gl .getUniformLocation (program, "boundedNormalsIndex");
@@ -479,19 +606,17 @@ precision highp float;void main(){}`
479
606
  program .boundedHierarchyRoot = gl .getUniformLocation (program, "boundedHierarchyRoot");
480
607
  program .boundedVolume = gl .getUniformLocation (program, "boundedVolume");
481
608
 
482
- program .numColors = gl .getUniformLocation (program, "numColors");
483
609
  program .colorRamp = gl .getUniformLocation (program, "colorRamp");
484
610
 
485
611
  program .texCoordCount = gl .getUniformLocation (program, "texCoordCount");
486
- program .numTexCoords = gl .getUniformLocation (program, "numTexCoords");
487
612
  program .texCoordRamp = gl .getUniformLocation (program, "texCoordRamp");
488
613
 
489
- for (const name of Object .keys (this .uniforms))
614
+ for (const name of this .uniforms .keys ())
490
615
  program [name] = gl .getUniformLocation (program, name);
491
616
 
492
- program .NaN = gl .getUniformLocation (program, "NaN");
617
+ gl .uniform1f (gl .getUniformLocation (program, "NaN"), NaN);
493
618
 
494
- gl .useProgram (program);
619
+ // Samplers
495
620
 
496
621
  for (const name of this .samplers)
497
622
  {
@@ -500,10 +625,15 @@ precision highp float;void main(){}`
500
625
  gl .uniform1i (location, program [name + "TextureUnit"] = browser .getTexture2DUnit ());
501
626
  }
502
627
 
503
- gl .uniform1f (program .NaN, NaN);
504
-
505
628
  browser .resetTextureUnits ();
506
629
 
630
+ // Field uniforms
631
+
632
+ for (const callback of this .callbacks)
633
+ callback .call (this);
634
+
635
+ // Return
636
+
507
637
  return program;
508
638
  },
509
639
  activateTextures ()
@@ -556,7 +686,7 @@ const X3DParticleEmitterNode_default_ = X3DParticleEmitterNode;
556
686
  Namespace_default().add ("X3DParticleEmitterNode", "x_ite/Components/ParticleSystems/X3DParticleEmitterNode", X3DParticleEmitterNode_default_);
557
687
  /* harmony default export */ const ParticleSystems_X3DParticleEmitterNode = (X3DParticleEmitterNode_default_);
558
688
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"standard/Math/Numbers/Vector3\")"
559
- const Vector3_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("standard/Math/Numbers/Vector3");
689
+ const Vector3_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("standard/Math/Numbers/Vector3");
560
690
  var Vector3_default = /*#__PURE__*/__webpack_require__.n(Vector3_namespaceObject);
561
691
  ;// CONCATENATED MODULE: ./src/x_ite/Components/ParticleSystems/PointEmitter.js
562
692
  /*******************************************************************************
@@ -620,23 +750,6 @@ function PointEmitter (executionContext)
620
750
  this .addType ((X3DConstants_default()).PointEmitter);
621
751
 
622
752
  this ._position .setUnit ("length");
623
-
624
- this .addUniform ("position", "uniform vec3 position;");
625
- this .addUniform ("direction", "uniform vec3 direction;");
626
-
627
- this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
628
- {
629
- if (direction == vec3 (0.0))
630
- return getRandomSphericalVelocity ();
631
-
632
- else
633
- return direction * getRandomSpeed ();
634
- }`);
635
-
636
- this .addFunction (/* glsl */ `vec4 getRandomPosition ()
637
- {
638
- return vec4 (position, 1.0);
639
- }`);
640
753
  }
641
754
 
642
755
  Object .assign (Object .setPrototypeOf (PointEmitter .prototype, ParticleSystems_X3DParticleEmitterNode .prototype),
@@ -651,14 +764,49 @@ Object .assign (Object .setPrototypeOf (PointEmitter .prototype, ParticleSystems
651
764
  this ._position .addInterest ("set_position__", this);
652
765
  this ._direction .addInterest ("set_direction__", this);
653
766
 
654
- this .set_position__ ();
655
- this .set_direction__ ();
767
+ this .addDefine ("#define X3D_POINT_EMITTER");
768
+
769
+ this .addUniform ("position", "uniform vec3 position;");
770
+ this .addUniform ("direction", "uniform vec3 direction;");
771
+
772
+ this .addCallback (this .set_position__);
773
+ this .addCallback (this .set_direction__);
774
+
775
+ this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
776
+ {
777
+ if (direction == vec3 (0.0))
778
+ return getRandomSphericalVelocity ();
779
+
780
+ else
781
+ return direction * getRandomSpeed ();
782
+ }`);
783
+
784
+ this .addFunction (/* glsl */ `vec4 getRandomPosition ()
785
+ {
786
+ return vec4 (position, 1.0);
787
+ }`);
656
788
  },
789
+ getBBox: (function ()
790
+ {
791
+ const bboxSize = new (Vector3_default()) ();
792
+
793
+ return function (bbox, { particleLifetime, lifetimeVariation })
794
+ {
795
+ const
796
+ maxParticleLifetime = particleLifetime * (1 + lifetimeVariation),
797
+ maxSpeed = this ._speed .getValue () * (1 + this ._variation .getValue ()),
798
+ s = maxParticleLifetime * maxSpeed * 2;
799
+
800
+ return bbox .set (bboxSize .set (s, s, s), this ._position .getValue ());
801
+ };
802
+ })(),
657
803
  set_position__ ()
658
804
  {
659
- const position = this ._position .getValue ();
805
+ const { x, y, z } = this ._position .getValue ();
806
+
807
+ this .setUniform ("uniform3f", "position", x, y, z);
660
808
 
661
- this .setUniform ("uniform3f", "position", position .x, position .y, position .z);
809
+ this ._bbox_changed .addEvent ();
662
810
  },
663
811
  set_direction__: (() =>
664
812
  {
@@ -666,9 +814,9 @@ Object .assign (Object .setPrototypeOf (PointEmitter .prototype, ParticleSystems
666
814
 
667
815
  return function ()
668
816
  {
669
- direction .assign (this ._direction .getValue ()) .normalize ();
817
+ const { x, y, z } = direction .assign (this ._direction .getValue ()) .normalize ();
670
818
 
671
- this .setUniform ("uniform3f", "direction", direction .x, direction .y, direction .z);
819
+ this .setUniform ("uniform3f", "direction", x, y, z);
672
820
  };
673
821
  })(),
674
822
  });
@@ -875,7 +1023,7 @@ const X3DParticlePhysicsModelNode_default_ = X3DParticlePhysicsModelNode;
875
1023
  Namespace_default().add ("X3DParticlePhysicsModelNode", "x_ite/Components/ParticleSystems/X3DParticlePhysicsModelNode", X3DParticlePhysicsModelNode_default_);
876
1024
  /* harmony default export */ const ParticleSystems_X3DParticlePhysicsModelNode = (X3DParticlePhysicsModelNode_default_);
877
1025
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Base/X3DCast\")"
878
- const X3DCast_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Base/X3DCast");
1026
+ const X3DCast_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Base/X3DCast");
879
1027
  var X3DCast_default = /*#__PURE__*/__webpack_require__.n(X3DCast_namespaceObject);
880
1028
  ;// CONCATENATED MODULE: ./src/x_ite/Components/ParticleSystems/BoundedPhysicsModel.js
881
1029
  /*******************************************************************************
@@ -949,6 +1097,10 @@ Object .assign (Object .setPrototypeOf (BoundedPhysicsModel .prototype, Particle
949
1097
 
950
1098
  this .set_geometry__ ();
951
1099
  },
1100
+ getBBox ()
1101
+ {
1102
+ return this .geometryNode ?.getBBox ();
1103
+ },
952
1104
  set_geometry__ ()
953
1105
  {
954
1106
  this .geometryNode ?._rebuild .removeInterest ("addNodeEvent", this);
@@ -959,20 +1111,22 @@ Object .assign (Object .setPrototypeOf (BoundedPhysicsModel .prototype, Particle
959
1111
  },
960
1112
  addGeometry (boundedNormals, boundedVertices)
961
1113
  {
962
- const damping = this ._damping .getValue ();
1114
+ if (!this .geometryNode)
1115
+ return;
963
1116
 
964
- if (this .geometryNode && this ._enabled .getValue ())
965
- {
966
- const
967
- normals = this .geometryNode .getNormals () .getValue (),
968
- vertices = this .geometryNode .getVertices () .getValue ();
1117
+ if (!this ._enabled .getValue ())
1118
+ return;
969
1119
 
970
- for (const value of normals)
971
- boundedNormals .push (value * damping);
1120
+ const
1121
+ damping = this ._damping .getValue (),
1122
+ normals = this .geometryNode .getNormals () .getValue (),
1123
+ vertices = this .geometryNode .getVertices () .getValue ();
972
1124
 
973
- for (const value of vertices)
974
- boundedVertices .push (value);
975
- }
1125
+ for (const value of normals)
1126
+ boundedNormals .push (value * damping);
1127
+
1128
+ for (const value of vertices)
1129
+ boundedVertices .push (value);
976
1130
  },
977
1131
  });
978
1132
 
@@ -1069,6 +1223,7 @@ Namespace_default().add ("BoundedPhysicsModel", "x_ite/Components/ParticleSystem
1069
1223
 
1070
1224
 
1071
1225
 
1226
+
1072
1227
  function ConeEmitter (executionContext)
1073
1228
  {
1074
1229
  ParticleSystems_X3DParticleEmitterNode .call (this, executionContext);
@@ -1077,30 +1232,6 @@ function ConeEmitter (executionContext)
1077
1232
 
1078
1233
  this ._position .setUnit ("length");
1079
1234
  this ._angle .setUnit ("angle");
1080
-
1081
- this .addUniform ("position", "uniform vec3 position;");
1082
- this .addUniform ("direction", "uniform vec3 direction;");
1083
- this .addUniform ("angle", "uniform float angle;");
1084
-
1085
- this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
1086
- {
1087
- if (direction == vec3 (0.0))
1088
- {
1089
- return getRandomSphericalVelocity ();
1090
- }
1091
- else
1092
- {
1093
- vec3 normal = getRandomNormalWithDirectionAndAngle (direction, angle);
1094
- float speed = getRandomSpeed ();
1095
-
1096
- return normal * speed;
1097
- }
1098
- }`);
1099
-
1100
- this .addFunction (/* glsl */ `vec4 getRandomPosition ()
1101
- {
1102
- return vec4 (position, 1.0);
1103
- }`);
1104
1235
  }
1105
1236
 
1106
1237
  Object .assign (Object .setPrototypeOf (ConeEmitter .prototype, ParticleSystems_X3DParticleEmitterNode .prototype),
@@ -1116,21 +1247,63 @@ Object .assign (Object .setPrototypeOf (ConeEmitter .prototype, ParticleSystems_
1116
1247
  this ._direction .addInterest ("set_direction__", this);
1117
1248
  this ._angle .addInterest ("set_angle__", this);
1118
1249
 
1119
- this .set_position__ ();
1120
- this .set_direction__ ();
1121
- this .set_angle__ ();
1250
+ this .addDefine ("#define X3D_CONE_EMITTER");
1251
+
1252
+ this .addUniform ("position", "uniform vec3 position;");
1253
+ this .addUniform ("direction", "uniform vec3 direction;");
1254
+ this .addUniform ("angle", "uniform float angle;");
1255
+
1256
+ this .addCallback (this .set_position__);
1257
+ this .addCallback (this .set_direction__);
1258
+ this .addCallback (this .set_angle__);
1259
+
1260
+ this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
1261
+ {
1262
+ if (direction == vec3 (0.0))
1263
+ {
1264
+ return getRandomSphericalVelocity ();
1265
+ }
1266
+ else
1267
+ {
1268
+ vec3 normal = getRandomNormalWithDirectionAndAngle (direction, angle);
1269
+ float speed = getRandomSpeed ();
1270
+
1271
+ return normal * speed;
1272
+ }
1273
+ }`);
1274
+
1275
+ this .addFunction (/* glsl */ `vec4 getRandomPosition ()
1276
+ {
1277
+ return vec4 (position, 1.0);
1278
+ }`);
1122
1279
  },
1280
+ getBBox: (function ()
1281
+ {
1282
+ const bboxSize = new (Vector3_default()) ();
1283
+
1284
+ return function (bbox, { particleLifetime, lifetimeVariation })
1285
+ {
1286
+ const
1287
+ maxParticleLifetime = particleLifetime * (1 + lifetimeVariation),
1288
+ maxSpeed = this ._speed .getValue () * (1 + this ._variation .getValue ()),
1289
+ s = maxParticleLifetime * maxSpeed * 2;
1290
+
1291
+ return bbox .set (bboxSize .set (s, s, s), this ._position .getValue ());
1292
+ };
1293
+ })(),
1123
1294
  set_position__ ()
1124
1295
  {
1125
- const position = this ._position .getValue ();
1296
+ const { x, y, z } = this ._position .getValue ();
1297
+
1298
+ this .setUniform ("uniform3f", "position", x, y, z );
1126
1299
 
1127
- this .setUniform ("uniform3f", "position", position .x, position .y, position .z);
1300
+ this ._bbox_changed .addEvent ();
1128
1301
  },
1129
1302
  set_direction__ ()
1130
1303
  {
1131
- const direction = this ._direction .getValue ();
1304
+ const { x, y, z } = this ._direction .getValue ();
1132
1305
 
1133
- this .setUniform ("uniform3f", "direction", direction .x, direction .y, direction .z);
1306
+ this .setUniform ("uniform3f", "direction", x, y, z );
1134
1307
  },
1135
1308
  set_angle__ ()
1136
1309
  {
@@ -1236,6 +1409,7 @@ Namespace_default().add ("ConeEmitter", "x_ite/Components/ParticleSystems/ConeEm
1236
1409
 
1237
1410
 
1238
1411
 
1412
+
1239
1413
  function ExplosionEmitter (executionContext)
1240
1414
  {
1241
1415
  ParticleSystems_X3DParticleEmitterNode .call (this, executionContext);
@@ -1243,18 +1417,6 @@ function ExplosionEmitter (executionContext)
1243
1417
  this .addType ((X3DConstants_default()).ExplosionEmitter);
1244
1418
 
1245
1419
  this ._position .setUnit ("length");
1246
-
1247
- this .addUniform ("position", "uniform vec3 position;");
1248
-
1249
- this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
1250
- {
1251
- return getRandomSphericalVelocity ();
1252
- }`);
1253
-
1254
- this .addFunction (/* glsl */ `vec4 getRandomPosition ()
1255
- {
1256
- return vec4 (position, 1.0);
1257
- }`);
1258
1420
  }
1259
1421
 
1260
1422
  Object .assign (Object .setPrototypeOf (ExplosionEmitter .prototype, ParticleSystems_X3DParticleEmitterNode .prototype),
@@ -1268,17 +1430,45 @@ Object .assign (Object .setPrototypeOf (ExplosionEmitter .prototype, ParticleSys
1268
1430
 
1269
1431
  this ._position .addInterest ("set_position__", this);
1270
1432
 
1271
- this .set_position__ ();
1433
+ this .addDefine ("#define X3D_EXPLOSION_EMITTER");
1434
+ this .addUniform ("position", "uniform vec3 position;");
1435
+ this .addCallback (this .set_position__);
1436
+
1437
+ this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
1438
+ {
1439
+ return getRandomSphericalVelocity ();
1440
+ }`);
1441
+
1442
+ this .addFunction (/* glsl */ `vec4 getRandomPosition ()
1443
+ {
1444
+ return vec4 (position, 1.0);
1445
+ }`);
1272
1446
  },
1447
+ getBBox: (function ()
1448
+ {
1449
+ const bboxSize = new (Vector3_default()) ();
1450
+
1451
+ return function (bbox, { particleLifetime, lifetimeVariation })
1452
+ {
1453
+ const
1454
+ maxParticleLifetime = particleLifetime * (1 + lifetimeVariation),
1455
+ maxSpeed = this ._speed .getValue () * (1 + this ._variation .getValue ()),
1456
+ s = maxParticleLifetime * maxSpeed * 2;
1457
+
1458
+ return bbox .set (bboxSize .set (s, s, s), this ._position .getValue ());
1459
+ };
1460
+ })(),
1273
1461
  isExplosive ()
1274
1462
  {
1275
1463
  return true;
1276
1464
  },
1277
1465
  set_position__ ()
1278
1466
  {
1279
- const position = this ._position .getValue ();
1467
+ const { x, y, z } = this ._position .getValue ();
1280
1468
 
1281
- this .setUniform ("uniform3f", "position", position .x, position .y, position .z);
1469
+ this .setUniform ("uniform3f", "position", x, y, z);
1470
+
1471
+ this ._bbox_changed .addEvent ();
1282
1472
  },
1283
1473
  });
1284
1474
 
@@ -1450,34 +1640,34 @@ const ForcePhysicsModel_default_ = ForcePhysicsModel;
1450
1640
  Namespace_default().add ("ForcePhysicsModel", "x_ite/Components/ParticleSystems/ForcePhysicsModel", ForcePhysicsModel_default_);
1451
1641
  /* harmony default export */ const ParticleSystems_ForcePhysicsModel = (ForcePhysicsModel_default_);
1452
1642
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Components/Shape/X3DShapeNode\")"
1453
- const X3DShapeNode_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Components/Shape/X3DShapeNode");
1643
+ const X3DShapeNode_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Components/Shape/X3DShapeNode");
1454
1644
  var X3DShapeNode_default = /*#__PURE__*/__webpack_require__.n(X3DShapeNode_namespaceObject);
1455
1645
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Browser/Rendering/GeometryContext\")"
1456
- const GeometryContext_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Browser/Rendering/GeometryContext");
1646
+ const GeometryContext_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Browser/Rendering/GeometryContext");
1457
1647
  var GeometryContext_default = /*#__PURE__*/__webpack_require__.n(GeometryContext_namespaceObject);
1458
1648
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Rendering/VertexArray\")"
1459
- const VertexArray_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Rendering/VertexArray");
1649
+ const VertexArray_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Rendering/VertexArray");
1460
1650
  var VertexArray_default = /*#__PURE__*/__webpack_require__.n(VertexArray_namespaceObject);
1461
1651
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Rendering/TraverseType\")"
1462
- const TraverseType_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Rendering/TraverseType");
1652
+ const TraverseType_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Rendering/TraverseType");
1463
1653
  var TraverseType_default = /*#__PURE__*/__webpack_require__.n(TraverseType_namespaceObject);
1464
1654
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Browser/Shape/AlphaMode\")"
1465
- const AlphaMode_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Browser/Shape/AlphaMode");
1655
+ const AlphaMode_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Browser/Shape/AlphaMode");
1466
1656
  var AlphaMode_default = /*#__PURE__*/__webpack_require__.n(AlphaMode_namespaceObject);
1467
1657
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Components/Rendering/LineSet\")"
1468
- const LineSet_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Components/Rendering/LineSet");
1658
+ const LineSet_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Components/Rendering/LineSet");
1469
1659
  var LineSet_default = /*#__PURE__*/__webpack_require__.n(LineSet_namespaceObject);
1470
1660
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Components/Rendering/Coordinate\")"
1471
- const Coordinate_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Components/Rendering/Coordinate");
1661
+ const Coordinate_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Components/Rendering/Coordinate");
1472
1662
  var Coordinate_default = /*#__PURE__*/__webpack_require__.n(Coordinate_namespaceObject);
1473
1663
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"standard/Math/Numbers/Matrix4\")"
1474
- const Matrix4_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("standard/Math/Numbers/Matrix4");
1664
+ const Matrix4_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("standard/Math/Numbers/Matrix4");
1475
1665
  var Matrix4_default = /*#__PURE__*/__webpack_require__.n(Matrix4_namespaceObject);
1476
1666
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"standard/Math/Numbers/Matrix3\")"
1477
- const Matrix3_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("standard/Math/Numbers/Matrix3");
1667
+ const Matrix3_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("standard/Math/Numbers/Matrix3");
1478
1668
  var Matrix3_default = /*#__PURE__*/__webpack_require__.n(Matrix3_namespaceObject);
1479
1669
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"standard/Math/Geometry/Plane3\")"
1480
- const Plane3_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("standard/Math/Geometry/Plane3");
1670
+ const Plane3_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("standard/Math/Geometry/Plane3");
1481
1671
  var Plane3_default = /*#__PURE__*/__webpack_require__.n(Plane3_namespaceObject);
1482
1672
  ;// CONCATENATED MODULE: ./src/standard/Math/Algorithms/QuickSort.js
1483
1673
  /*******************************************************************************
@@ -2133,14 +2323,16 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (X3DShapeNode
2133
2323
  this .getLive () .addInterest ("set_live__", this);
2134
2324
 
2135
2325
  this ._enabled .addInterest ("set_enabled__", this);
2136
- this ._createParticles .addInterest ("set_createParticles__", this);
2137
2326
  this ._geometryType .addInterest ("set_geometryType__", this);
2138
2327
  this ._geometryType .addInterest ("set_texCoord__", this);
2139
2328
  this ._maxParticles .addInterest ("set_enabled__", this);
2140
2329
  this ._particleLifetime .addInterest ("set_particleLifetime__", this);
2330
+ this ._particleLifetime .addInterest ("set_bbox__", this);
2141
2331
  this ._lifetimeVariation .addInterest ("set_lifetimeVariation__", this);
2332
+ this ._lifetimeVariation .addInterest ("set_bbox__", this);
2142
2333
  this ._particleSize .addInterest ("set_particleSize__", this);
2143
2334
  this ._emitter .addInterest ("set_emitter__", this);
2335
+ this ._emitter .addInterest ("set_bbox__", this);
2144
2336
  this ._physics .addInterest ("set_physics__", this);
2145
2337
  this ._colorKey .addInterest ("set_color__", this);
2146
2338
  this ._color .addInterest ("set_colorRamp__", this);
@@ -2196,13 +2388,13 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (X3DShapeNode
2196
2388
  this .set_emitter__ ();
2197
2389
  this .set_enabled__ ();
2198
2390
  this .set_geometryType__ ();
2199
- this .set_createParticles__ ();
2200
2391
  this .set_particleLifetime__ ();
2201
2392
  this .set_lifetimeVariation__ ();
2202
2393
  this .set_particleSize__ ();
2203
2394
  this .set_physics__ ();
2204
2395
  this .set_colorRamp__ ();
2205
2396
  this .set_texCoordRamp__ ();
2397
+ this .set_bbox__ ();
2206
2398
  },
2207
2399
  getShapeKey ()
2208
2400
  {
@@ -2233,9 +2425,28 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (X3DShapeNode
2233
2425
  set_bbox__ ()
2234
2426
  {
2235
2427
  if (this ._bboxSize .getValue () .equals (this .getDefaultBBoxSize ()))
2236
- this .bbox .set ((Vector3_default()).One, (Vector3_default()).Zero);
2428
+ {
2429
+ if (this .boundedPhysicsModelNodes .length)
2430
+ {
2431
+ this .bbox .set ();
2432
+
2433
+ for (const boundedPhysicsModelNode of this .boundedPhysicsModelNodes)
2434
+ {
2435
+ const bbox = boundedPhysicsModelNode .getBBox ();
2436
+
2437
+ if (bbox)
2438
+ this .bbox .add (bbox);
2439
+ }
2440
+ }
2441
+ else
2442
+ {
2443
+ this .emitterNode ?.getBBox (this .bbox, this);
2444
+ }
2445
+ }
2237
2446
  else
2447
+ {
2238
2448
  this .bbox .set (this ._bboxSize .getValue (), this ._bboxCenter .getValue ());
2449
+ }
2239
2450
 
2240
2451
  this .bboxSize .assign (this .bbox .size);
2241
2452
  this .bboxCenter .assign (this .bbox .center);
@@ -2301,7 +2512,7 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (X3DShapeNode
2301
2512
  {
2302
2513
  if (this ._enabled .getValue () && this ._maxParticles .getValue ())
2303
2514
  {
2304
- if (! this ._isActive .getValue ())
2515
+ if (!this ._isActive .getValue ())
2305
2516
  {
2306
2517
  if (this .getLive () .getValue ())
2307
2518
  {
@@ -2335,10 +2546,6 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (X3DShapeNode
2335
2546
 
2336
2547
  this .set_maxParticles__ ();
2337
2548
  },
2338
- set_createParticles__ ()
2339
- {
2340
- this .createParticles = this ._createParticles .getValue ();
2341
- },
2342
2549
  set_geometryType__ ()
2343
2550
  {
2344
2551
  const
@@ -2418,7 +2625,7 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (X3DShapeNode
2418
2625
  this .maxParticles = maxParticles;
2419
2626
  this .numParticles = Math .min (lastNumParticles, maxParticles);
2420
2627
 
2421
- if (! this .emitterNode .isExplosive ())
2628
+ if (!this .emitterNode .isExplosive ())
2422
2629
  this .creationTime = Date .now () / 1000;
2423
2630
 
2424
2631
  this .resizeBuffers (lastNumParticles);
@@ -2426,11 +2633,11 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (X3DShapeNode
2426
2633
  },
2427
2634
  set_particleLifetime__ ()
2428
2635
  {
2429
- this .particleLifetime = this ._particleLifetime .getValue ();
2636
+ this .particleLifetime = Math .max (this ._particleLifetime .getValue (), 0);
2430
2637
  },
2431
2638
  set_lifetimeVariation__ ()
2432
2639
  {
2433
- this .lifetimeVariation = this ._lifetimeVariation .getValue ();
2640
+ this .lifetimeVariation = Math .max (this ._lifetimeVariation .getValue (), 0);
2434
2641
  },
2435
2642
  set_particleSize__ ()
2436
2643
  {
@@ -2439,12 +2646,12 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (X3DShapeNode
2439
2646
  },
2440
2647
  set_emitter__ ()
2441
2648
  {
2442
- this .emitterNode = X3DCast_default() ((X3DConstants_default()).X3DParticleEmitterNode, this ._emitter);
2649
+ this .emitterNode ?._bbox_changed .removeInterest ("set_bbox__", this);
2443
2650
 
2444
- if (! this .emitterNode)
2445
- this .emitterNode = this .getBrowser () .getDefaultEmitter ();
2651
+ this .emitterNode = X3DCast_default() ((X3DConstants_default()).X3DParticleEmitterNode, this ._emitter)
2652
+ ?? this .getBrowser () .getDefaultEmitter ();
2446
2653
 
2447
- this .createParticles = this ._createParticles .getValue ();
2654
+ this .emitterNode ._bbox_changed .addInterest ("set_bbox__", this);
2448
2655
  },
2449
2656
  set_physics__ ()
2450
2657
  {
@@ -2453,8 +2660,11 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (X3DShapeNode
2453
2660
  forcePhysicsModelNodes = this .forcePhysicsModelNodes,
2454
2661
  boundedPhysicsModelNodes = this .boundedPhysicsModelNodes;
2455
2662
 
2456
- for (let i = 0, length = boundedPhysicsModelNodes .length; i < length; ++ i)
2457
- boundedPhysicsModelNodes [i] .removeInterest ("set_boundedPhysics__", this);
2663
+ for (const boundedPhysicsModelNode of boundedPhysicsModelNodes)
2664
+ {
2665
+ boundedPhysicsModelNode .removeInterest ("set_boundedPhysics__", this);
2666
+ boundedPhysicsModelNode .removeInterest ("set_bbox__", this);
2667
+ }
2458
2668
 
2459
2669
  forcePhysicsModelNodes .length = 0;
2460
2670
  boundedPhysicsModelNodes .length = 0;
@@ -2479,7 +2689,6 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (X3DShapeNode
2479
2689
  }
2480
2690
  case (X3DConstants_default()).BoundedPhysicsModel:
2481
2691
  {
2482
- innerNode .addInterest ("set_boundedPhysics__", this);
2483
2692
  boundedPhysicsModelNodes .push (innerNode);
2484
2693
  break;
2485
2694
  }
@@ -2494,6 +2703,12 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (X3DShapeNode
2494
2703
  { }
2495
2704
  }
2496
2705
 
2706
+ for (const boundedPhysicsModelNode of boundedPhysicsModelNodes)
2707
+ {
2708
+ boundedPhysicsModelNode .addInterest ("set_boundedPhysics__", this);
2709
+ boundedPhysicsModelNode .addInterest ("set_bbox__", this);
2710
+ }
2711
+
2497
2712
  this .set_boundedPhysics__ ();
2498
2713
  },
2499
2714
  set_boundedPhysics__ ()
@@ -2543,7 +2758,7 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (X3DShapeNode
2543
2758
  gl .bindTexture (gl .TEXTURE_2D, this .boundedTexture);
2544
2759
  gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, boundedArraySize, boundedArraySize, 0, gl .RGBA, gl .FLOAT, boundedArray);
2545
2760
  }
2546
- },
2761
+ },
2547
2762
  set_colorRamp__ ()
2548
2763
  {
2549
2764
  if (this .colorRampNode)
@@ -2732,6 +2947,8 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (X3DShapeNode
2732
2947
  }
2733
2948
  else
2734
2949
  {
2950
+ this .createParticles = this ._createParticles .getValue ();
2951
+
2735
2952
  if (this .numParticles < this .maxParticles)
2736
2953
  {
2737
2954
  const
@@ -2765,7 +2982,7 @@ Object .assign (Object .setPrototypeOf (ParticleSystem .prototype, (X3DShapeNode
2765
2982
 
2766
2983
  for (let i = 0; i < numForces; ++ i)
2767
2984
  {
2768
- disabledForces += ! forcePhysicsModelNodes [i] .addForce (i - disabledForces, emitterNode, timeByMass, forces);
2985
+ disabledForces += !forcePhysicsModelNodes [i] .addForce (i - disabledForces, emitterNode, timeByMass, forces);
2769
2986
  }
2770
2987
 
2771
2988
  this .numForces = numForces -= disabledForces;
@@ -3110,7 +3327,7 @@ const ParticleSystem_default_ = ParticleSystem;
3110
3327
  Namespace_default().add ("ParticleSystem", "x_ite/Components/ParticleSystems/ParticleSystem", ParticleSystem_default_);
3111
3328
  /* harmony default export */ const ParticleSystems_ParticleSystem = (ParticleSystem_default_);
3112
3329
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Components/Rendering/IndexedLineSet\")"
3113
- const IndexedLineSet_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Components/Rendering/IndexedLineSet");
3330
+ const IndexedLineSet_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Components/Rendering/IndexedLineSet");
3114
3331
  var IndexedLineSet_default = /*#__PURE__*/__webpack_require__.n(IndexedLineSet_namespaceObject);
3115
3332
  ;// CONCATENATED MODULE: ./src/x_ite/Components/ParticleSystems/PolylineEmitter.js
3116
3333
  /*******************************************************************************
@@ -3174,54 +3391,9 @@ function PolylineEmitter (executionContext)
3174
3391
 
3175
3392
  this .addType ((X3DConstants_default()).PolylineEmitter);
3176
3393
 
3394
+ this .verticesIndex = -1;
3177
3395
  this .polylinesNode = new (IndexedLineSet_default()) (executionContext);
3178
3396
  this .polylinesArray = new Float32Array ();
3179
-
3180
- this .addSampler ("polylines");
3181
-
3182
- this .addUniform ("direction", "uniform vec3 direction;");
3183
- this .addUniform ("verticesIndex", "uniform int verticesIndex;");
3184
- this .addUniform ("polylines", "uniform sampler2D polylines;");
3185
-
3186
- this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
3187
- {
3188
- if (direction == vec3 (0.0))
3189
- return getRandomSphericalVelocity ();
3190
-
3191
- else
3192
- return direction * getRandomSpeed ();
3193
- }`);
3194
-
3195
- this .addFunction (/* glsl */ `vec4 getRandomPosition ()
3196
- {
3197
- if (verticesIndex < 0)
3198
- {
3199
- return vec4 (NaN);
3200
- }
3201
- else
3202
- {
3203
- // Determine index0, index1 and weight.
3204
-
3205
- float lastLengthSoFar = texelFetch (polylines, verticesIndex - 1, 0) .x;
3206
- float fraction = random () * lastLengthSoFar;
3207
-
3208
- int index0 = 0;
3209
- int index1 = 0;
3210
- float weight = 0.0;
3211
-
3212
- interpolate (polylines, verticesIndex, fraction, index0, index1, weight);
3213
-
3214
- // Interpolate and return position.
3215
-
3216
- index0 *= 2;
3217
- index1 = index0 + 1;
3218
-
3219
- vec4 vertex0 = texelFetch (polylines, verticesIndex + index0, 0);
3220
- vec4 vertex1 = texelFetch (polylines, verticesIndex + index1, 0);
3221
-
3222
- return mix (vertex0, vertex1, weight);
3223
- }
3224
- }`);
3225
3397
  }
3226
3398
 
3227
3399
  Object .assign (Object .setPrototypeOf (PolylineEmitter .prototype, ParticleSystems_X3DParticleEmitterNode .prototype),
@@ -3254,20 +3426,88 @@ Object .assign (Object .setPrototypeOf (PolylineEmitter .prototype, ParticleSyst
3254
3426
  this .polylinesNode .setup ();
3255
3427
  this .polylinesNode ._rebuild .addInterest ("set_polylines__", this);
3256
3428
 
3257
- this .set_direction__ ();
3429
+ this .addDefine ("#define X3D_POLYLINE_EMITTER");
3430
+ this .addSampler ("polylines");
3431
+
3432
+ this .addUniform ("direction", "uniform vec3 direction;");
3433
+ this .addUniform ("verticesIndex", "uniform int verticesIndex;");
3434
+ this .addUniform ("polylines", "uniform sampler2D polylines;");
3435
+
3436
+ this .addCallback (this .set_direction__);
3437
+ this .addCallback (this .set_verticesIndex__);
3438
+
3439
+ this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
3440
+ {
3441
+ if (direction == vec3 (0.0))
3442
+ return getRandomSphericalVelocity ();
3443
+
3444
+ else
3445
+ return direction * getRandomSpeed ();
3446
+ }`);
3447
+
3448
+ this .addFunction (/* glsl */ `vec4 getRandomPosition ()
3449
+ {
3450
+ if (verticesIndex < 0)
3451
+ {
3452
+ return vec4 (NaN);
3453
+ }
3454
+ else
3455
+ {
3456
+ // Determine index0, index1 and weight.
3457
+
3458
+ float lastLengthSoFar = texelFetch (polylines, verticesIndex - 1, 0) .x;
3459
+ float fraction = random () * lastLengthSoFar;
3460
+
3461
+ int index0 = 0;
3462
+ int index1 = 0;
3463
+ float weight = 0.0;
3464
+
3465
+ interpolate (polylines, verticesIndex, fraction, index0, index1, weight);
3466
+
3467
+ // Interpolate and return position.
3468
+
3469
+ index0 *= 2;
3470
+ index1 = index0 + 1;
3471
+
3472
+ vec4 vertex0 = texelFetch (polylines, verticesIndex + index0, 0);
3473
+ vec4 vertex1 = texelFetch (polylines, verticesIndex + index1, 0);
3474
+
3475
+ return mix (vertex0, vertex1, weight);
3476
+ }
3477
+ }`);
3478
+
3258
3479
  this .set_polylines__ ();
3259
3480
  },
3481
+ getBBox: (function ()
3482
+ {
3483
+ const bboxSize = new (Vector3_default()) ();
3484
+
3485
+ return function (bbox, { particleLifetime, lifetimeVariation })
3486
+ {
3487
+ const
3488
+ maxParticleLifetime = particleLifetime * (1 + lifetimeVariation),
3489
+ maxSpeed = this ._speed .getValue () * (1 + this ._variation .getValue ()),
3490
+ s = maxParticleLifetime * maxSpeed * 2;
3491
+
3492
+ return bbox .set (bboxSize .set (s, s, s), this .polylinesNode .getBBox () .center)
3493
+ .add (this .polylinesNode .getBBox ());
3494
+ };
3495
+ })(),
3260
3496
  set_direction__: (() =>
3261
3497
  {
3262
3498
  const direction = new (Vector3_default()) ();
3263
3499
 
3264
3500
  return function ()
3265
3501
  {
3266
- direction .assign (this ._direction .getValue ()) .normalize ();
3502
+ const { x, y, z } = direction .assign (this ._direction .getValue ()) .normalize ();
3267
3503
 
3268
- this .setUniform ("uniform3f", "direction", direction .x, direction .y, direction .z);
3504
+ this .setUniform ("uniform3f", "direction", x, y, z);
3269
3505
  };
3270
3506
  })(),
3507
+ set_verticesIndex__ ()
3508
+ {
3509
+ this .setUniform ("uniform1i", "verticesIndex", this .verticesIndex);
3510
+ },
3271
3511
  set_polylines__: (() =>
3272
3512
  {
3273
3513
  const
@@ -3302,13 +3542,17 @@ Object .assign (Object .setPrototypeOf (PolylineEmitter .prototype, ParticleSyst
3302
3542
 
3303
3543
  polylinesArray .set (vertices, verticesIndex * 4);
3304
3544
 
3305
- this .setUniform ("uniform1i", "verticesIndex", numVertices ? verticesIndex : -1);
3545
+ this .verticesIndex = numVertices ? verticesIndex : -1;
3306
3546
 
3307
3547
  if (polylineArraySize)
3308
3548
  {
3309
3549
  gl .bindTexture (gl .TEXTURE_2D, this .polylinesTexture);
3310
3550
  gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, polylineArraySize, polylineArraySize, 0, gl .RGBA, gl .FLOAT, polylinesArray);
3311
3551
  }
3552
+
3553
+ this .set_verticesIndex__ ();
3554
+
3555
+ this ._bbox_changed .addEvent ();
3312
3556
  };
3313
3557
  })(),
3314
3558
  activateTextures (gl, program)
@@ -3364,7 +3608,7 @@ const PolylineEmitter_default_ = PolylineEmitter;
3364
3608
  Namespace_default().add ("PolylineEmitter", "x_ite/Components/ParticleSystems/PolylineEmitter", PolylineEmitter_default_);
3365
3609
  /* harmony default export */ const ParticleSystems_PolylineEmitter = (PolylineEmitter_default_);
3366
3610
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"standard/Math/Geometry/Triangle3\")"
3367
- const Triangle3_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("standard/Math/Geometry/Triangle3");
3611
+ const Triangle3_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("standard/Math/Geometry/Triangle3");
3368
3612
  var Triangle3_default = /*#__PURE__*/__webpack_require__.n(Triangle3_namespaceObject);
3369
3613
  ;// CONCATENATED MODULE: ./src/x_ite/Components/ParticleSystems/SurfaceEmitter.js
3370
3614
  /*******************************************************************************
@@ -3429,39 +3673,10 @@ function SurfaceEmitter (executionContext)
3429
3673
 
3430
3674
  this .addType ((X3DConstants_default()).SurfaceEmitter);
3431
3675
 
3432
- this .surfaceNode = null;
3433
- this .surfaceArray = new Float32Array ();
3434
-
3435
- this .addSampler ("surface");
3436
-
3437
- this .addUniform ("solid", "uniform bool solid;");
3438
- this .addUniform ("verticesIndex", "uniform int verticesIndex;");
3439
- this .addUniform ("normalsIndex", "uniform int normalsIndex;");
3440
- this .addUniform ("surface", "uniform sampler2D surface;");
3441
-
3442
- this .addFunction (/* glsl */ `vec4 position; vec3 getRandomVelocity ()
3443
- {
3444
- if (verticesIndex < 0)
3445
- {
3446
- return vec3 (0.0);
3447
- }
3448
- else
3449
- {
3450
- vec3 normal;
3451
-
3452
- getRandomPointOnSurface (surface, verticesIndex, normalsIndex, position, normal);
3453
-
3454
- if (solid == false && random () > 0.5)
3455
- normal = -normal;
3456
-
3457
- return normal * getRandomSpeed ();
3458
- }
3459
- }`);
3460
-
3461
- this .addFunction (/* glsl */ `vec4 getRandomPosition ()
3462
- {
3463
- return verticesIndex < 0 ? vec4 (NaN) : position;
3464
- }`);
3676
+ this .verticesIndex = -1;
3677
+ this .normalsIndex = -1;
3678
+ this .surfaceNode = null;
3679
+ this .surfaceArray = new Float32Array ();
3465
3680
  }
3466
3681
 
3467
3682
  Object .assign (Object .setPrototypeOf (SurfaceEmitter .prototype, ParticleSystems_X3DParticleEmitterNode .prototype),
@@ -3483,8 +3698,62 @@ Object .assign (Object .setPrototypeOf (SurfaceEmitter .prototype, ParticleSyste
3483
3698
 
3484
3699
  this ._surface .addInterest ("set_surface__", this);
3485
3700
 
3701
+ this .addDefine ("#define X3D_SURFACE_EMITTER");
3702
+ this .addSampler ("surface");
3703
+
3704
+ this .addUniform ("solid", "uniform bool solid;");
3705
+ this .addUniform ("verticesIndex", "uniform int verticesIndex;");
3706
+ this .addUniform ("normalsIndex", "uniform int normalsIndex;");
3707
+ this .addUniform ("surface", "uniform sampler2D surface;");
3708
+
3709
+ this .addCallback (this .set_solid__);
3710
+ this .addCallback (this .set_verticesIndex__);
3711
+ this .addCallback (this .set_normalsIndex__);
3712
+
3713
+ this .addFunction (/* glsl */ `vec4 position; vec3 getRandomVelocity ()
3714
+ {
3715
+ if (verticesIndex < 0)
3716
+ {
3717
+ return vec3 (0.0);
3718
+ }
3719
+ else
3720
+ {
3721
+ vec3 normal;
3722
+
3723
+ getRandomPointOnSurface (surface, verticesIndex, normalsIndex, position, normal);
3724
+
3725
+ if (solid == false && random () > 0.5)
3726
+ normal = -normal;
3727
+
3728
+ return normal * getRandomSpeed ();
3729
+ }
3730
+ }`);
3731
+
3732
+ this .addFunction (/* glsl */ `vec4 getRandomPosition ()
3733
+ {
3734
+ return verticesIndex < 0 ? vec4 (NaN) : position;
3735
+ }`);
3736
+
3486
3737
  this .set_surface__ ();
3487
3738
  },
3739
+ getBBox: (function ()
3740
+ {
3741
+ const bboxSize = new (Vector3_default()) ();
3742
+
3743
+ return function (bbox, { particleLifetime, lifetimeVariation })
3744
+ {
3745
+ if (!this .surfaceNode)
3746
+ return bbox .set ();
3747
+
3748
+ const
3749
+ maxParticleLifetime = particleLifetime * (1 + lifetimeVariation),
3750
+ maxSpeed = this ._speed .getValue () * (1 + this ._variation .getValue ()),
3751
+ s = maxParticleLifetime * maxSpeed * 2;
3752
+
3753
+ return bbox .set (bboxSize .set (s, s, s), this .surfaceNode .getBBox () .center)
3754
+ .add (this .surfaceNode .getBBox ());
3755
+ };
3756
+ })(),
3488
3757
  set_surface__ ()
3489
3758
  {
3490
3759
  if (this .surfaceNode)
@@ -3506,8 +3775,15 @@ Object .assign (Object .setPrototypeOf (SurfaceEmitter .prototype, ParticleSyste
3506
3775
  },
3507
3776
  set_solid__ ()
3508
3777
  {
3509
- if (this .surfaceNode)
3510
- this .setUniform ("uniform1i", "solid", this .surfaceNode ._solid .getValue ());
3778
+ this .setUniform ("uniform1i", "solid", this .surfaceNode ?._solid .getValue () ?? true);
3779
+ },
3780
+ set_verticesIndex__ ()
3781
+ {
3782
+ this .setUniform ("uniform1i", "verticesIndex", this .verticesIndex);
3783
+ },
3784
+ set_normalsIndex__ ()
3785
+ {
3786
+ this .setUniform ("uniform1i", "normalsIndex", this .normalsIndex);
3511
3787
  },
3512
3788
  set_geometry__: (() =>
3513
3789
  {
@@ -3558,8 +3834,8 @@ Object .assign (Object .setPrototypeOf (SurfaceEmitter .prototype, ParticleSyste
3558
3834
  surfaceArray [s + 2] = normals [n + 2];
3559
3835
  }
3560
3836
 
3561
- this .setUniform ("uniform1i", "verticesIndex", numVertices ? verticesIndex : -1);
3562
- this .setUniform ("uniform1i", "normalsIndex", numVertices ? normalsIndex : -1);
3837
+ this .verticesIndex = numVertices ? verticesIndex : -1;
3838
+ this .normalsIndex = numVertices ? normalsIndex : -1;
3563
3839
 
3564
3840
  if (surfaceArraySize)
3565
3841
  {
@@ -3569,9 +3845,14 @@ Object .assign (Object .setPrototypeOf (SurfaceEmitter .prototype, ParticleSyste
3569
3845
  }
3570
3846
  else
3571
3847
  {
3572
- this .setUniform ("uniform1i", "verticesIndex", -1);
3573
- this .setUniform ("uniform1i", "normalsIndex", -1);
3848
+ this .verticesIndex = -1;
3849
+ this .normalsIndex = -1;
3574
3850
  }
3851
+
3852
+ this .set_verticesIndex__ ();
3853
+ this .set_normalsIndex__ ();
3854
+
3855
+ this ._bbox_changed .addEvent ();
3575
3856
  };
3576
3857
  })(),
3577
3858
  activateTextures (gl, program)
@@ -3624,7 +3905,7 @@ const SurfaceEmitter_default_ = SurfaceEmitter;
3624
3905
  Namespace_default().add ("SurfaceEmitter", "x_ite/Components/ParticleSystems/SurfaceEmitter", SurfaceEmitter_default_);
3625
3906
  /* harmony default export */ const ParticleSystems_SurfaceEmitter = (SurfaceEmitter_default_);
3626
3907
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"x_ite/Components/Geometry3D/IndexedFaceSet\")"
3627
- const IndexedFaceSet_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("x_ite/Components/Geometry3D/IndexedFaceSet");
3908
+ const IndexedFaceSet_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("x_ite/Components/Geometry3D/IndexedFaceSet");
3628
3909
  var IndexedFaceSet_default = /*#__PURE__*/__webpack_require__.n(IndexedFaceSet_namespaceObject);
3629
3910
  ;// CONCATENATED MODULE: ./src/x_ite/Components/ParticleSystems/VolumeEmitter.js
3630
3911
  /*******************************************************************************
@@ -3690,71 +3971,12 @@ function VolumeEmitter (executionContext)
3690
3971
 
3691
3972
  this .addType ((X3DConstants_default()).VolumeEmitter);
3692
3973
 
3693
- this .volumeNode = new (IndexedFaceSet_default()) (executionContext);
3694
- this .volumeArray = new Float32Array ();
3695
-
3696
- this .addSampler ("volume");
3697
-
3698
- this .addUniform ("direction", "uniform vec3 direction;");
3699
- this .addUniform ("verticesIndex", "uniform int verticesIndex;");
3700
- this .addUniform ("normalsIndex", "uniform int normalsIndex;");
3701
- this .addUniform ("hierarchyIndex", "uniform int hierarchyIndex;");
3702
- this .addUniform ("hierarchyRoot", "uniform int hierarchyRoot;");
3703
- this .addUniform ("volume", "uniform sampler2D volume;");
3704
-
3705
- this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
3706
- {
3707
- if (hierarchyRoot < 0)
3708
- {
3709
- return vec3 (0.0);
3710
- }
3711
- else
3712
- {
3713
- if (direction == vec3 (0.0))
3714
- return getRandomSphericalVelocity ();
3715
-
3716
- else
3717
- return direction * getRandomSpeed ();
3718
- }
3719
- }`);
3720
-
3721
- this .addFunction (/* glsl */ `vec4 getRandomPosition ()
3722
- {
3723
- if (hierarchyRoot < 0)
3724
- {
3725
- return vec4 (NaN);
3726
- }
3727
- else
3728
- {
3729
- vec4 point;
3730
- vec3 normal;
3731
-
3732
- getRandomPointOnSurface (volume, verticesIndex, normalsIndex, point, normal);
3733
-
3734
- Line3 line = Line3 (point .xyz, getRandomSurfaceNormal (normal));
3735
-
3736
- vec4 points [ARRAY_SIZE];
3737
-
3738
- int numIntersections = getIntersections (volume, verticesIndex, hierarchyIndex, hierarchyRoot, line, points);
3739
-
3740
- numIntersections -= numIntersections % 2; // We need an even count of intersections.
3741
-
3742
- switch (numIntersections)
3743
- {
3744
- case 0:
3745
- return vec4 (0.0);
3746
- case 2:
3747
- break;
3748
- default:
3749
- sort (points, numIntersections, plane3 (line .point, line .direction));
3750
- break;
3751
- }
3752
-
3753
- int index = int (fract (random ()) * float (numIntersections / 2)) * 2; // Select random intersection.
3754
-
3755
- return mix (points [index], points [index + 1], random ());
3756
- }
3757
- }`);
3974
+ this .verticesIndex = -1;
3975
+ this .normalsIndex = -1;
3976
+ this .hierarchyIndex = -1;
3977
+ this .hierarchyRoot = -1;
3978
+ this .volumeNode = new (IndexedFaceSet_default()) (executionContext);
3979
+ this .volumeArray = new Float32Array ();
3758
3980
  }
3759
3981
 
3760
3982
  Object .assign (Object .setPrototypeOf (VolumeEmitter .prototype, ParticleSystems_X3DParticleEmitterNode .prototype),
@@ -3789,20 +4011,120 @@ Object .assign (Object .setPrototypeOf (VolumeEmitter .prototype, ParticleSystem
3789
4011
  this .volumeNode .setup ();
3790
4012
  this .volumeNode ._rebuild .addInterest ("set_geometry__", this);
3791
4013
 
3792
- this .set_direction__ ();
4014
+ this .addDefine ("#define X3D_VOLUME_EMITTER");
4015
+ this .addSampler ("volume");
4016
+
4017
+ this .addUniform ("direction", "uniform vec3 direction;");
4018
+ this .addUniform ("verticesIndex", "uniform int verticesIndex;");
4019
+ this .addUniform ("normalsIndex", "uniform int normalsIndex;");
4020
+ this .addUniform ("hierarchyIndex", "uniform int hierarchyIndex;");
4021
+ this .addUniform ("hierarchyRoot", "uniform int hierarchyRoot;");
4022
+ this .addUniform ("volume", "uniform sampler2D volume;");
4023
+
4024
+ this .addCallback (this .set_direction__);
4025
+ this .addCallback (this .set_verticesIndex__);
4026
+ this .addCallback (this .set_normalsIndex__);
4027
+ this .addCallback (this .set_hierarchyIndex__);
4028
+ this .addCallback (this .set_hierarchyRoot__);
4029
+
4030
+ this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
4031
+ {
4032
+ if (hierarchyRoot < 0)
4033
+ {
4034
+ return vec3 (0.0);
4035
+ }
4036
+ else
4037
+ {
4038
+ if (direction == vec3 (0.0))
4039
+ return getRandomSphericalVelocity ();
4040
+
4041
+ else
4042
+ return direction * getRandomSpeed ();
4043
+ }
4044
+ }`);
4045
+
4046
+ this .addFunction (/* glsl */ `vec4 getRandomPosition ()
4047
+ {
4048
+ if (hierarchyRoot < 0)
4049
+ {
4050
+ return vec4 (NaN);
4051
+ }
4052
+ else
4053
+ {
4054
+ vec4 point;
4055
+ vec3 normal;
4056
+
4057
+ getRandomPointOnSurface (volume, verticesIndex, normalsIndex, point, normal);
4058
+
4059
+ Line3 line = Line3 (point .xyz, getRandomSurfaceNormal (normal));
4060
+
4061
+ vec4 points [ARRAY_SIZE];
4062
+
4063
+ int numIntersections = getIntersections (volume, verticesIndex, hierarchyIndex, hierarchyRoot, line, points);
4064
+
4065
+ numIntersections -= numIntersections % 2; // We need an even count of intersections.
4066
+
4067
+ switch (numIntersections)
4068
+ {
4069
+ case 0:
4070
+ return vec4 (0.0);
4071
+ case 2:
4072
+ break;
4073
+ default:
4074
+ sort (points, numIntersections, plane3 (line .point, line .direction));
4075
+ break;
4076
+ }
4077
+
4078
+ int index = int (fract (random ()) * float (numIntersections / 2)) * 2; // Select random intersection.
4079
+
4080
+ return mix (points [index], points [index + 1], random ());
4081
+ }
4082
+ }`);
4083
+
3793
4084
  this .set_geometry__ ();
3794
4085
  },
4086
+ getBBox: (function ()
4087
+ {
4088
+ const bboxSize = new (Vector3_default()) ();
4089
+
4090
+ return function (bbox, { particleLifetime, lifetimeVariation })
4091
+ {
4092
+ const
4093
+ maxParticleLifetime = particleLifetime * (1 + lifetimeVariation),
4094
+ maxSpeed = this ._speed .getValue () * (1 + this ._variation .getValue ()),
4095
+ s = maxParticleLifetime * maxSpeed * 2;
4096
+
4097
+ return bbox .set (bboxSize .set (s, s, s), this .volumeNode .getBBox () .center)
4098
+ .add (this .volumeNode .getBBox ());
4099
+ };
4100
+ })(),
3795
4101
  set_direction__: (() =>
3796
4102
  {
3797
4103
  const direction = new (Vector3_default()) ();
3798
4104
 
3799
4105
  return function ()
3800
4106
  {
3801
- direction .assign (this ._direction .getValue ()) .normalize ();
4107
+ const { x, y, z } = direction .assign (this ._direction .getValue ()) .normalize ();
3802
4108
 
3803
- this .setUniform ("uniform3f", "direction", direction .x, direction .y, direction .z);
4109
+ this .setUniform ("uniform3f", "direction", x, y, z);
3804
4110
  };
3805
4111
  })(),
4112
+ set_verticesIndex__ ()
4113
+ {
4114
+ this .setUniform ("uniform1i", "verticesIndex", this .verticesIndex);
4115
+ },
4116
+ set_normalsIndex__ ()
4117
+ {
4118
+ this .setUniform ("uniform1i", "normalsIndex", this .normalsIndex);
4119
+ },
4120
+ set_hierarchyIndex__ ()
4121
+ {
4122
+ this .setUniform ("uniform1i", "hierarchyIndex", this .hierarchyIndex);
4123
+ },
4124
+ set_hierarchyRoot__ ()
4125
+ {
4126
+ this .setUniform ("uniform1i", "hierarchyRoot", this .hierarchyRoot);
4127
+ },
3806
4128
  set_geometry__: (() =>
3807
4129
  {
3808
4130
  const
@@ -3855,16 +4177,23 @@ Object .assign (Object .setPrototypeOf (VolumeEmitter .prototype, ParticleSystem
3855
4177
 
3856
4178
  volumeArray .set (hierarchy, hierarchyIndex * 4);
3857
4179
 
3858
- this .setUniform ("uniform1i", "verticesIndex", verticesIndex);
3859
- this .setUniform ("uniform1i", "normalsIndex", normalsIndex);
3860
- this .setUniform ("uniform1i", "hierarchyIndex", hierarchyIndex);
3861
- this .setUniform ("uniform1i", "hierarchyRoot", hierarchyIndex + hierarchyLength - 1);
4180
+ this .verticesIndex = verticesIndex;
4181
+ this .normalsIndex = normalsIndex;
4182
+ this .hierarchyIndex = hierarchyIndex;
4183
+ this .hierarchyRoot = hierarchyIndex + hierarchyLength - 1;
3862
4184
 
3863
4185
  if (volumeArraySize)
3864
4186
  {
3865
4187
  gl .bindTexture (gl .TEXTURE_2D, this .volumeTexture);
3866
4188
  gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, volumeArraySize, volumeArraySize, 0, gl .RGBA, gl .FLOAT, volumeArray);
3867
4189
  }
4190
+
4191
+ this .set_verticesIndex__ ();
4192
+ this .set_normalsIndex__ ();
4193
+ this .set_hierarchyIndex__ ();
4194
+ this .set_hierarchyRoot__ ();
4195
+
4196
+ this ._bbox_changed .addEvent ();
3868
4197
  };
3869
4198
  })(),
3870
4199
  activateTextures (gl, program)
@@ -3921,7 +4250,7 @@ const VolumeEmitter_default_ = VolumeEmitter;
3921
4250
  Namespace_default().add ("VolumeEmitter", "x_ite/Components/ParticleSystems/VolumeEmitter", VolumeEmitter_default_);
3922
4251
  /* harmony default export */ const ParticleSystems_VolumeEmitter = (VolumeEmitter_default_);
3923
4252
  ;// CONCATENATED MODULE: external "window [Symbol .for (\"X_ITE.X3D\")] .require (\"standard/Math/Algorithm\")"
3924
- const Algorithm_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.5.2")] .require ("standard/Math/Algorithm");
4253
+ const Algorithm_namespaceObject = window [Symbol .for ("X_ITE.X3D-9.6.1")] .require ("standard/Math/Algorithm");
3925
4254
  var Algorithm_default = /*#__PURE__*/__webpack_require__.n(Algorithm_namespaceObject);
3926
4255
  ;// CONCATENATED MODULE: ./src/x_ite/Components/ParticleSystems/WindPhysicsModel.js
3927
4256
  /*******************************************************************************
@@ -4000,8 +4329,8 @@ Object .assign (Object .setPrototypeOf (WindPhysicsModel .prototype, ParticleSys
4000
4329
  getRandomSpeed (emitterNode)
4001
4330
  {
4002
4331
  const
4003
- speed = Math .max (0, this ._speed .getValue ()),
4004
- variation = speed * Math .max (0, this ._gustiness .getValue ());
4332
+ speed = Math .max (this ._speed .getValue (), 0),
4333
+ variation = speed * Math .max (this ._gustiness .getValue (), 0);
4005
4334
 
4006
4335
  return emitterNode .getRandomValue (Math .max (0, speed - variation), speed + variation);
4007
4336
  },
@@ -4014,7 +4343,7 @@ Object .assign (Object .setPrototypeOf (WindPhysicsModel .prototype, ParticleSys
4014
4343
  if (this ._enabled .getValue ())
4015
4344
  {
4016
4345
  const
4017
- surfaceArea = emitterNode ._surfaceArea .getValue (),
4346
+ surfaceArea = emitterNode .getSurfaceArea (),
4018
4347
  speed = this .getRandomSpeed (emitterNode),
4019
4348
  pressure = 10 ** (2 * Math .log (speed)) * 0.64615;
4020
4349