|
// The body of the plugin's setup() function, |
|
// which takes a single argument, the Visualizer context, |
|
// and is called once, prior to entering the render loop. |
|
|
|
// Initialize particle count and array in context memory |
|
context.memory.spark_count = 0; |
|
context.memory.sparks = []; |
|
|
|
// Create a function to get the current emitter swing settings |
|
context.memory.getSwingInfo = function() { |
|
|
|
// Base position |
|
let x_base = context.plugin.getSettingValue('Emitter', 'X Pos'); |
|
let y_base = context.plugin.getSettingValue('Emitter', 'Y Pos'); |
|
let z_base = context.plugin.getSettingValue('Emitter', 'Z Pos'); |
|
|
|
// Swing params |
|
let modulator = context.plugin.getSettingValue('Emitter', 'Swing Mod'); |
|
let mod_amount = context.modulators.getModulatorValue( modulator ) || (Math.random() * 1); |
|
let radius = context.plugin.getSettingValue('Emitter', 'Swing Radius'); |
|
let duration = context.plugin.getSettingValue('Emitter', 'Swing Duration'); |
|
let curve = context.plugin.getSettingValue('Emitter', 'Swing Curve'); |
|
let x_min = x_base - radius, x_max = x_base + radius; |
|
let y_min = y_base - radius, y_max = y_base + radius; |
|
let z_min = z_base - radius, z_max = z_base + radius; |
|
|
|
// Bundle and return the settings |
|
return { |
|
radius: radius, |
|
curve: curve, |
|
duration: duration, |
|
x_base: x_base, |
|
y_base: y_base, |
|
z_base: z_base, |
|
x_min: x_min * mod_amount, |
|
x_max: x_max * mod_amount, |
|
y_min: y_min * mod_amount, |
|
y_max: y_max * mod_amount, |
|
z_min: z_min * mod_amount, |
|
z_max: z_max * mod_amount |
|
}; |
|
|
|
}; |
|
|
|
// Create a function to setup the swing motion for the emitter |
|
context.memory.setupSwing = function() { |
|
let swing = context.memory.getSwingInfo(); |
|
swing.x_ease = context.modulators.getEaser(swing.curve, swing.x_max, swing.x_min, swing.duration * (Math.random() * 1), Setting.LOOPS.PING_PONG); |
|
swing.y_ease = context.modulators.getEaser(swing.curve, swing.y_min, swing.y_max, swing.duration * (Math.random() * 1), Setting.LOOPS.PING_PONG); |
|
swing.z_ease = context.modulators.getEaser(swing.curve, swing.z_max, swing.z_min, swing.duration * (Math.random() * 1), Setting.LOOPS.PING_PONG); |
|
context.memory.swing = swing; |
|
}; |
|
|
|
// Create a function to check if the emitter swing info changed since last frame. |
|
// Remember, the user can change the setting values during visualization. |
|
context.memory.swingChanged = function() { |
|
let old = context.memory.swing; |
|
let current = context.memory.getSwingInfo(); |
|
let changed = ( |
|
current.curve !== old.curve || |
|
current.duration !== old.duration || |
|
current.radius !== old.radius || |
|
current.x_base !== old.x_base || |
|
current.y_base !== old.y_base || |
|
current.z_base !== old.z_base |
|
); |
|
|
|
return changed; |
|
} |
|
|
|
// Create a function to get the current emitter location |
|
context.memory.getEmitterLocation = function() { |
|
|
|
// Build/rebuild the swing eases if need be |
|
if (!context.memory.swing || context.memory.swingChanged()) context.memory.setupSwing(); |
|
|
|
// Get the current position of the emitter |
|
let x = context.memory.swing.x_ease(); |
|
let y = context.memory.swing.y_ease(); |
|
let z = context.memory.swing.z_ease(); |
|
return new THREE.Vector3(x,y,z); |
|
}; |
|
|
|
// Create a funcion to get a random target position for a new particle, within the min and max distance |
|
context.memory.getSparkTarget = function(emitter_loc) { |
|
let min_distance = context.plugin.getSettingValue('Particle Motion', 'Min Distance'); |
|
let max_distance = context.plugin.getSettingValue('Particle Motion', 'Max Distance'); |
|
let dx = Math.floor(Math.random() * (max_distance - min_distance)) + min_distance; |
|
let dy = Math.floor(Math.random() * (max_distance - min_distance)) + min_distance; |
|
let dz = Math.floor(Math.random() * (max_distance - min_distance)) + min_distance; |
|
dx = (Math.random() > 0.5) ? dx : -dx; |
|
dy = (Math.random() > 0.5) ? dy : -dy; |
|
dz = (Math.random() > 0.5) ? dz : -dz; |
|
return new THREE.Vector3(emitter_loc.x + dx, emitter_loc.y + dy, emitter_loc.z + dz); |
|
}; |
|
|
|
// Create a function to get the lifespan for a spark based on current setting and modulation |
|
context.memory.getSparkLifeSpan = function() { |
|
let max_life = context.plugin.getSettingValue('Particle', 'Life Span'); |
|
let modulator = context.plugin.getSettingValue('Particle','Life Span Mod'); |
|
let life_span = context.modulators.getModulatorValue( modulator ) * max_life || (Math.random() * max_life) + 1; |
|
return life_span; |
|
}; |
|
|
|
// Create a function to get a random size for a spark |
|
context.memory.getSparkSize = function() { |
|
let max_size = context.plugin.getSettingValue('Particle', 'Max Size'); |
|
let modulator = context.plugin.getSettingValue('Particle','Size Mod'); |
|
let spark_size = context.modulators.getModulatorValue( modulator ) * max_size || (Math.random() * max_size) + 1; |
|
return spark_size; |
|
}; |
|
|
|
// Create a function to build the material for a new spark (which will be modified over time) |
|
context.memory.getSparkMaterial = function() { |
|
let color = context.plugin.getSettingValue('Particle', 'Color'); |
|
let material = new THREE.MeshLambertMaterial({color: color, emissive: color, emissiveIntensity:1, side:THREE.DoubleSide}); |
|
return material; |
|
}; |
|
|
|
// Create a function to spawn a new particle |
|
context.memory.spawn = function() { |
|
|
|
// Get the key attributes of the spark |
|
let spark_num = context.memory.spark_count; |
|
let spark_size = context.memory.getSparkSize(); |
|
let life_span = context.memory.getSparkLifeSpan(); |
|
let emitter_loc = context.memory.getEmitterLocation(); |
|
|
|
// Create and register material |
|
let color = context.plugin.getSettingValue('Particle', 'Color'); |
|
let spark_mat = context.memory.getSparkMaterial(); |
|
context.registerMaterial(`spark-material-${spark_num}`, spark_mat); |
|
|
|
// Create and register the spark geometry |
|
let spark_geo = new THREE.DodecahedronGeometry(spark_size); |
|
context.registerGeometry(`spark-geo-${spark_num}`, spark_geo); |
|
|
|
// Create and regsister the mesh |
|
let spark_mesh = new THREE.Mesh(spark_geo, spark_mat); |
|
spark_mesh.position.set(emitter_loc.x, emitter_loc.y, emitter_loc.z); |
|
context.addToScene(spark_mesh); |
|
|
|
// Create the target for the spark and create motion eases |
|
let spark_target = context.memory.getSparkTarget(emitter_loc); |
|
|
|
// Vary the easing curves for each |
|
let x_curve = context.plugin.getSettingValue('Particle Motion', 'X Curve'); |
|
let y_curve = context.plugin.getSettingValue('Particle Motion', 'Y Curve'); |
|
let z_curve = context.plugin.getSettingValue('Particle Motion', 'Z Curve'); |
|
let x_ease = context.modulators.getEaser(x_curve, emitter_loc.x, spark_target.x, life_span); |
|
let y_ease = context.modulators.getEaser(y_curve, emitter_loc.y, spark_target.y, life_span); |
|
let z_ease = context.modulators.getEaser(z_curve, emitter_loc.z, spark_target.z, life_span); |
|
let s_ease = context.modulators.getEaser(Setting.EASES.LINEAR, 1, 0, life_span); // scale |
|
let e_ease = context.modulators.getEaser(Setting.EASES.EXP_OUT, 1, 0, life_span); // emissive intensity |
|
|
|
// Create and store the particle |
|
let spark = { |
|
age: 0, |
|
mesh: spark_mesh, |
|
material: spark_mat, |
|
life_span: life_span, |
|
x_ease: x_ease, |
|
y_ease: y_ease, |
|
z_ease: z_ease, |
|
s_ease: s_ease, |
|
e_ease: e_ease |
|
}; |
|
context.memory.sparks.push(spark); |
|
context.memory.spark_count++; |
|
}; |
|
|
|
// Create a function to age all the living particles |
|
context.memory.age = function() { |
|
context.memory.sparks.forEach( spark => { |
|
if (spark.age <= spark.life_span) { |
|
let scale = spark.s_ease(); |
|
if (scale > 0) spark.mesh.scale.set(scale, scale, scale); |
|
spark.mesh.position.set(spark.x_ease(), spark.y_ease(), spark.z_ease()); |
|
spark.material.emissiveIntenstity = spark.e_ease(); |
|
spark.age++; |
|
if (spark.age > spark.life_span) { |
|
context.removeFromScene(spark.mesh); |
|
spark.mesh = null; |
|
} |
|
} |
|
}); |
|
}; |