Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // =========================================================================
- // VIDEO MIXER IDEA
- // processing doodle by /u/frumperino
- // 2014-01-31
- // =========================================================================
- // Disclaimer:
- // This software is hostile to all forms of life and civilization
- // * It does not do what it says on the tin.
- // * You almost certainly shouldn't use it for your project.
- // * It is released as-is to public domain without any form of warranty.
- // =========================================================================
- int sw = 640;
- int sh = 480;
- Mixer mainMixer;
- float videoHz = 30;
- void setup()
- {
- //sw = displayWidth;
- //sh = displayHeight;
- size(sw,sh,P3D);
- frameRate(videoHz);
- frame.setResizable(true);
- mainMixer = new Mixer();
- mainMixer.setChannel(2,new PT_pattern1());
- mainMixer.setChannel(3,new PT_pattern2());
- mainMixer.setBlender(1,new BL_circleWipe()); // add circle wipe to mixer blender slot 1
- mainMixer.setFader(new SG_osc(0.25)); // replace mixer handle with 0.25 Hz oscillator
- mainMixer.selectChannel(2);
- mainMixer.selectChannel(3);
- mainMixer.selectBlender(1);
- mainMixer.initialize(g);
- }
- boolean sketchFullScreen()
- {
- return false;
- }
- void keyPressed()
- {
- mainMixer.nextBlender();
- }
- void draw()
- {
- mainMixer.iterate();
- mainMixer.draw(g,0);
- }
- // ====================================================
- // INTERFACES
- // ====================================================
- // contract for plug-in Painter classes
- interface Painter
- {
- // must have an initialize function which will be called when a pattern is first invoked or screen resolution changes.
- void initialize(PGraphics gr);
- // must have a draw function which paints to a provided PGraphics object.
- // the phase argument (0..1) is only used when painter is used as alpha mask provider
- // in a crossfade function.
- void draw(PGraphics gr, float phase);
- void iterate(); // animate / recompute the pattern
- }
- // contract for plug-in Signal Provider classes
- // used for things like fader handles (but can be oscillators, glitchers, etc)
- interface SignalProvider
- {
- float get(); // a signal value between 0 and 1 (don't iterate underlying function)
- float iterate(); // animate / recompute the signal function (and return it)
- }
- abstract class Blender implements Painter
- {
- public void initialize(PGraphics gr) {}
- public void iterate() {}
- }
- abstract class Pattern implements Painter
- {
- public void initialize(PGraphics gr) {}
- public void iterate() {}
- }
- // ====================================================
- // MIXER
- // ====================================================
- // the mixer itself is a Painter (allows for nesting!)
- class Mixer implements Painter
- {
- HashMap<Integer,Painter> channels;
- HashMap<Integer,Painter> blenders;
- int sw, sh;
- PGraphics pg1;
- PGraphics pg2;
- PGraphics pgB;
- int selectedBlenderIndex = 0;
- int selectedChannelIndex = 0;
- int previousChannelIndex = 0;
- SignalProvider fader;
- public void initialize(PGraphics gr)
- {
- pg1 = createGraphics(gr.width,gr.height,P3D);
- pg2 = createGraphics(gr.width,gr.height,P3D);
- pgB = createGraphics(gr.width,gr.height,P3D);
- sw = gr.width;
- sh = gr.height;
- Painter cp = selectedChannel();
- if (cp != null) cp.initialize(gr);
- cp = previousChannel();
- if (cp != null) cp.initialize(gr);
- cp = selectedBlender();
- if (cp != null) cp.initialize(gr);
- }
- public Mixer()
- {
- channels = new HashMap<Integer,Painter>();
- blenders = new HashMap<Integer,Painter>();
- setChannel(0, new PT_solid(0xFF000000));
- setChannel(1, new PT_colorBars());
- setBlender(0, new BL_flat());
- selectBlender(0);
- selectChannel(0);
- fadeTo(1,1000);
- }
- public Painter getChannel(int channelIndex)
- {
- if (channels.size() > 0)
- {
- if (channels.containsKey(channelIndex))
- {
- return channels.get(channelIndex);
- }
- }
- return null;
- }
- public Painter getBlender(int blenderIndex)
- {
- if (blenders.size() > 0)
- {
- if (blenders.containsKey(blenderIndex))
- {
- return blenders.get(blenderIndex);
- }
- }
- return null;
- }
- public Painter selectedChannel()
- {
- return getChannel(selectedChannelIndex);
- }
- public Painter previousChannel()
- {
- return getChannel(previousChannelIndex);
- }
- public Painter selectedBlender()
- {
- return getBlender(selectedBlenderIndex);
- }
- public int numChannels()
- {
- return channels.size();
- }
- public int numBlenders()
- {
- return blenders.size();
- }
- public void selectChannel(int channelIndex)
- {
- previousChannelIndex = selectedChannelIndex;
- selectedChannelIndex = channelIndex % channels.size();
- }
- public void selectBlender(int blenderIndex)
- {
- this.selectedBlenderIndex = blenderIndex % blenders.size();
- }
- public void nextBlender()
- {
- this.selectedBlenderIndex++;
- this.selectedBlenderIndex %= blenders.size();
- }
- public void fadeTo(int channelIndex, int transitionMS)
- {
- selectChannel(channelIndex);
- SG_linearFader f = new SG_linearFader(0);
- setFader(f);
- f.fadeTo(1,transitionMS);
- }
- public void snapTo(int channelIndex)
- {
- fadeTo(channelIndex,0);
- }
- public void setChannel(int channelIndex, Painter channel)
- {
- this.channels.put(channelIndex,channel);
- }
- public void setFader(SignalProvider fader)
- {
- this.fader = fader;
- }
- public void setBlender(int blenderIndex, Painter blender)
- {
- this.blenders.put(blenderIndex, blender);
- }
- void draw(PGraphics gr, float phase)
- {
- gr.beginDraw();
- float f = fader.get();
- if (f < 0.9999)
- {
- selectedBlender().draw(pgB,f);
- previousChannel().draw(pg1,0);
- selectedChannel().draw(pg2,0);
- PImage img = pg2.get();
- img.mask(pgB.get());
- gr.image(pg1,0,0);
- gr.image(img,0,0);
- }
- else
- {
- // draw selected channel to main
- selectedChannel().draw(gr,0);
- }
- gr.endDraw();
- }
- public void iterate()
- {
- fader.iterate();
- selectedBlender().iterate();
- selectedChannel().iterate();
- if(fader.get() < 0.9999)
- {
- previousChannel().iterate();
- }
- }
- }
- // ====================================================
- // SIGNAL PROVIDERS
- // Used to control a mixer or anything else
- // ====================================================
- class SG_constant implements SignalProvider
- {
- float value = 0;
- public SG_constant(float value)
- {
- this.value = value < 0 ? 0 : value > 1 ? 1 : value;
- }
- public float iterate()
- {
- return get();
- }
- public float get()
- {
- return this.value;
- }
- }
- class SG_linearFader implements SignalProvider
- {
- float actualPos = 0;
- float deltaPos = 0;
- float defaultPos = 0;
- float startPos = 0;
- int totalSteps = 0;
- int stepCount = 0;
- public SG_linearFader(float initialPos)
- {
- this.actualPos = initialPos;
- this.defaultPos = initialPos;
- }
- public void setHandle(float pos)
- {
- this.actualPos = pos < 0 ? 0 : pos > 1 ? 1 : pos;
- }
- // fade handle to specific position
- // transition time in milliseconds
- public void fadeTo(float targetPos, int transitionMS)
- {
- this.startPos = this.actualPos;
- this.totalSteps = round( transitionMS * videoHz / 1000 );
- this.deltaPos = targetPos - actualPos;
- this.stepCount = 0;
- if (transitionMS == 0)
- {
- this.actualPos = 1;
- }
- }
- public void reset()
- {
- this.actualPos = this.defaultPos;
- }
- public float get()
- {
- return actualPos;
- }
- public float iterate()
- {
- if (stepCount < totalSteps)
- {
- stepCount++;
- actualPos = startPos + deltaPos * ((float) stepCount / totalSteps);
- }
- return actualPos;
- }
- }
- class SG_osc implements SignalProvider
- {
- float value = 0;
- int cycle = 1000;
- int counter = 0;
- float multiplier = 0;
- public SG_osc(float cycleHz)
- {
- value = 0;
- counter = 0;
- cycle = 1000;
- multiplier = 0;
- setFrequency(cycleHz);
- }
- public void setFrequency(float hz)
- {
- if (hz > 0)
- {
- cycle = round ( videoHz / hz );
- multiplier = 2 * PI;
- }
- else
- {
- cycle = 0;
- multiplier = 0;
- }
- }
- public float get()
- {
- return value;
- }
- public float iterate()
- {
- counter++;
- counter %= cycle;
- float phase = (float) counter / (cycle-1);
- value = 0.5 + 0.5 * cos (phase * multiplier);
- return value;
- }
- }
- // ====================================================
- // BLENDER CLASSES
- // These provide greyscale alpha mask images used in pattern transitions
- // ====================================================
- // flat greyscale basic crossfader
- class BL_flat extends Blender
- {
- public void draw(PGraphics gr, float phase)
- {
- gr.beginDraw();
- int y = round (phase * 255);
- gr.background( y < 0 ? 0 : y > 255 ? 255 : y);
- gr.endDraw();
- }
- }
- // circle wipe with sharp edges(from middle of screen outwards)
- class BL_circleWipe extends Blender
- {
- float diag;
- float cx,cy;
- @Override
- public void initialize(PGraphics gr)
- {
- // find screen diagonal
- diag = sqrt(gr.width * gr.width + gr.height * gr.height);
- cx = 0.5 * gr.width;
- cy = 0.5 * gr.height;
- }
- public void draw(PGraphics gr, float phase)
- {
- gr.beginDraw();
- gr.background(0);
- gr.fill(0xFF);
- gr.noStroke();
- gr.ellipseMode(CENTER);
- gr.ellipse(cx,cy,diag*phase,diag*phase);
- gr.endDraw();
- }
- }
- // ====================================================
- // PATTERN CHANNEL CLASSES
- // Actual image generators
- // ====================================================
- // baseline color bars painter class used as test picture (channel 0)
- class PT_colorBars extends Pattern
- {
- int ofs = 0;
- int div = 1000;
- int wrap = 1000;
- @Override
- public void initialize(PGraphics gr)
- {
- ofs = 0;
- wrap = gr.width;
- div = wrap / 8;
- }
- void draw(PGraphics gr, float phase)
- {
- gr.beginDraw();
- for (int x=0;x<wrap;x++)
- {
- int dx = (x+ofs) % wrap;
- int n = dx / div;
- int cb = 255 * ( n & 0x01 );
- int cr = 255 * ( (n >> 1) & 0x01 );
- int cg = 255 * ( (n >> 2) & 0x01 );
- int c = 0xFF000000 | cb | (cg << 8) | (cr << 16);
- gr.stroke(c);
- gr.line(x,0,x,gr.height);
- }
- gr.endDraw();
- }
- @Override
- public void iterate()
- {
- ofs++;
- ofs %= wrap;
- }
- }
- // solid pattern used as default channel 1 (black)
- class PT_solid extends Pattern
- {
- color c;
- public PT_solid(color col)
- {
- this.c = col;
- }
- void draw(PGraphics gr, float phase)
- {
- gr.beginDraw();
- gr.background(c);
- gr.endDraw();
- }
- }
- // user patterns
- // --------------------------------------------------
- class PT_pattern1 implements Painter
- {
- public void initialize(PGraphics gr)
- {
- }
- public void draw(PGraphics gr, float phase)
- {
- gr.beginDraw();
- gr.background(0xFFCC0000);
- gr.fill(0x88FF9900);
- for (int i=0;i<50;i++)
- {
- gr.rect(random(gr.width), random(gr.height), random(100), random(100));
- }
- gr.endDraw();
- }
- public void iterate() {}
- }
- class PT_pattern2 implements Painter
- {
- /**
- * Bouncy Bubbles
- * based on code from Keith Peters.
- *
- * Multiple-object collision.
- */
- int numBalls = 12;
- float spring = 0.05;
- float gravity = 0.03;
- float friction = -0.9;
- Ball[] balls = new Ball[numBalls];
- class Ball
- {
- float x, y;
- float diameter;
- float vx = 0;
- float vy = 0;
- int id;
- Ball[] others;
- Ball(float xin, float yin, float din, int idin, Ball[] oin)
- {
- x = xin;
- y = yin;
- diameter = din;
- id = idin;
- others = oin;
- }
- void collide()
- {
- for (int i = id + 1; i < numBalls; i++) {
- float dx = others[i].x - x;
- float dy = others[i].y - y;
- float distance = sqrt(dx*dx + dy*dy);
- float minDist = others[i].diameter/2 + diameter/2;
- if (distance < minDist) {
- float angle = atan2(dy, dx);
- float targetX = x + cos(angle) * minDist;
- float targetY = y + sin(angle) * minDist;
- float ax = (targetX - others[i].x) * spring;
- float ay = (targetY - others[i].y) * spring;
- vx -= ax;
- vy -= ay;
- others[i].vx += ax;
- others[i].vy += ay;
- }
- }
- }
- void move()
- {
- vy += gravity;
- x += vx;
- y += vy;
- if (x + diameter/2 > width) {
- x = width - diameter/2;
- vx *= friction;
- }
- else if (x - diameter/2 < 0) {
- x = diameter/2;
- vx *= friction;
- }
- if (y + diameter/2 > height) {
- y = height - diameter/2;
- vy *= friction;
- }
- else if (y - diameter/2 < 0) {
- y = diameter/2;
- vy *= friction;
- }
- }
- void display(PGraphics gr)
- {
- gr.ellipse(x, y, diameter, diameter);
- }
- }
- void initialize(PGraphics gr)
- {
- for (int i = 0; i < numBalls; i++)
- {
- balls[i] = new Ball(random(gr.width), random(gr.height), random(30, 70), i, balls);
- }
- }
- void draw(PGraphics gr, float phase)
- {
- gr.beginDraw();
- gr.background(0xFF000099);
- gr.noStroke();
- gr.fill(0x9999CCFF);
- for (int i = 0; i < numBalls; i++)
- {
- balls[i].collide();
- balls[i].move();
- balls[i].display(gr);
- }
- gr.endDraw();
- }
- void iterate() {}
- }
- /*
- // template - fill in the blanks
- class PT_patternX implements Painter
- {
- public void initialize(PGraphics g)
- {
- }
- public void draw(PGraphics g, float phase)
- {
- }
- public void iterate()
- {
- }
- }
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement