We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
Page Index Toggle Pages: 1
Shockwave (Read 871 times)
Shockwave
Apr 2nd, 2008, 2:26pm
 
Hey, I'm trying to get a shockwave (really a texture on a vertex shape) to be spawned by bass drum kicks in music, increase in size (all from a central origin) and then fading out, using ESS. The problem is how to spawn them properly (ie. multiple instances).

I've been messing with classes, and I think this might be on the right lines...
Code:

import krister.Ess.*;
import processing.opengl.*;

float radius;
PulseCircle pulse;
PImage pulseCircleImg;

AudioChannel myChannel; // For ESS
FFT fft;
int bands = 512; // Number of FFT frequency bands to calculate
int bufferSize = 1024;
int samplingRate = 44100;

void setup() {
size(400,400,OPENGL);
hint( ENABLE_OPENGL_4X_SMOOTH );
textureMode(NORMALIZED);
pulseCircleImg = loadImage( "glowCircleThin.png" );

Ess.start(this); // Start Ess
// Load audio file into AudioChannel, file is in the "data" folder
myChannel = new AudioChannel( "Learning.wav" );
fft=new FFT(bands);
// normalise spectrum
fft.limits();
// 16 averages
fft.averages(16);
//Apply Envelope
fft.envelope(1);
//Damp FFT data
fft.damp(.1);
myChannel.play(Ess.FOREVER);
}

void draw() {
background(0);
pulse.update();
pulse.display();

fft.getSpectrum(myChannel);

if( fft.averages[2]*1024 > 100 ) {
translate(width/2, height/2);
//radius = fft.averages[2]*1024; // Manipulate 'radius' float, which affects pulseCircle
new.PulseCircle();
//radius += 1;
//println(fft.averages[2]*1024);
}
}


class PulseCircle {
float pulseRadius;

// Constructor
PulseCircle(float pulseRadius) {
pulseRadius = 0;
}

void update() {
pulseRadius += 1;
}

void display() {
pushMatrix();
beginShape();
texture(pulseCircleImg);
vertex(-(pulseRadius), -(pulseRadius), 0, 0, 0);
vertex((pulseRadius), -(pulseRadius), 0, 1, 0);
vertex((pulseRadius), (pulseRadius), 0, 1, 1);
vertex(-(pulseRadius), (pulseRadius), 0, 0, 1);
endShape();
popMatrix();
}
}


Here's the texture i'm using btw:
http://img.photobucket.com/albums/v380/werebunny/glowCircleThin.png

What would be the best way of doing this properly?
Re: Shockwave
Reply #1 - Apr 8th, 2008, 5:26pm
 
OK, so I have the pulse increasing in size when the mouse is clicked, but it resets itself (ie. there's only one instance) when you click again. What I'd like is for a pulse (shockwave) to be spawned every time the mouse is clicked (and for each one to be independent - a new one made every mouse click), increase in size and be killed when it is a certain radius. I've tried doing it with arrays but it doesn't seem to like it.

Is it possible to create multiple instances of a class?

Code:

import processing.opengl.*;

float radius;
PulseCircle pulse;
PImage pulseCircleImg;

void setup() {
size(500,500,OPENGL);
hint( ENABLE_OPENGL_4X_SMOOTH );
textureMode( NORMALIZED );
pulseCircleImg = loadImage( "glowCircleThin.png" );

pulse = new PulseCircle(0,0);
}

void draw() {
background(0);

if( mousePressed ) {
pulse.start(0,0);
}
pulse.update();
pulse.display();
//println(fft.averages[2]);
}


class PulseCircle {
float x, y;
float pulseRadius;
boolean on = false;

// Constructor
PulseCircle(float xpos, float ypos) {
x = xpos;
y = ypos;
println("PulseCircle");
}

void start(float xpos, float ypos) {
x = xpos;
y = ypos;
on = true;
pulseRadius = 0;
println("Start");
}

void update() {
if (on == true) {
pulseRadius += 5;
println("Update : True");
}
if (pulseRadius > 500) {
pulseRadius = 0;
on = false;
println("Update : False");
}
}

void display() {
if (on == true) {
pushMatrix();
beginShape();
texture(pulseCircleImg);
vertex(-(pulseRadius), -(pulseRadius), 0, 0, 0);
vertex((pulseRadius), -(pulseRadius), 0, 1, 0);
vertex((pulseRadius), (pulseRadius), 0, 1, 1);
vertex(-(pulseRadius), (pulseRadius), 0, 0, 1);
endShape();
popMatrix();
println("Display");
}
}
}

Re: Shockwave
Reply #2 - Apr 8th, 2008, 5:59pm
 
You should either create a static array (fixed size) containing your custom objects, or dynamically grow the array when a new one should be created.

check out this post: http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Syntax;action=display;num=1193701437
Re: Shockwave
Reply #3 - Apr 22nd, 2008, 3:49pm
 
Hi again. I have this working in a basic way now...

But there are a couple of problems.

1. When you hold down a key, loads get spawned at the same time (as you'd expect) but this is an undesired effect. Is there some sort of simple 'dampening' I can use - ie. "if a pulse has been spawned within 500ms (or whatever) don't spawn a new one" to avoid this continuous repeating.

2. I'm thinking that expanding the array isn't the most efficient way. These shockwaves will react to the kick drum sound in music, so I can't imagine there would be more than 10 or 20 on screen at once (probably no-where near that number actually). But how could I make an array that is say 25 long but which cycles through the array and gives the same effect? Expanding by 1 will eventually cause an out of memory error won't it?

Code:
 import processing.opengl.*;

float radius;
PulseCircle pulse[] = new PulseCircle[0];
PImage pulseCircleImg;
int PulseCircleCount = 1;

void setup() {
size(400,400,OPENGL);
hint( ENABLE_OPENGL_4X_SMOOTH );
textureMode(NORMALIZED);
pulseCircleImg = loadImage( "glowCircleThin.png" );
}

void draw() {
background(0);

translate(width/2, height/2);

if( keyPressed ) {
pulse = (PulseCircle[]) expand(pulse, pulse.length+1);
pulse[pulse.length-1] = new PulseCircle(0,0);


println(pulse.length);

}

for(int i = 0; i < pulse.length; ++i) {
pulse[i].update();
pulse[i].display();
}
}


class PulseCircle {
float x, y;
float pulseRadius;
boolean on = false;

// Constructor
PulseCircle(float xpos, float ypos) {
x = xpos;
y = ypos;
on = true;
pulseRadius = 0;
println("PulseCircle");
}

void start(float xpos, float ypos) {
x = xpos;
y = ypos;


println("Start");
}

void update() {
if (on == true) {
pulseRadius += 5;
println("Update : True");
}
if (pulseRadius > 200) {
pulseRadius = 0;
on = false;
println("Update : False");
}
}

void display() {
if (on == true) {
pushMatrix();
beginShape();
//fill(255);
texture(pulseCircleImg);
vertex(-(pulseRadius), -(pulseRadius), 0, 0, 0);
vertex((pulseRadius), -(pulseRadius), 0, 1, 0);
vertex((pulseRadius), (pulseRadius), 0, 1, 1);
vertex(-(pulseRadius), (pulseRadius), 0, 0, 1);
endShape();
popMatrix();
//fill(255);
//ellipse(0,0,pulseRadius,pulseRadius);
println("Display");
}
}
}
Re: Shockwave
Reply #4 - Apr 22nd, 2008, 4:45pm
 
One way to solve the issue is to only spawn a pulse if there's a change in the state of the key, so you could use something like:

Code:
boolean isPressed=false; //outside of draw/setup functions

...
if(keyPressed && !isPressed)
{
isPressed=true;
//make a pulse as before
}
else
{
isPresse=false;
}


This way only the first frame in which a key has been pressed will spawn a pulse until there are no keys pressed, when it'll be able to re-activate.
Re: Shockwave
Reply #5 - Apr 27th, 2008, 6:29pm
 
Hi JohnG.

I tried your suggestion but it doesn't seem to have much of an effect (although it does slow the rate... but it is still an endless stream in that particular issue).

I think generally a better way would be to create a pre-defined array size (using Code:
PulseCircle pulse[] = new PulseCircle[25]; 

right at the top of the sketch), but when I try and do this I get errors.

And once I have a pre-defined array how can I step through and initialise a pulse every time a key is pressed?
I've just totally confused myself with this shockwave thing - not tried object oriented programming before.
Re: Shockwave
Reply #6 - May 6th, 2008, 9:40pm
 
Does anybody have an ideas about this?

Just to stop it initialising so much ("if pulse has been activated within 500ms, don't make another one").
Re: Shockwave
Reply #7 - May 7th, 2008, 4:25pm
 
I made this for a project I'm still working on a while ago, its a basic version of what I used in the end.

It creates ripples (not very realistic ones) on a grid plane.

http://www.graphicfilth.com/wavey

for your initialising delay question:

I'd just have a value that you count down every cycle, only allow the creation of a wave when the value equals Zero. When the code runs to create a new shockwave, just set the value to whatever number of frames you want to run before being able to create another.

Martin
Re: Shockwave
Reply #8 - May 8th, 2008, 10:19am
 
AMAZING sketch!

I tried your suggestion and it works - I was thinking about it too much!
Page Index Toggle Pages: 1