x_ite
Version:
X_ITE X3D Browser, view and manipulate X3D, VRML, glTF and other 3D sources in HTML.
1,025 lines (814 loc) • 142 kB
JavaScript
/* X_ITE v12.2.3 */
const __X_ITE_X3D__ = window [Symbol .for ("X_ITE.X3D-12.2.3")];
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ // The require scope
/******/ var __webpack_require__ = {};
/******/
/************************************************************************/
/******/ /* webpack/runtime/compat get default export */
/******/ (() => {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = (module) => {
/******/ var getter = module && module.__esModule ?
/******/ () => (module['default']) :
/******/ () => (module);
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/************************************************************************/
// UNUSED EXPORTS: default
;// external "__X_ITE_X3D__ .Components"
const external_X_ITE_X3D_Components_namespaceObject = __X_ITE_X3D__ .Components;
var external_X_ITE_X3D_Components_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_Components_namespaceObject);
;// external "__X_ITE_X3D__ .Fields"
const external_X_ITE_X3D_Fields_namespaceObject = __X_ITE_X3D__ .Fields;
var external_X_ITE_X3D_Fields_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_Fields_namespaceObject);
;// external "__X_ITE_X3D__ .X3DFieldDefinition"
const external_X_ITE_X3D_X3DFieldDefinition_namespaceObject = __X_ITE_X3D__ .X3DFieldDefinition;
var external_X_ITE_X3D_X3DFieldDefinition_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_X3DFieldDefinition_namespaceObject);
;// external "__X_ITE_X3D__ .FieldDefinitionArray"
const external_X_ITE_X3D_FieldDefinitionArray_namespaceObject = __X_ITE_X3D__ .FieldDefinitionArray;
var external_X_ITE_X3D_FieldDefinitionArray_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_FieldDefinitionArray_namespaceObject);
;// external "__X_ITE_X3D__ .X3DNode"
const external_X_ITE_X3D_X3DNode_namespaceObject = __X_ITE_X3D__ .X3DNode;
var external_X_ITE_X3D_X3DNode_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_X3DNode_namespaceObject);
;// external "__X_ITE_X3D__ .Namespace"
const external_X_ITE_X3D_Namespace_namespaceObject = __X_ITE_X3D__ .Namespace;
var external_X_ITE_X3D_Namespace_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_Namespace_namespaceObject);
;// ./src/x_ite/Browser/ParticleSystems/ParticleSampler.js
const ParticleSampler = {
forces: Symbol (),
colors: Symbol (),
texCoords: Symbol (),
scales: Symbol (),
};
const __default__ = ParticleSampler;
;
/* harmony default export */ const ParticleSystems_ParticleSampler = (external_X_ITE_X3D_Namespace_default().add ("ParticleSampler", __default__));
;// external "__X_ITE_X3D__ .GeometryType"
const external_X_ITE_X3D_GeometryType_namespaceObject = __X_ITE_X3D__ .GeometryType;
var external_X_ITE_X3D_GeometryType_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_GeometryType_namespaceObject);
;// external "__X_ITE_X3D__ .X3DConstants"
const external_X_ITE_X3D_X3DConstants_namespaceObject = __X_ITE_X3D__ .X3DConstants;
var external_X_ITE_X3D_X3DConstants_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_X3DConstants_namespaceObject);
;// ./src/x_ite/Browser/ParticleSystems/Line3.glsl.js
const Line3_glsl_default_ = /* glsl */ `
#if defined(X3D_BOUNDED_VOLUME)||defined(X3D_VOLUME_EMITTER)
struct Line3{vec3 point;vec3 direction;};bool intersects(const in Line3 line,const in vec3 a,const in vec3 b,const in vec3 c,out vec3 r){vec3 edge1=b-a;vec3 edge2=c-a;vec3 pvec=cross(line.direction,edge2);float det=dot(edge1,pvec);if(det==0.)return false;float inv_det=1./det;vec3 tvec=line.point-a;float u=dot(tvec,pvec)*inv_det;if(u<0.||u>1.)return false;vec3 qvec=cross(tvec,edge1);float v=dot(line.direction,qvec)*inv_det;if(v<0.||u+v>1.)return false;r=vec3(u,v,1.-u-v);return true;}
#endif
`
;
/* harmony default export */ const Line3_glsl = (external_X_ITE_X3D_Namespace_default().add ("Line3.glsl", Line3_glsl_default_));
;// ./src/x_ite/Browser/ParticleSystems/Plane3.glsl.js
const Plane3_glsl_default_ = /* glsl */ `
#if defined(X3D_BOUNDED_VOLUME)||defined(X3D_VOLUME_EMITTER)
struct Plane3{vec3 normal;float distanceFromOrigin;};Plane3 plane3(const in vec3 point,const in vec3 normal){return Plane3(normal,dot(normal,point));}float plane_distance(const in Plane3 plane,const in vec3 point){return dot(point,plane.normal)-plane.distanceFromOrigin;}bool intersects(const in Plane3 plane,const in Line3 line,out vec3 point){float theta=dot(line.direction,plane.normal);if(theta==0.)return false;float t=(plane.distanceFromOrigin-dot(plane.normal,line.point))/theta;point=line.point+line.direction*t;return true;}void sort(inout vec4 points[ARRAY_SIZE],const in int count,const in Plane3 plane){const float shrink=1./1.3;int gap=count;bool exchanged=true;while(exchanged){gap=int(float(gap)*shrink);if(gap<=1){exchanged=false;gap=1;}for(int i=0,l=count-gap;i<l;++i){int j=gap+i;if(plane_distance(plane,points[i].xyz)>plane_distance(plane,points[j].xyz)){vec4 tmp1=points[i];points[i]=points[j];points[j]=tmp1;exchanged=true;}}}}int min_index(const in vec4 points[ARRAY_SIZE],const in int count,const in float value,const in Plane3 plane){int index=-1;float dist=1000000.;for(int i=0;i<count;++i){float d=plane_distance(plane,points[i].xyz);if(d>=value&&d<dist){dist=d;index=i;}}return index;}
#endif
`
;
/* harmony default export */ const Plane3_glsl = (external_X_ITE_X3D_Namespace_default().add ("Plane3.glsl", Plane3_glsl_default_));
;// ./src/x_ite/Browser/ParticleSystems/Box3.glsl.js
const Box3_glsl_default_ = /* glsl */ `
#if defined(X3D_VOLUME_EMITTER)||defined(X3D_BOUNDED_VOLUME)
bool intersects(const in vec3 min,const in vec3 max,const in Line3 line){vec3 intersection;if(intersects(plane3(max,vec3(0.,0.,1.)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.xy,max.xy),vec4(min.xy,intersection.xy))))return true;}if(intersects(plane3(min,vec3(0.,0.,-1.)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.xy,max.xy),vec4(min.xy,intersection.xy))))return true;}if(intersects(plane3(max,vec3(0.,1.,0.)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.xz,max.xz),vec4(min.xz,intersection.xz))))return true;}if(intersects(plane3(min,vec3(0.,-1.,0.)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.xz,max.xz),vec4(min.xz,intersection.xz))))return true;}if(intersects(plane3(max,vec3(1.,0.,0.)),line,intersection)){if(all(greaterThanEqual(vec4(intersection.yz,max.yz),vec4(min.yz,intersection.yz))))return true;}return false;}
#endif
`
;
/* harmony default export */ const Box3_glsl = (external_X_ITE_X3D_Namespace_default().add ("Box3.glsl", Box3_glsl_default_));
;// ./src/x_ite/Browser/ParticleSystems/BVH.glsl.js
const BVH_glsl_default_ = /* glsl */ `
#if defined(X3D_VOLUME_EMITTER)||defined(X3D_BOUNDED_VOLUME)
#define BVH_NODE 0
#define BVH_TRIANGLE 1
#define BVH_STACK_SIZE 32
int bvhNodeIndex=0;void setBVHIndex(const in int index){bvhNodeIndex=index;}int getBVHRoot(const in sampler2D volume,const in int hierarchyIndex,const in int rootIndex){return int(texelFetch(volume,rootIndex,0).x)+hierarchyIndex;}int getBVHType(const in sampler2D volume){return int(texelFetch(volume,bvhNodeIndex,0).x);}vec3 getBVHMin(const in sampler2D volume){return texelFetch(volume,bvhNodeIndex+1,0).xyz;}vec3 getBVHMax(const in sampler2D volume){return texelFetch(volume,bvhNodeIndex+2,0).xyz;}int getBVHLeft(const in sampler2D volume,const in int hierarchyIndex){return int(texelFetch(volume,bvhNodeIndex,0).y)+hierarchyIndex;}int getBVHRight(const in sampler2D volume,const in int hierarchyIndex){return int(texelFetch(volume,bvhNodeIndex,0).z)+hierarchyIndex;}int getBVHTriangle(const in sampler2D volume){return int(texelFetch(volume,bvhNodeIndex,0).y);}
#if defined(X3D_VOLUME_EMITTER)
int getIntersections(const in sampler2D volume,const in int verticesIndex,const in int hierarchyIndex,const in int rootIndex,const in Line3 line,out vec4 points[ARRAY_SIZE]){int current=getBVHRoot(volume,hierarchyIndex,rootIndex);int count=0;int stackIndex=-1;int stack[BVH_STACK_SIZE];while(stackIndex>=0||current>=0){if(current>=0){setBVHIndex(current);if(getBVHType(volume)==BVH_NODE){if(intersects(getBVHMin(volume),getBVHMax(volume),line)){stack[++stackIndex]=current;current=getBVHLeft(volume,hierarchyIndex);}else{current=-1;}}else{int t=getBVHTriangle(volume);int v=verticesIndex+t;vec3 r=vec3(0);vec3 a=texelFetch(volume,v,0).xyz;vec3 b=texelFetch(volume,v+1,0).xyz;vec3 c=texelFetch(volume,v+2,0).xyz;if(intersects(line,a,b,c,r))points[count++]=vec4(r.z*a+r.x*b+r.y*c,1.);current=-1;}}else{setBVHIndex(stack[stackIndex--]);current=getBVHRight(volume,hierarchyIndex);}}return count;}
#endif
#if defined(X3D_BOUNDED_VOLUME)
int getIntersections(const in sampler2D volume,const in int verticesIndex,const in int normalsIndex,const in int hierarchyIndex,const in int rootIndex,const in Line3 line,out vec4 points[ARRAY_SIZE],out vec3 normals[ARRAY_SIZE]){int current=getBVHRoot(volume,hierarchyIndex,rootIndex);int count=0;int stackIndex=-1;int stack[BVH_STACK_SIZE];while(stackIndex>=0||current>=0){if(current>=0){setBVHIndex(current);if(getBVHType(volume)==BVH_NODE){if(intersects(getBVHMin(volume),getBVHMax(volume),line)){stack[++stackIndex]=current;current=getBVHLeft(volume,hierarchyIndex);}else{current=-1;}}else{int t=getBVHTriangle(volume);int v=verticesIndex+t;vec3 r=vec3(0);vec3 a=texelFetch(volume,v,0).xyz;vec3 b=texelFetch(volume,v+1,0).xyz;vec3 c=texelFetch(volume,v+2,0).xyz;if(intersects(line,a,b,c,r)){points[count]=vec4(r.z*a+r.x*b+r.y*c,1.);int n=normalsIndex+t;vec3 n0=texelFetch(volume,n,0).xyz;vec3 n1=texelFetch(volume,n+1,0).xyz;vec3 n2=texelFetch(volume,n+2,0).xyz;normals[count]=r.z*n0+r.x*n1+r.y*n2;++count;}current=-1;}}else{setBVHIndex(stack[stackIndex--]);current=getBVHRight(volume,hierarchyIndex);}}return count;}
#endif
#endif
`
;
/* harmony default export */ const BVH_glsl = (external_X_ITE_X3D_Namespace_default().add ("BVH.glsl", BVH_glsl_default_));
;// ./src/x_ite/Components/ParticleSystems/X3DParticleEmitterNode.js
function X3DParticleEmitterNode (executionContext)
{
external_X_ITE_X3D_X3DNode_default().call (this, executionContext);
this .addType ((external_X_ITE_X3D_X3DConstants_default()).X3DParticleEmitterNode);
this .addChildObjects ((external_X_ITE_X3D_X3DConstants_default()).outputOnly, "bbox_changed", new (external_X_ITE_X3D_Fields_default()).SFTime ());
// Units
this ._speed .setUnit ("speed");
this ._mass .setUnit ("mass");
this ._surfaceArea .setUnit ("area");
// Private properties
this .defines = [ ];
this .samplers = [ ];
this .uniforms = new Map ();
this .callbacks = [ ];
this .functions = [ ];
this .programs = new Map ();
}
Object .assign (Object .setPrototypeOf (X3DParticleEmitterNode .prototype, (external_X_ITE_X3D_X3DNode_default()).prototype),
{
initialize ()
{
external_X_ITE_X3D_X3DNode_default().prototype .initialize .call (this);
const gl = this .getBrowser () .getContext ();
// Create program.
this .transformFeedback = gl .createTransformFeedback ();
// Initialize fields.
this ._on .addInterest ("set_on__", this);
this ._speed .addInterest ("set_speed__", this);
this ._variation .addInterest ("set_variation__", this);
this ._mass .addInterest ("set_mass__", this);
this ._surfaceArea .addInterest ("set_surfaceArea__", this);
this .addSampler ("boundedVolume");
for (const key in ParticleSystems_ParticleSampler)
this .addSampler (key);
this .addUniform ("speed", "uniform float speed;");
this .addUniform ("variation", "uniform float variation;");
this .addCallback (this .set_speed__);
this .addCallback (this .set_variation__);
this .addFunction (Line3_glsl);
this .addFunction (Plane3_glsl);
this .addFunction (Box3_glsl);
this .addFunction (BVH_glsl);
this .set_on__ ();
this .set_mass__ ();
this .set_surfaceArea__ ();
},
isExplosive ()
{
return false;
},
getMass ()
{
return this .mass;
},
getSurfaceArea ()
{
return this .surfaceArea;
},
set_on__ ()
{
this .on = this ._on .getValue ();
},
set_speed__ ()
{
this .setUniform ("uniform1f", "speed", Math .max (this ._speed .getValue (), 0));
},
set_variation__ ()
{
this .setUniform ("uniform1f", "variation", Math .max (this ._variation .getValue (), 0));
},
set_mass__ ()
{
this .mass = Math .max (this ._mass .getValue (), 0);
},
set_surfaceArea__ ()
{
this .surfaceArea = Math .max (this ._surfaceArea .getValue (), 0);
},
getRandomValue (min, max)
{
return Math .random () * (max - min) + min;
},
getRandomNormal (normal)
{
const
theta = this .getRandomValue (-1, 1) * Math .PI,
cphi = this .getRandomValue (-1, 1),
phi = Math .acos (cphi),
r = Math .sin (phi);
return normal .set (Math .sin (theta) * r,
Math .cos (theta) * r,
cphi);
},
animate (particleSystem, deltaTime)
{
const
browser = this .getBrowser (),
gl = browser .getContext (),
program = this .getProgram (particleSystem),
inputParticles = particleSystem .inputParticles;
// Start
gl .useProgram (program);
// Uniforms
gl .uniform1i (program .randomSeed, Math .random () * 0xffffffff);
gl .uniform1f (program .particleLifetime, particleSystem .particleLifetime);
gl .uniform1f (program .lifetimeVariation, particleSystem .lifetimeVariation);
gl .uniform1f (program .deltaTime, deltaTime);
gl .uniform2f (program .particleSize, particleSystem ._particleSize .x, particleSystem ._particleSize .y);
// Bounded Physics
if (particleSystem .boundedHierarchyRoot > -1)
{
gl .uniform1i (program .boundedVerticesIndex, particleSystem .boundedVerticesIndex);
gl .uniform1i (program .boundedNormalsIndex, particleSystem .boundedNormalsIndex);
gl .uniform1i (program .boundedHierarchyIndex, particleSystem .boundedHierarchyIndex);
gl .uniform1i (program .boundedHierarchyRoot, particleSystem .boundedHierarchyRoot);
gl .activeTexture (gl .TEXTURE0 + program .boundedVolumeTextureUnit);
gl .bindTexture (gl .TEXTURE_2D, particleSystem .boundedTexture);
}
// Forces, Colors, TexCoords, Scales
for (const sampler of particleSystem .samplers)
{
gl .activeTexture (gl .TEXTURE0 + program [sampler]);
gl .bindTexture (gl .TEXTURE_2D, particleSystem [sampler]);
}
// Other textures
this .activateTextures (gl, program);
// Input attributes
if (inputParticles .vertexArrayObject .enable (program))
{
const { particlesStride, particleOffsets } = particleSystem;
for (const [i, attribute] of program .inputs)
{
gl .bindBuffer (gl .ARRAY_BUFFER, inputParticles);
gl .enableVertexAttribArray (attribute);
gl .vertexAttribPointer (attribute, 4, gl .FLOAT, false, particlesStride, particleOffsets [i]);
}
}
// Transform particles.
gl .bindFramebuffer (gl .FRAMEBUFFER, browser .getDefaultFramebuffer ()); // Prevent texture feedback loop error, see NYC in Firefox.
gl .bindBuffer (gl .ARRAY_BUFFER, null);
gl .bindTransformFeedback (gl .TRANSFORM_FEEDBACK, this .transformFeedback);
gl .bindBufferBase (gl .TRANSFORM_FEEDBACK_BUFFER, 0, particleSystem .outputParticles);
gl .enable (gl .RASTERIZER_DISCARD);
gl .beginTransformFeedback (gl .POINTS);
gl .drawArrays (gl .POINTS, 0, particleSystem .numParticles);
gl .endTransformFeedback ();
gl .disable (gl .RASTERIZER_DISCARD);
gl .bindTransformFeedback (gl .TRANSFORM_FEEDBACK, null);
// DEBUG
// const data = new Float32Array (particleSystem .numParticles * (particleSystem .particlesStride / 4));
// gl .bindBuffer (gl .ARRAY_BUFFER, particleSystem .outputParticles);
// gl .getBufferSubData (gl .ARRAY_BUFFER, 0, data);
// console .log (data .slice (0, particleSystem .particlesStride / 4));
},
addDefine (define)
{
this .defines .push (define);
},
addSampler (name)
{
this .samplers .push (name);
},
addUniform (name, uniform)
{
this .uniforms .set (name, uniform);
},
setUniform (func, name, value1, value2, value3)
{
const gl = this .getBrowser () .getContext ();
for (const program of this .programs .values ())
{
gl .useProgram (program);
gl [func] (program [name], value1, value2, value3);
}
},
addCallback (callback)
{
this .callbacks .push (callback);
},
addFunction (func)
{
this .functions .push (func);
},
getProgram (particleSystem)
{
const {
geometryType,
createParticles,
numColors,
numTexCoords,
texCoordCount,
numScales,
numForces,
boundedHierarchyRoot
} = particleSystem;
let key = "";
key += geometryType;
key += createParticles && this .on ? 1 : 0;
key += ".";
key += numColors
key += ".";
key += numTexCoords;
key += ".";
key += texCoordCount;
key += ".";
key += numScales;
key += ".";
key += numForces
key += ".";
key += boundedHierarchyRoot;
return this .programs .get (key) ??
this .createProgram (key, particleSystem);
},
createProgram (key, particleSystem)
{
const
browser = this .getBrowser (),
gl = browser .getContext (),
defines = this .defines .slice ();
defines .push (`#define X3D_GEOMETRY_TYPE ${particleSystem .geometryType}`)
defines .push (`${particleSystem .createParticles && this .on ? "#define X3D_CREATE_PARTICLES" : ""}`);
defines .push (`#define X3D_NUM_COLORS ${particleSystem .numColors}`);
defines .push (`#define X3D_NUM_TEX_COORDS ${particleSystem .numTexCoords}`);
defines .push (`#define X3D_TEX_COORDS_COUNT ${particleSystem .texCoordCount}`);
defines .push (`#define X3D_NUM_SCALES ${particleSystem .numScales}`);
defines .push (`#define X3D_NUM_FORCES ${particleSystem .numForces}`);
defines .push (`${particleSystem .boundedHierarchyRoot > -1 ? "#define X3D_BOUNDED_VOLUME" : ""}`);
const vertexShaderSource = /* glsl */ `#version 300 es
precision highp float;precision highp int;precision highp sampler2D;
${defines .join ("\n")}
uniform int randomSeed;uniform float particleLifetime;uniform float lifetimeVariation;uniform float deltaTime;uniform vec2 particleSize;
#if X3D_NUM_FORCES>0
uniform sampler2D forces;
#endif
#if defined(X3D_BOUNDED_VOLUME)
uniform int boundedVerticesIndex;uniform int boundedNormalsIndex;uniform int boundedHierarchyIndex;uniform int boundedHierarchyRoot;uniform sampler2D boundedVolume;
#endif
#if X3D_NUM_COLORS>0
uniform sampler2D colors;
#endif
#if X3D_NUM_TEX_COORDS>0
uniform sampler2D texCoords;
#endif
#if X3D_NUM_SCALES>0
uniform sampler2D scales;
#endif
${Array .from (this .uniforms .values ()) .join ("\n")}
in vec4 input0;in vec4 input2;in vec4 input6;out vec4 output0;out vec4 output1;out vec4 output2;out vec4 output3;out vec4 output4;out vec4 output5;out vec4 output6;
${Object .entries ((external_X_ITE_X3D_GeometryType_default())) .map (([k, v]) => `#define ${k} ${v}`) .join ("\n")}
const int ARRAY_SIZE=32;const float M_PI=3.14159265359;uniform float NaN;vec4 texelFetch(const in sampler2D sampler,const in int index,const in int lod){int x=textureSize(sampler,lod).x;ivec2 p=ivec2(index % x,index/x);vec4 t=texelFetch(sampler,p,lod);return t;}vec3 save_normalize(const in vec3 vector){float l=length(vector);if(l==0.)return vec3(0);return vector/l;}vec4 Quaternion(const in vec3 fromVector,const in vec3 toVector){vec3 from=save_normalize(fromVector);vec3 to=save_normalize(toVector);float cos_angle=dot(from,to);vec3 cross_vec=cross(from,to);float cross_len=length(cross_vec);if(cross_len==0.){if(cos_angle>0.){return vec4(0.,0.,0.,1.);}else{vec3 t=cross(from,vec3(1.,0.,0.));if(dot(t,t)==0.)t=cross(from,vec3(0.,1.,0.));t=save_normalize(t);return vec4(t,0.);}}else{float s=sqrt(abs(1.-cos_angle)*.5);cross_vec=save_normalize(cross_vec);return vec4(cross_vec*s,sqrt(abs(1.+cos_angle)*.5));}}vec3 multVecQuat(const in vec3 v,const in vec4 q){float a=q.w*q.w-q.x*q.x-q.y*q.y-q.z*q.z;float b=2.*(v.x*q.x+v.y*q.y+v.z*q.z);float c=2.*q.w;vec3 r=a*v.xyz+b*q.xyz+c*(q.yzx*v.zxy-q.zxy*v.yzx);return r;}mat3 Matrix3(const in vec4 quaternion){float x=quaternion.x;float y=quaternion.y;float z=quaternion.z;float w=quaternion.w;float A=y*y;float B=z*z;float C=x*y;float D=z*w;float E=z*x;float F=y*w;float G=x*x;float H=y*z;float I=x*w;return mat3(1.-2.*(A+B),2.*(C+D),2.*(E-F),2.*(C-D),1.-2.*(B+G),2.*(H+I),2.*(E+F),2.*(H-I),1.-2.*(A+G));}uint seed=1u;void srand(const in int value){seed=uint(value);}float random(){seed=seed*1103515245u+12345u;return float(seed)/4294967295.;}float getRandomValue(const in float min,const in float max){return min+random()*(max-min);}float getRandomLifetime(){float v=particleLifetime*lifetimeVariation;float min_=max(0.,particleLifetime-v);float max_=particleLifetime+v;return getRandomValue(min_,max_);}float getRandomSpeed(){float v=speed*variation;float min_=max(0.,speed-v);float max_=speed+v;return getRandomValue(min_,max_);}vec3 getRandomNormal(){float theta=getRandomValue(-M_PI,M_PI);float cphi=getRandomValue(-1.,1.);float r=sqrt(1.-cphi*cphi);return vec3(sin(theta)*r,cos(theta)*r,cphi);}vec3 getRandomNormalWithAngle(const in float angle){float theta=getRandomValue(-M_PI,M_PI);float cphi=getRandomValue(cos(angle),1.);float r=sqrt(1.-cphi*cphi);return vec3(sin(theta)*r,cos(theta)*r,cphi);}vec3 getRandomNormalWithDirectionAndAngle(const in vec3 direction,const in float angle){vec4 rotation=Quaternion(vec3(0.,0.,1.),direction);vec3 normal=getRandomNormalWithAngle(angle);return multVecQuat(normal,rotation);}vec3 getRandomSurfaceNormal(const in vec3 direction){float theta=getRandomValue(-M_PI,M_PI);float cphi=pow(random(),1./3.);float r=sqrt(1.-cphi*cphi);vec3 normal=vec3(sin(theta)*r,cos(theta)*r,cphi);vec4 rotation=Quaternion(vec3(0.,0.,1.),direction);return multVecQuat(normal,rotation);}vec3 getRandomSphericalVelocity(){vec3 normal=getRandomNormal();float speed=getRandomSpeed();return normal*speed;}int upperBound(const in sampler2D sampler,in int count,const in float value){int first=0;int step=0;while(count>0){int index=first;step=count>>1;index+=step;if(value<texelFetch(sampler,index,0).x){count=step;}else{first=++index;count-=step+1;}}return first;}
#if X3D_NUM_TEX_COORDS>0
void interpolate(const in sampler2D sampler,const in int count,const in float fraction,out int index0){if(count==1||fraction<=texelFetch(sampler,0,0).x){index0=0;}else if(fraction>=texelFetch(sampler,count-1,0).x){index0=count-2;}else{int index=upperBound(sampler,count,fraction);if(index<count)index0=index-1;else index0=0;}}
#endif
#if X3D_NUM_COLORS>0||X3D_NUM_SCALES>0||defined(X3D_POLYLINE_EMITTER)||defined(X3D_SURFACE_EMITTER)||defined(X3D_VOLUME_EMITTER)
void interpolate(const in sampler2D sampler,const in int count,const in float fraction,out int index0,out int index1,out float weight){if(count==1||fraction<=texelFetch(sampler,0,0).x){index0=0;index1=0;weight=0.;}else if(fraction>=texelFetch(sampler,count-1,0).x){index0=count-2;index1=count-1;weight=1.;}else{int index=upperBound(sampler,count,fraction);if(index<count){index1=index;index0=index-1;float key0=texelFetch(sampler,index0,0).x;float key1=texelFetch(sampler,index1,0).x;weight=clamp((fraction-key0)/(key1-key0),0.,1.);}else{index0=0;index1=0;weight=0.;}}}
#endif
#if defined(X3D_SURFACE_EMITTER)||defined(X3D_VOLUME_EMITTER)
vec3 getRandomBarycentricCoord(){float u=random();float v=random();if(u+v>1.){u=1.-u;v=1.-v;}float t=1.-u-v;return vec3(t,u,v);}void getRandomPointOnSurface(const in sampler2D surface,const in int verticesIndex,const in int normalsIndex,out vec4 position,out vec3 normal){float lastAreaSoFar=texelFetch(surface,verticesIndex-1,0).x;float fraction=random()*lastAreaSoFar;int index0;int index1;int index2;float weight;interpolate(surface,verticesIndex,fraction,index0,index1,weight);index0*=3;index1=index0+1;index2=index0+2;vec4 vertex0=texelFetch(surface,verticesIndex+index0,0);vec4 vertex1=texelFetch(surface,verticesIndex+index1,0);vec4 vertex2=texelFetch(surface,verticesIndex+index2,0);vec3 normal0=texelFetch(surface,normalsIndex+index0,0).xyz;vec3 normal1=texelFetch(surface,normalsIndex+index1,0).xyz;vec3 normal2=texelFetch(surface,normalsIndex+index2,0).xyz;vec3 r=getRandomBarycentricCoord();position=r.z*vertex0+r.x*vertex1+r.y*vertex2;normal=save_normalize(r.z*normal0+r.x*normal1+r.y*normal2);}
#endif
${this .functions .join ("\n")}
#if X3D_NUM_TEX_COORDS>0
int getTexCoordIndex0(const in float fraction){int index0=0;interpolate(texCoords,X3D_NUM_TEX_COORDS,fraction,index0);return X3D_NUM_TEX_COORDS+index0*X3D_TEX_COORDS_COUNT;}
#else
#define getTexCoordIndex0(fraction)(-1)
#endif
#if X3D_NUM_COLORS>0
vec4 getColor(const in float fraction){int index0;int index1;float weight;interpolate(colors,X3D_NUM_COLORS,fraction,index0,index1,weight);vec4 color0=texelFetch(colors,X3D_NUM_COLORS+index0,0);vec4 color1=texelFetch(colors,X3D_NUM_COLORS+index1,0);return mix(color0,color1,weight);}
#else
#define getColor(fraction)(vec4(1))
#endif
#if X3D_NUM_SCALES>0
vec3 getScale(const in float fraction){int index0;int index1;float weight;interpolate(scales,X3D_NUM_SCALES,fraction,index0,index1,weight);vec3 scale0=texelFetch(scales,X3D_NUM_SCALES+index0,0).xyz;vec3 scale1=texelFetch(scales,X3D_NUM_SCALES+index1,0).xyz;return mix(scale0,scale1,weight);}
#else
#define getScale(fraction)(vec3(1))
#endif
#if defined(X3D_BOUNDED_VOLUME)
void bounce(const in float deltaTime,const in vec4 fromPosition,inout vec4 toPosition,inout vec3 velocity){Line3 line=Line3(fromPosition.xyz,save_normalize(velocity));vec4 points[ARRAY_SIZE];vec3 normals[ARRAY_SIZE];int numIntersections=getIntersections(boundedVolume,boundedVerticesIndex,boundedNormalsIndex,boundedHierarchyIndex,boundedHierarchyRoot,line,points,normals);if(numIntersections==0)return;Plane3 plane1=plane3(line.point,line.direction);int index=min_index(points,numIntersections,0.,plane1);if(index==-1)return;vec3 point=points[index].xyz;vec3 normal=save_normalize(normals[index]);Plane3 plane2=plane3(point,normal);if(sign(plane_distance(plane2,fromPosition.xyz))==sign(plane_distance(plane2,toPosition.xyz)))return;float damping=length(normals[index]);velocity=reflect(velocity,normal);toPosition=vec4(point+save_normalize(velocity)*.0001,1.);velocity*=damping;}
#endif
void main(){int life=int(input0[0]);float lifetime=input0[1];float elapsedTime=input0[2]+deltaTime;float fraction=elapsedTime/lifetime;srand((gl_VertexID+randomSeed)*randomSeed);if(elapsedTime>lifetime){lifetime=getRandomLifetime();elapsedTime=0.;fraction=0.;output0=vec4(max(life+1,1),lifetime,elapsedTime,getTexCoordIndex0(fraction));
#if defined(X3D_CREATE_PARTICLES)
output1=getColor(fraction);output2=vec4(getRandomVelocity(),0.);output6=getRandomPosition();
#else
output1=vec4(0);output2=vec4(0);output6=vec4(NaN);
#endif
}else{vec3 velocity=input2.xyz;vec4 position=input6;
#if X3D_NUM_FORCES>0
for(int i=0;i<X3D_NUM_FORCES;++i){vec4 force=texelFetch(forces,i,0);float turbulence=force.w;vec3 normal=getRandomNormalWithDirectionAndAngle(force.xyz,turbulence);float speed=length(force.xyz);velocity+=normal*speed;}
#endif
position.xyz+=velocity*deltaTime;
#if defined(X3D_BOUNDED_VOLUME)
bounce(deltaTime,input6,position,velocity);
#endif
output0=vec4(life,lifetime,elapsedTime,getTexCoordIndex0(fraction));output1=getColor(fraction);output2=vec4(velocity,0.);output6=position;}vec3 scale=getScale(fraction);
#if X3D_GEOMETRY_TYPE==POINT||X3D_GEOMETRY_TYPE==SPRITE||X3D_GEOMETRY_TYPE==GEOMETRY
output3=vec4(scale.x,0.,0.,0.);output4=vec4(0.,scale.y,0.,0.);output5=vec4(0.,0.,scale.z,0.);
#elif X3D_GEOMETRY_TYPE==LINE
mat3 m=Matrix3(Quaternion(vec3(0.,0.,1.),output2.xyz));
#if X3D_NUM_SCALES>0
m*=mat3(scale.x,0.,0.,0.,scale.y,0.,0.,0.,scale.z);
#endif
output3=vec4(m[0],0.);output4=vec4(m[1],0.);output5=vec4(m[2],0.);
#else
vec2 s=particleSize*scale.xy;output3=vec4(s.x,0.,0.,0.);output4=vec4(0.,s.y,0.,0.);output5=vec4(0.,0.,scale.z,0.);
#endif
}`
const fragmentShaderSource = /* glsl */ `#version 300 es
precision highp float;void main(){}`
// Vertex shader
const vertexShader = gl .createShader (gl .VERTEX_SHADER);
gl .shaderSource (vertexShader, vertexShaderSource);
gl .compileShader (vertexShader);
if (!gl .getShaderParameter (vertexShader, gl .COMPILE_STATUS))
console .error (gl .getShaderInfoLog (vertexShader));
// Fragment shader
const fragmentShader = gl .createShader (gl .FRAGMENT_SHADER);
gl .shaderSource (fragmentShader, fragmentShaderSource);
gl .compileShader (fragmentShader);
if (!gl .getShaderParameter (fragmentShader, gl .COMPILE_STATUS))
console .error (gl .getShaderInfoLog (fragmentShader));
// Program
const program = gl .createProgram ();
gl .attachShader (program, vertexShader);
gl .attachShader (program, fragmentShader);
gl .transformFeedbackVaryings (program, Array .from ({length: 7}, (_, i) => "output" + i), gl .INTERLEAVED_ATTRIBS);
gl .linkProgram (program);
if (!gl .getProgramParameter (program, gl .LINK_STATUS))
{
console .error (`Couldn't initialize particle shader: ${gl .getProgramInfoLog (program)}`);
// console .error (vertexShaderSource);
}
this .programs .set (key, program);
gl .useProgram (program);
// Attributes
program .inputs = [
[0, gl .getAttribLocation (program, "input0")],
[2, gl .getAttribLocation (program, "input2")],
[6, gl .getAttribLocation (program, "input6")],
];
// Uniforms
program .randomSeed = gl .getUniformLocation (program, "randomSeed");
program .particleLifetime = gl .getUniformLocation (program, "particleLifetime");
program .lifetimeVariation = gl .getUniformLocation (program, "lifetimeVariation");
program .deltaTime = gl .getUniformLocation (program, "deltaTime");
program .particleSize = gl .getUniformLocation (program, "particleSize");
program .boundedVerticesIndex = gl .getUniformLocation (program, "boundedVerticesIndex");
program .boundedNormalsIndex = gl .getUniformLocation (program, "boundedNormalsIndex");
program .boundedHierarchyIndex = gl .getUniformLocation (program, "boundedHierarchyIndex");
program .boundedHierarchyRoot = gl .getUniformLocation (program, "boundedHierarchyRoot");
program .boundedVolume = gl .getUniformLocation (program, "boundedVolume");
for (const key in ParticleSystems_ParticleSampler)
program [key] = gl .getUniformLocation (program, key);
for (const name of this .uniforms .keys ())
program [name] = gl .getUniformLocation (program, name);
gl .uniform1f (gl .getUniformLocation (program, "NaN"), NaN);
// Samplers
for (const name of this .samplers)
{
const location = gl .getUniformLocation (program, name);
gl .uniform1i (location, program [name + "TextureUnit"] = browser .popTextureUnit ());
}
for (const [key, symbol] of Object .entries (ParticleSystems_ParticleSampler))
program [symbol] = program [key + "TextureUnit"];
browser .resetTextureUnits ();
// Field uniforms
for (const callback of this .callbacks)
callback .call (this);
// Return
return program;
},
activateTextures ()
{ },
createTexture ()
{
const
gl = this .getBrowser () .getContext (),
texture = gl .createTexture ();
gl .bindTexture (gl .TEXTURE_2D, texture);
gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_WRAP_S, gl .CLAMP_TO_EDGE);
gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_WRAP_T, gl .CLAMP_TO_EDGE);
gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_MAG_FILTER, gl .NEAREST);
gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_MIN_FILTER, gl .NEAREST);
gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, 1, 1, 0, gl .RGBA, gl .FLOAT, new Float32Array (4));
return texture;
},
popTextureUnit (browser, object, property)
{
const textureUnit = object [property];
if (textureUnit === undefined)
return object [property] = browser .popTextureUnit ();
return textureUnit;
},
});
Object .defineProperties (X3DParticleEmitterNode, external_X_ITE_X3D_X3DNode_default().getStaticProperties ("X3DParticleEmitterNode", "ParticleSystems", 1));
const X3DParticleEmitterNode_default_ = X3DParticleEmitterNode;
;
/* harmony default export */ const ParticleSystems_X3DParticleEmitterNode = (external_X_ITE_X3D_Namespace_default().add ("X3DParticleEmitterNode", X3DParticleEmitterNode_default_));
;// external "__X_ITE_X3D__ .Vector3"
const external_X_ITE_X3D_Vector3_namespaceObject = __X_ITE_X3D__ .Vector3;
var external_X_ITE_X3D_Vector3_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_Vector3_namespaceObject);
;// ./src/x_ite/Components/ParticleSystems/PointEmitter.js
function PointEmitter (executionContext)
{
ParticleSystems_X3DParticleEmitterNode .call (this, executionContext);
this .addType ((external_X_ITE_X3D_X3DConstants_default()).PointEmitter);
// Units
this ._position .setUnit ("length");
}
Object .assign (Object .setPrototypeOf (PointEmitter .prototype, ParticleSystems_X3DParticleEmitterNode .prototype),
{
initialize ()
{
ParticleSystems_X3DParticleEmitterNode .prototype .initialize .call (this);
this ._position .addInterest ("set_position__", this);
this ._direction .addInterest ("set_direction__", this);
this .addDefine ("#define X3D_POINT_EMITTER");
this .addUniform ("position", "uniform vec3 position;");
this .addUniform ("direction", "uniform vec3 direction;");
this .addCallback (this .set_position__);
this .addCallback (this .set_direction__);
this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
{
if (direction == vec3 (0.0))
return getRandomSphericalVelocity ();
else
return direction * getRandomSpeed ();
}`);
this .addFunction (/* glsl */ `vec4 getRandomPosition ()
{
return vec4 (position, 1.0);
}`);
},
getBBox: (() =>
{
const bboxSize = new (external_X_ITE_X3D_Vector3_default()) ();
return function (bbox, { particleLifetime, lifetimeVariation })
{
const
maxParticleLifetime = particleLifetime * (1 + lifetimeVariation),
maxSpeed = this ._speed .getValue () * (1 + this ._variation .getValue ()),
s = maxParticleLifetime * maxSpeed * 2;
return bbox .set (bboxSize .set (s, s, s), this ._position .getValue ());
};
})(),
set_position__ ()
{
const { x, y, z } = this ._position .getValue ();
this .setUniform ("uniform3f", "position", x, y, z);
this ._bbox_changed .addEvent ();
},
set_direction__: (() =>
{
const direction = new (external_X_ITE_X3D_Vector3_default()) ();
return function ()
{
const { x, y, z } = direction .assign (this ._direction .getValue ()) .normalize ();
this .setUniform ("uniform3f", "direction", x, y, z);
};
})(),
});
Object .defineProperties (PointEmitter,
{
... external_X_ITE_X3D_X3DNode_default().getStaticProperties ("PointEmitter", "ParticleSystems", 1, "emitter", "3.2"),
fieldDefinitions:
{
value: new (external_X_ITE_X3D_FieldDefinitionArray_default()) ([
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "metadata", new (external_X_ITE_X3D_Fields_default()).SFNode ()),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "on", new (external_X_ITE_X3D_Fields_default()).SFBool (true)),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "position", new (external_X_ITE_X3D_Fields_default()).SFVec3f ()),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "direction", new (external_X_ITE_X3D_Fields_default()).SFVec3f (0, 1, 0)),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "speed", new (external_X_ITE_X3D_Fields_default()).SFFloat ()),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "variation", new (external_X_ITE_X3D_Fields_default()).SFFloat (0.25)),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "mass", new (external_X_ITE_X3D_Fields_default()).SFFloat ()),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "surfaceArea", new (external_X_ITE_X3D_Fields_default()).SFFloat ()),
]),
enumerable: true,
},
});
const PointEmitter_default_ = PointEmitter;
;
/* harmony default export */ const ParticleSystems_PointEmitter = (external_X_ITE_X3D_Namespace_default().add ("PointEmitter", PointEmitter_default_));
;// ./src/x_ite/Browser/ParticleSystems/X3DParticleSystemsContext.js
const _defaultEmitter = Symbol ();
function X3DParticleSystemsContext () { }
Object .assign (X3DParticleSystemsContext .prototype,
{
getDefaultEmitter ()
{
return this [_defaultEmitter] ??= (() =>
{
const defaultEmitter = new ParticleSystems_PointEmitter (this .getPrivateScene ());
defaultEmitter .setup ();
return defaultEmitter;
})();
},
});
const X3DParticleSystemsContext_default_ = X3DParticleSystemsContext;
;
/* harmony default export */ const ParticleSystems_X3DParticleSystemsContext = (external_X_ITE_X3D_Namespace_default().add ("X3DParticleSystemsContext", X3DParticleSystemsContext_default_));
;// ./src/x_ite/Components/ParticleSystems/X3DParticlePhysicsModelNode.js
function X3DParticlePhysicsModelNode (executionContext)
{
external_X_ITE_X3D_X3DNode_default().call (this, executionContext);
this .addType ((external_X_ITE_X3D_X3DConstants_default()).X3DParticlePhysicsModelNode);
}
Object .assign (Object .setPrototypeOf (X3DParticlePhysicsModelNode .prototype, (external_X_ITE_X3D_X3DNode_default()).prototype),
{
addForce ()
{ },
});
Object .defineProperties (X3DParticlePhysicsModelNode, external_X_ITE_X3D_X3DNode_default().getStaticProperties ("X3DParticlePhysicsModelNode", "ParticleSystems", 1));
const X3DParticlePhysicsModelNode_default_ = X3DParticlePhysicsModelNode;
;
/* harmony default export */ const ParticleSystems_X3DParticlePhysicsModelNode = (external_X_ITE_X3D_Namespace_default().add ("X3DParticlePhysicsModelNode", X3DParticlePhysicsModelNode_default_));
;// external "__X_ITE_X3D__ .X3DCast"
const external_X_ITE_X3D_X3DCast_namespaceObject = __X_ITE_X3D__ .X3DCast;
var external_X_ITE_X3D_X3DCast_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_X3DCast_namespaceObject);
;// ./src/x_ite/Components/ParticleSystems/BoundedPhysicsModel.js
function BoundedPhysicsModel (executionContext)
{
ParticleSystems_X3DParticlePhysicsModelNode .call (this, executionContext);
this .addType ((external_X_ITE_X3D_X3DConstants_default()).BoundedPhysicsModel);
}
Object .assign (Object .setPrototypeOf (BoundedPhysicsModel .prototype, ParticleSystems_X3DParticlePhysicsModelNode .prototype),
{
initialize ()
{
ParticleSystems_X3DParticlePhysicsModelNode .prototype .initialize .call (this);
this ._geometry .addInterest ("set_geometry__", this);
this .set_geometry__ ();
},
getBBox ()
{
return this .geometryNode ?.getBBox ();
},
set_geometry__ ()
{
this .geometryNode ?._rebuild .removeInterest ("addNodeEvent", this);
this .geometryNode = external_X_ITE_X3D_X3DCast_default() ((external_X_ITE_X3D_X3DConstants_default()).X3DGeometryNode, this ._geometry);
this .geometryNode ?._rebuild .addInterest ("addNodeEvent", this);
},
addGeometry (boundedNormals, boundedVertices)
{
if (!this .geometryNode)
return;
if (!this ._enabled .getValue ())
return;
const
damping = this ._damping .getValue (),
normals = this .geometryNode .getNormals () .getValue (),
vertices = this .geometryNode .getVertices () .getValue ();
for (const value of normals)
boundedNormals .push (value * damping);
for (const value of vertices)
boundedVertices .push (value);
},
});
Object .defineProperties (BoundedPhysicsModel,
{
... external_X_ITE_X3D_X3DNode_default().getStaticProperties ("BoundedPhysicsModel", "ParticleSystems", 2, "physics", "3.2"),
fieldDefinitions:
{
value: new (external_X_ITE_X3D_FieldDefinitionArray_default()) ([
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "metadata", new (external_X_ITE_X3D_Fields_default()).SFNode ()),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "enabled", new (external_X_ITE_X3D_Fields_default()).SFBool (true)),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "damping", new (external_X_ITE_X3D_Fields_default()).SFFloat (1)), // skip test
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "geometry", new (external_X_ITE_X3D_Fields_default()).SFNode ()),
]),
enumerable: true,
},
});
const BoundedPhysicsModel_default_ = BoundedPhysicsModel;
;
/* harmony default export */ const ParticleSystems_BoundedPhysicsModel = (external_X_ITE_X3D_Namespace_default().add ("BoundedPhysicsModel", BoundedPhysicsModel_default_));
;// ./src/x_ite/Components/ParticleSystems/ConeEmitter.js
function ConeEmitter (executionContext)
{
ParticleSystems_X3DParticleEmitterNode .call (this, executionContext);
this .addType ((external_X_ITE_X3D_X3DConstants_default()).ConeEmitter);
// Units
this ._position .setUnit ("length");
this ._angle .setUnit ("angle");
}
Object .assign (Object .setPrototypeOf (ConeEmitter .prototype, ParticleSystems_X3DParticleEmitterNode .prototype),
{
initialize ()
{
ParticleSystems_X3DParticleEmitterNode .prototype .initialize .call (this);
this ._position .addInterest ("set_position__", this);
this ._direction .addInterest ("set_direction__", this);
this ._angle .addInterest ("set_angle__", this);
this .addDefine ("#define X3D_CONE_EMITTER");
this .addUniform ("position", "uniform vec3 position;");
this .addUniform ("direction", "uniform vec3 direction;");
this .addUniform ("angle", "uniform float angle;");
this .addCallback (this .set_position__);
this .addCallback (this .set_direction__);
this .addCallback (this .set_angle__);
this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
{
if (direction == vec3 (0.0))
{
return getRandomSphericalVelocity ();
}
else
{
vec3 normal = getRandomNormalWithDirectionAndAngle (direction, angle);
float speed = getRandomSpeed ();
return normal * speed;
}
}`);
this .addFunction (/* glsl */ `vec4 getRandomPosition ()
{
return vec4 (position, 1.0);
}`);
},
getBBox: (() =>
{
const bboxSize = new (external_X_ITE_X3D_Vector3_default()) ();
return function (bbox, { particleLifetime, lifetimeVariation })
{
const
maxParticleLifetime = particleLifetime * (1 + lifetimeVariation),
maxSpeed = this ._speed .getValue () * (1 + this ._variation .getValue ()),
s = maxParticleLifetime * maxSpeed * 2;
return bbox .set (bboxSize .set (s, s, s), this ._position .getValue ());
};
})(),
set_position__ ()
{
const { x, y, z } = this ._position .getValue ();
this .setUniform ("uniform3f", "position", x, y, z );
this ._bbox_changed .addEvent ();
},
set_direction__ ()
{
const { x, y, z } = this ._direction .getValue ();
this .setUniform ("uniform3f", "direction", x, y, z );
},
set_angle__ ()
{
this .setUniform ("uniform1f", "angle", this ._angle .getValue ());
},
});
Object .defineProperties (ConeEmitter,
{
... external_X_ITE_X3D_X3DNode_default().getStaticProperties ("ConeEmitter", "ParticleSystems", 1, "emitter", "3.2"),
fieldDefinitions:
{
value: new (external_X_ITE_X3D_FieldDefinitionArray_default()) ([
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "metadata", new (external_X_ITE_X3D_Fields_default()).SFNode ()),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "on", new (external_X_ITE_X3D_Fields_default()).SFBool (true)),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "position", new (external_X_ITE_X3D_Fields_default()).SFVec3f ()),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "direction", new (external_X_ITE_X3D_Fields_default()).SFVec3f (0, 1, 0)),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "angle", new (external_X_ITE_X3D_Fields_default()).SFFloat (0.785398)),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "speed", new (external_X_ITE_X3D_Fields_default()).SFFloat ()),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "variation", new (external_X_ITE_X3D_Fields_default()).SFFloat (0.25)),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "mass", new (external_X_ITE_X3D_Fields_default()).SFFloat ()),
new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "surfaceArea", new (external_X_ITE_X3D_Fields_default()).SFFloat ()),
]),
enumerable: true,
},
});
const ConeEmitter_default_ = ConeEmitter;
;
/* harmony default export */ const ParticleSystems_ConeEmitter = (external_X_ITE_X3D_Namespace_default().add ("ConeEmitter", ConeEmitter_default_));
;// ./src/x_ite/Components/ParticleSystems/ExplosionEmitter.js
function ExplosionEmitter (executionContext)
{
ParticleSystems_X3DParticleEmitterNode .call (this, executionContext);
this .addType ((external_X_ITE_X3D_X3DConstants_default()).ExplosionEmitter);
// Units
this ._position .setUnit ("length");
}
Object .assign (Object .setPrototypeOf (ExplosionEmitter .prototype, ParticleSystems_X3DParticleEmitterNode .prototype),
{
initialize ()
{
ParticleSystems_X3DParticleEmitterNode .prototype .initialize .call (this);
this ._position .addInterest ("set_position__", this);
this .addDefine ("#define X3D_EXPLOSION_EMITTER");
this .addUniform ("position", "uniform vec3 position;");
this .addCallback (this .set_position__);
this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
{
return getRandomSphericalVelocity ();
}`);
this .addFunction (/* glsl */ `vec4 getRandomPosition ()
{
return vec4 (position, 1.0);
}`);
},
getBBox: (() =>
{
const bboxSize = new (external_X_ITE_X3D_Vector3_default()) ();
return function (bbox, { particleLifetime, lifetimeVariation })
{
const
maxParticleLifetime = particleLifetime * (1 + lifetimeVariation),
maxSpeed = this ._speed .getValue () * (1 + this