Last active
January 4, 2016 01:39
-
-
Save movitto/8549607 to your computer and use it in GitHub Desktop.
Patch to squarefeet/ShaderParticleEngine adding 'spiral' emitter type
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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