Skip to content

Instantly share code, notes, and snippets.

@movitto
Last active January 4, 2016 01:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save movitto/8549607 to your computer and use it in GitHub Desktop.
Save movitto/8549607 to your computer and use it in GitHub Desktop.
Patch to squarefeet/ShaderParticleEngine adding 'spiral' emitter type
134a135,188
> /**
> * Create a new THREE.Vector3 instance and project it onto a random point
> * on a spiral (in the XY-plane) centered at `base` and with randomized radius.
> *
> * Spiral generated by rotating series of ellipses generated with the
> * specified skew in accordance with the density wave theory
> *
> * @param {THREE.Vector3} base
> * @param {Number} radius
> * @param {THREE.Vector3} radiusSpread
> * @param {THREE.Vector3} radiusScale
> * @param {Number} radiusSpreadClamp
> * @param {Number} radiusMax
> * @param {Number} skew
> *
> * @private
> *
> * @return {THREE.Vector3}
> */
> randomVector3OnSpiral: function( base, radius, radiusSpread, radiusScale, radiusSpreadClamp, radiusMax, skew ) {
> /// generate vertex in same manner as disk...
> var t = 6.2832 * Math.random();
> var rand = this._randomFloat( radius, radiusSpread );
>
> if( radiusSpreadClamp ) {
> rand = Math.round( rand / radiusSpreadClamp ) * radiusSpreadClamp;
> }
>
> var p = rand / radiusMax;
>
> // ...except w/ skew applied to form ellipse
> var vec = new THREE.Vector3( Math.cos(t), Math.sin(t) * skew, 0 );
>
> // rotate ellipse by percentage total distance it is in total spiral,
> // we could parameterize this to determine the number of rotations
> // that formal the spiral, determining the # of arms
> var angle = 6.2832 * p;
> vec.applyAxisAngle(new THREE.Vector3(0,0,1), angle);
>
> /// from here it's the same as disk
> vec.multiplyScalar( rand );
>
> if ( radiusScale ) {
> vec.multiply( radiusScale );
> }
>
> /// particles near the center have greater z values forming center
> vec.z = (Math.random() - 0.5 ) * Math.pow(0.975, vec.length()) * 10;
>
> vec.add( base );
>
> return vec ;
> },
>
162a217,247
> /**
> * Create a new THREE.Vector3 instance, and given a spiral w/ a specified radius and
> * point `position` on spiral, set direction towards sphere center with tangential
> * component and random magnitude
> *
> * @param {THREE.Vector3} base
> * @param {THREE.Vector3} position
> * @param {Number} speed
> * @param {Number} speedSpread
> * @param {Number} radiusMax
> *
> * @private
> *
> * @return {THREE.Vector3}
> */
> randomVelocityVector3OnSpiral: function( base, position, speed, speedSpread, radiusMax ){
> var direction = new THREE.Vector3().subVectors( base, position );
>
> /// speed scales according to distance
> var d = direction.length();
> var p = d / radiusMax;
>
> direction.normalize()
> .multiplyScalar( Math.abs( this._randomFloat( speed / p, speedSpread ) ) )
> .negate();
> direction.add(direction.cross(new THREE.Vector3(0,0,-1)).multiplyScalar(p));
>
> return direction;
> },
>
>
270a356,400
> /**
> * Given an existing particle vector, project it onto a random point
> * on a spiral (in the XY-plane) centered at `base` and with randomized radius.
> *
> * @private
> *
> * @param {THREE.Vector3} v
> * @param {THREE.Vector3} base
> * @param {Number} radius
> * @param {THREE.Vector3} radiusSpread
> * @param {THREE.Vector3} radiusScale
> * @param {Number} radiusSpreadClamp
> * @param {Number} radiusMax
> * @param {Number} skew
> */
> randomizeExistingVector3OnSpiral: function( v, base, radius, radiusSpread, radiusScale, radiusSpreadClamp, radiusMax, skew ) {
> var rand = Math.random,
> t = 6.2832 * rand(),
> rand = Math.abs( this._randomFloat( radius, radiusSpread ) );
>
> if( radiusSpreadClamp ) {
> rand = Math.round( rand / radiusSpreadClamp ) * radiusSpreadClamp;
> }
>
> var p = rand / radiusMax;
>
> v.set(
> Math.cos( t ),
> Math.sin( t ) * skew,
> 0
> );
>
> var angle = 6.2832 * p;
> v.applyAxisAngle(new THREE.Vector3(0,0,1), angle);
> v.multiplyScalar( rand );
>
> if ( radiusScale ) {
> v.multiply( radiusScale );
> }
>
> v.z = (Math.random() - 0.5 ) * Math.pow(0.975, v.length()) * 10;
>
> v.add( base );
> },
>
277a408,423
> randomizeExistingVelocityVector3OnSpiral: function( v, base, position, speed, speedSpread, radiusMax ) {
> v.copy(position).sub(base);
>
> /// speed scales according to distance
> var d = v.length();
> var p = d / radiusMax;
>
> /// velocity component towards center of spiral
> v.normalize()
> .multiplyScalar( Math.abs( this._randomFloat( speed / p, speedSpread ) ) )
> .negate();
>
> /// tangential velocity component (again scale w/ distance)
> v.add(v.cross(new THREE.Vector3(0,0,-1)).multiplyScalar(p));
> },
>
312a459
> that.fadeFactor = parseFloat( typeof options.fadeFactor === 'number' ? options.fadeFactor : 0.0 );
325a473
> fadeFactor: { type: 'f', value: that.fadeFactor },
463,464c611,615
< }
< else {
---
> }else if(emitter.type === 'spiral'){
> vertices[i] = that._randomVector3OnSpiral( emitter.position, emitter.radius, emitter.radiusSpread, emitter.radiusScale, emitter.radiusSpreadClamp, emitter.radiusMax, emitter.skew );
> velocity[i] = that._randomVelocityVector3OnSpiral( vertices[i], emitter.position, emitter.speed, emitter.speedSpread, emitter.radiusMax );
>
> }else {
707a859
> 'uniform float fadeFactor;',
710d861
<
777a929,933
> /// optional fade w/ distance
> 'if( fadeFactor != 0.0 ) {',
> 'vColor = mix( vColor, vec4(0.0, 0.0, 0.0, 0.0), 1.0 / length ( pos.xyz ) * fadeFactor );',
> '}',
>
852c1008
< that.type = (options.type === 'cube' || options.type === 'sphere' || options.type === 'disk') ? options.type : 'cube';
---
> that.type = (options.type === 'cube' || options.type === 'sphere' || options.type === 'disk' || options.type == 'spiral') ? options.type : 'cube';
857c1013
< // These two properties are only used when this.type === 'sphere' or 'disk'
---
> // These properties are only used when this.type === 'sphere', 'disk', or 'spiral'
861a1018
> that.radiusMax = that.radius + that.radiusSpread;
869,870c1026
<
< // And again here; only used when this.type === 'sphere' or 'disk'
---
> // And again here; only used when this.type === 'sphere', 'disk', or 'spiral'
873a1030,1032
> /// These properties are only used when this.type === 'spiral'
> that.skew = parseFloat( typeof options.skew === 'number' ? options.skew : 1.0 );
>
943c1102,1103
< ( type === 'disk' && that.radius === 0 )
---
> ( type === 'disk' && that.radius === 0 ) ||
> ( type === 'spiral' && that.radius === 0 )
967a1128,1132
> }
>
> else if( type === 'spiral') {
> that._randomizeExistingVector3OnSpiral( particlePosition, that.position, that.radius, that.radiusSpread, that.radiusScale, that.radiusSpreadClamp, that.radiusMax, that.skew );
> that._randomizeExistingVelocityVector3OnSpiral( particleVelocity, that.position, particlePosition, that.speed, that.speedSpread, that.radiusMax );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment