Advertisement
Guest User

Untitled

a guest
May 1st, 2016
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const
  2.   pVert = `
  3.     attribute vec3  color;
  4.     attribute vec2  scale;
  5.     attribute float size;
  6.     attribute float rotation;
  7.     attribute float opacity;
  8.     attribute float active;
  9.  
  10.     varying vec3 vColor;
  11.     varying vec2 vScale;
  12.     varying float vRotation;
  13.     varying float vOpacity;
  14.     varying float vActive;
  15.  
  16.     void main() {
  17.       vColor    = color;
  18.       vScale    = scale;
  19.       vRotation = rotation;
  20.       vOpacity  = opacity;
  21.       vActive   = active;
  22.      
  23.       vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
  24.       if (active > 0.5) { gl_PointSize = size * (300.0 / length(mvPosition.xyz)); };
  25.       gl_Position = projectionMatrix * mvPosition;
  26.     }
  27.   `,
  28.   pFrag = `
  29.     uniform sampler2D map;
  30.  
  31.     varying vec3  vColor;
  32.     varying vec2  vScale;
  33.     varying float vRotation;
  34.     varying float vOpacity;
  35.     varying float vActive;
  36.    
  37.     void main() {
  38.       float vMid = 0.5;
  39.       if (vActive > 0.5) {
  40.         vec2 rotated = vec2(
  41.           cos(vRotation) * (gl_PointCoord.x / vScale.x - vMid) + sin(vRotation) * (gl_PointCoord.y - vMid) + vMid,
  42.           1.0 - (cos(vRotation) * (gl_PointCoord.y / vScale.y - vMid) - sin(vRotation) * (gl_PointCoord.x - vMid) + vMid)
  43.         );
  44.         gl_FragColor = vec4(vColor, vOpacity);
  45.         gl_FragColor = gl_FragColor * texture2D(map, rotated);
  46.       } else {
  47.         gl_FragColor = vec4(0, 0, 0, 0);
  48.       }
  49.     }
  50.   `
  51.  
  52. class particleSystem {
  53.   pCld: THREE.PointCloud      = null;
  54.   pGeo: THREE.BufferGeometry  = new THREE.BufferGeometry;
  55.   pMat: THREE.ShaderMaterial  = new THREE.ShaderMaterial;
  56.   pNum: number                = 100;
  57.   pDef;
  58.   pAct: boolean[]             = [];
  59.   pLif: number[]              = [];
  60.  
  61.   p = {
  62.     position: null as THREE.BufferAttribute,
  63.     color:    null as THREE.BufferAttribute,
  64.     scale:    null as THREE.BufferAttribute,
  65.     size:     null as THREE.BufferAttribute,
  66.     rotation: null as THREE.BufferAttribute,
  67.     opacity:  null as THREE.BufferAttribute,
  68.     active:   null as THREE.BufferAttribute
  69.   };
  70.  
  71.   constructor(maxParticles: number, texture: THREE.Texture, extraFunction?: Function) {
  72.     this.pNum = maxParticles;
  73.    
  74.     let
  75.       positions: Float32Array = new Float32Array(maxParticles * 3),
  76.       colors:    Float32Array = new Float32Array(maxParticles * 3),
  77.       scales:    Float32Array = new Float32Array(maxParticles * 2),
  78.       sizes:     Float32Array = new Float32Array(maxParticles),
  79.       rotations: Float32Array = new Float32Array(maxParticles),
  80.       opacities: Float32Array = new Float32Array(maxParticles),
  81.       actives:   Float32Array = new Float32Array(maxParticles);
  82.    
  83.     // default values
  84.     for (let p = 0; p < this.pNum; p ++) {
  85.       this.pDef = {
  86.         id: p,
  87.         position: new Sup.Math.Vector3(),
  88.         scale: new Sup.Math.Vector2(1, 1),
  89.         color: new Sup.Color (1.0, 1.0, 1.0),
  90.         size: 1.0,
  91.         rotation: 0,
  92.         opacity: 1.0,
  93.         active: false
  94.       };
  95.      
  96.       if (extraFunction != undefined) extraFunction(this.pDef);
  97.      
  98.       positions [p * 3 + 0]   = this.pDef.position.x;
  99.       positions [p * 3 + 1]   = this.pDef.position.y;
  100.       positions [p * 3 + 2]   = this.pDef.position.z;
  101.      
  102.       colors    [p * 3 + 0]   = this.pDef.color.r;
  103.       colors    [p * 3 + 1]   = this.pDef.color.g;
  104.       colors    [p * 3 + 2]   = this.pDef.color.b;
  105.      
  106.       scales    [p * 2 + 0]   = this.pDef.scale.x;
  107.       scales    [p * 2 + 1]   = this.pDef.scale.y;
  108.      
  109.       sizes     [p]           = this.pDef.size;
  110.       rotations [p]           = this.pDef.rotation;
  111.       opacities [p]           = this.pDef.opacity;
  112.       actives   [p]           = this.pDef.active ? 1.0 : 0.0;
  113.      
  114.       this.pAct [p]           = this.pDef.active;
  115.       this.pLif [p]           = 0;
  116.     }
  117.    
  118.     // shader values
  119.     this.pMat.uniforms        = {map: {type: "t", value: texture}};
  120.     this.pMat.vertexShader    = pVert;
  121.     this.pMat.fragmentShader  = pFrag;
  122.     this.pMat.transparent     = true;
  123.     this.pMat.depthWrite      = false;
  124.    
  125.     // attribute values
  126.     this.p.position           = new THREE.BufferAttribute(positions, 3);
  127.     this.p.color              = new THREE.BufferAttribute(colors,    3);
  128.     this.p.scale              = new THREE.BufferAttribute(scales,    2);
  129.     this.p.size               = new THREE.BufferAttribute(sizes,     1);
  130.     this.p.rotation           = new THREE.BufferAttribute(rotations, 1);
  131.     this.p.opacity            = new THREE.BufferAttribute(opacities, 1);
  132.     this.p.active             = new THREE.BufferAttribute(actives,   1)
  133.    
  134.     this.pGeo.addAttribute('position', this.p.position);
  135.     this.pGeo.addAttribute('color',    this.p.color);
  136.     this.pGeo.addAttribute('scale',    this.p.scale);
  137.     this.pGeo.addAttribute('size',     this.p.size);
  138.     this.pGeo.addAttribute('rotation', this.p.rotation);
  139.     this.pGeo.addAttribute('opacity',  this.p.opacity);
  140.     this.pGeo.addAttribute('active',   this.p.active);
  141.    
  142.     this.pCld = new THREE.PointCloud(this.pGeo, this.pMat);
  143.   };
  144.  
  145.   animate(particleFunction: Function) {
  146.     for (let p = 0; p < this.pNum; p ++) {
  147.       if (this.pAct[p]) {
  148.         let pSt = {
  149.           id: p,
  150.           position: new Sup.Math.Vector3(
  151.             this.p.position.getX(p),
  152.             this.p.position.getY(p),
  153.             this.p.position.getZ(p)
  154.           ),
  155.           color: new Sup.Color(
  156.             this.p.color.getX(p),
  157.             this.p.color.getY(p),
  158.             this.p.color.getZ(p)
  159.           ),
  160.           scale: new Sup.Math.Vector2(
  161.             this.p.scale.getX(p),
  162.             this.p.scale.getY(p)
  163.           ),
  164.           size: this.p.size.array[p],
  165.           rotation: this.p.rotation.array[p],
  166.           opacity: this.p.opacity.array[p],
  167.           active: true,
  168.           life: this.pLif[p]
  169.         };
  170.  
  171.         particleFunction(pSt);
  172.  
  173.         this.p.position.setXYZ(p,
  174.           pSt.position.x,
  175.           pSt.position.y,
  176.           pSt.position.z
  177.         );
  178.         this.p.color.setXYZ( p,
  179.           pSt.color.r,
  180.           pSt.color.g,
  181.           pSt.color.b
  182.         );
  183.         this.p.scale.setXY(p,
  184.           pSt.scale.x,
  185.           pSt.scale.y
  186.         );
  187.         this.p.size.array[p] = pSt.size;
  188.         this.p.rotation.array[p] = pSt.rotation;
  189.         this.p.opacity.array[p] = pSt.opacity;
  190.         this.p.active.array[p] = pSt.active ? 1.0 : 0.0;
  191.         this.pAct[p] = pSt.active;
  192.        
  193.         this.pLif[p] ++;
  194.         if (!pSt.active) this.pLif[p] = 0;
  195.       }
  196.     }
  197.    
  198.     this.p.position.needsUpdate    = true;
  199.     this.p.size.needsUpdate    = true;
  200.     this.p.scale.needsUpdate = true;
  201.     this.p.color.needsUpdate    = true;
  202.     this.p.rotation.needsUpdate    = true;
  203.     this.p.opacity.needsUpdate    = true;
  204.     this.p.active.needsUpdate = true;
  205.   }
  206.  
  207.   destroy() {
  208.     for (let name in this.pGeo.attributes) {
  209.       let attribute: THREE.BufferAttribute = this.pGeo.attributes[ name ];
  210.      
  211.       if (typeof(attribute.array) != 'undefined') {
  212.         delete attribute.array;
  213.         attribute = null;
  214.       }
  215.     }
  216.    
  217.     this.pGeo.dispose();
  218.     this.pMat.dispose();
  219.    
  220.     this.pCld = null;
  221.     this.pGeo = null;
  222.     this.pMat = null;
  223.    
  224.     delete this.pGeo;
  225.     delete this.pMat;
  226.     delete this.pCld;
  227.   }
  228. }
  229.  
  230. class particleEmitterOptions {
  231.  
  232.   colorRange = {
  233.     start: new THREE.Color(1.0, 1.0, 1.0) as THREE.Color,
  234.     end:   new THREE.Color(1.0, 1.0, 1.0) as THREE.Color
  235.   }
  236.  
  237.   sizeRange = {
  238.     start: 1.0 as number,
  239.     end:   1.0 as number
  240.   }
  241.  
  242.   rotationRange = {
  243.     start: 0.0 as number,
  244.     end:   0.0 as number
  245.   }
  246.  
  247.   opacityRange = {
  248.     start: 1.0 as number,
  249.     end:   1.0 as number
  250.   }
  251.  
  252.   getColor(): THREE.Color {
  253.     return new THREE.Color(
  254.       Sup.Math.Random.float(this.colorRange.start.r, this.colorRange.end.r),
  255.       Sup.Math.Random.float(this.colorRange.start.g, this.colorRange.end.g),
  256.       Sup.Math.Random.float(this.colorRange.start.b, this.colorRange.end.b)
  257.     )
  258.   }
  259.  
  260.   getSize():     number { return Sup.Math.Random.float(this.sizeRange.start,     this.sizeRange.end    ) };
  261.   getRotation(): number { return Sup.Math.Random.float(this.rotationRange.start, this.rotationRange.end) };
  262.   getOpacity():  number { return Sup.Math.Random.float(this.opacityRange.start,  this.opacityRange.end ) };
  263.  
  264. }
  265.  
  266. class pointParticleEmitter {
  267.   start:          Sup.Math.Vector3;
  268.   pSys: particleSystem;
  269.   cId:            number;
  270.   options:        particleEmitterOptions;
  271.  
  272.   constructor(pSys: particleSystem, start: Sup.Math.Vector3) {
  273.     this.start          = start;
  274.     this.pSys = pSys
  275.     this.cId            = 0;
  276.     this.options        = new particleEmitterOptions();
  277.   }
  278.  
  279.   burst(numParticles: number) {
  280.     for (let p = 0; p < numParticles; p ++) {
  281.       const pSysAct = this.pSys.pAct
  282.       const toActivate = pSysAct.indexOf(false);
  283.      
  284.       if (toActivate !== -1) {
  285.         let cc = this.options.getColor();
  286.         pSysAct[toActivate] = true;
  287.        
  288.         this.pSys.p.position.setXYZ(toActivate, this.start.x, this.start.y, this.start.z);
  289.         this.pSys.p.color.   setXYZ(toActivate, cc.r,         cc.b,         cc.g);
  290.        
  291.         this.pSys.p.size.    array[toActivate] = this.options.getSize();
  292.         this.pSys.p.rotation.array[toActivate] = this.options.getRotation();
  293.         this.pSys.p.opacity .array[toActivate] = this.options.getOpacity();
  294.       }
  295.     }
  296.   }
  297. }
  298.  
  299. class cubeParticleEmitter {
  300.   start:          Sup.Math.Vector3;
  301.   end:            Sup.Math.Vector3;
  302.   offset:         Sup.Math.Vector3;
  303.   pSys: particleSystem;
  304.   cId:            number;
  305.   options:        particleEmitterOptions;
  306.   bounds:         number[][];
  307.  
  308.   constructor(pSys: particleSystem, start: Sup.Math.Vector3, end: Sup.Math.Vector3) {
  309.     this.start          = start;
  310.     this.end            = end;
  311.     this.offset         = new Sup.Math.Vector3;
  312.     this.pSys           = pSys;
  313.     this.cId            = 0;
  314.     this.options        = new particleEmitterOptions();
  315.     this.bounds = [
  316.       [Math.min(start.x, end.x), Math.max(start.x, end.x)],
  317.       [Math.min(start.y, end.y), Math.max(start.y, end.y)],
  318.       [Math.min(start.z, end.z), Math.max(start.z, end.z)]
  319.     ];
  320.   }
  321.  
  322.   burst(numParticles: number) {
  323.     let a: number[] = [];
  324.    
  325.     for (let p = 0; p < numParticles; p ++) {
  326.       const pSysAct = this.pSys.pAct;
  327.       const toActivate = pSysAct.indexOf(false);
  328.       a.push(toActivate);
  329.      
  330.       if (toActivate !== -1) {
  331.         let cc = this.options.getColor();
  332.         pSysAct[toActivate] = true;
  333.        
  334.         this.pSys.p.position.setXYZ(
  335.           toActivate,
  336.           this.offset.x + Sup.Math.Random.float(this.bounds[0][0], this.bounds[0][1]),
  337.           this.offset.y + Sup.Math.Random.float(this.bounds[1][0], this.bounds[1][1]),
  338.           this.offset.z + Sup.Math.Random.float(this.bounds[2][0], this.bounds[2][1])
  339.         );
  340.        
  341.         this.pSys.p.color.   setXYZ(toActivate, cc.r,         cc.b,         cc.g);
  342.        
  343.         this.pSys.p.size.    array[toActivate] = this.options.getSize();
  344.         this.pSys.p.rotation.array[toActivate] = this.options.getRotation();
  345.         this.pSys.p.opacity .array[toActivate] = this.options.getOpacity();
  346.       }
  347.     }
  348.   }
  349. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement