Skip to content
Snippets Groups Projects
Commit 5e7b6a39 authored by Micah Elizabeth Scott's avatar Micah Elizabeth Scott
Browse files

Particle trail example for Node.js

Shows easy and high quality particle animation with JavaScript
parent 8e4374fd
No related branches found
No related tags found
No related merge requests found
/*
* Simple Open Pixel Control client for Node.js
*
* 2013 Micah Elizabeth Scott
* 2013-2014 Micah Elizabeth Scott
* This file is released into the public domain.
*/
var net = require('net');
var fs = require('fs');
var OPC = function(host, port)
{
......@@ -14,6 +15,12 @@ var OPC = function(host, port)
this.pixelBuffer = null;
};
OPC.prototype.loadModel = function(filename)
{
// Synchronously load a JSON model from a file on disk
return JSON.parse(fs.readFileSync(filename))
}
OPC.prototype._reconnect = function()
{
var _this = this;
......@@ -70,4 +77,67 @@ OPC.prototype.setPixel = function(num, r, g, b)
this.pixelBuffer.writeUInt8(Math.max(0, Math.min(255, b | 0)), offset + 2);
}
OPC.prototype.mapPixels = function(fn, model)
{
// Set all pixels, by mapping each element of "model" through "fn" and setting the
// corresponding pixel value. The function returns a tuple of three 8-bit RGB values.
// Implies 'writePixels' as well. Has no effect if the OPC client is disconnected.
if (!this.socket) {
this._reconnect();
}
if (!this.connected) {
return;
}
this.setPixelCount(model.length);
var offset = 4;
for (var i = 0; i < model.length; i++) {
var rgb = fn(model[i]);
this.pixelBuffer.writeUInt8(Math.max(0, Math.min(255, rgb[0] | 0)), offset);
this.pixelBuffer.writeUInt8(Math.max(0, Math.min(255, rgb[1] | 0)), offset + 1);
this.pixelBuffer.writeUInt8(Math.max(0, Math.min(255, rgb[2] | 0)), offset + 2);
offset += 3;
}
this.writePixels();
}
OPC.prototype.mapParticles = function(particles, model)
{
// Set all pixels, by mapping a particle system to each element of "model".
// The particles include parameters 'point', 'intensity', 'falloff', and 'color'.
function shader(p) {
var r = 0;
var g = 0;
var b = 0;
for (var i = 0; i < particles.length; i++) {
var particle = particles[i];
// Particle to sample distance
var dx = (p.point[0] - particle.point[0]) || 0;
var dy = (p.point[1] - particle.point[1]) || 0;
var dz = (p.point[2] - particle.point[2]) || 0;
var dist2 = dx * dx + dy * dy + dz * dz;
// Particle edge falloff
var intensity = particle.intensity / (1 + particle.falloff * dist2);
// Intensity scaling
r += particle.color[0] * intensity;
g += particle.color[1] * intensity;
b += particle.color[2] * intensity;
}
return [r, g, b];
}
this.mapPixels(shader, model);
}
module.exports = OPC;
#!/usr/bin/env node
// Simple particle system example with Node and opc.js
// Specify a layout file on the command line, or use the default (grid32x16z)
var OPC = new require('./opc');
var client = new OPC('localhost', 7890);
var model = client.loadModel(process.argv[2] || '../layouts/grid32x16z.json');
function draw() {
var t = 0.009 * new Date().getTime();
var numParticles = 200;
var particles = [];
for (var i = 0; i < numParticles; i++) {
var r = 0.2 + 1.5 * i / numParticles;
var x = r * Math.cos(t);
var y = r * Math.sin(t + 10.0 * Math.sin(t * 0.15));
particles[i] = {
point: [0, x, y],
intensity: 40 * i / numParticles,
falloff: 60,
color: [0.9, 0.2, i * 0.01]
};
t += 0.04;
}
client.mapParticles(particles, model);
}
setInterval(draw, 10);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment