 |
This code was written
with the _ALPHA_ version of Processing
and it may not run correctly with the current vesion.
// The Internet Age
// or The Rights of Spring
// Reed Kram
// Created October 2002
// Revised November 2002
class particle {
float x, y, z;
float Vx, Vy, Vz;
float Ax, Ay, Az;
float mass, drag;
particle(float theMass, float theDrag, float startX,
float startY, float startZ) {
x = startX;
y = startY;
z = startZ;
Vx = 0.0f;
Vy = 0.0f;
Vz = 0.0f;
Ax = 0.0f;
Ay = 0.0f;
Az = 0.0f;
mass = theMass;
drag = theDrag;
}
// iterate for a single force acting on the particle
void iterate(float Fkx, float Fky, float Fkz) {
float Fx, Fy, Fz;
Fx = Fkx;
Fy = Fky;
Fz = Fkz;
Ax=Fx/mass;
Ay=Fy/mass;
Az=Fz/mass;
Vx += Ax;
Vy += Ay;
Vz += Az;
Vx *= (1.0f-drag);
Vy *= (1.0f-drag);
Vz *= (1.0f-drag);
x += Vx;
y += Vy;
z += Vz;
}
}
class imageDownloader implements Runnable {
Vector imagesToDownload;
Vector inbox;
Thread runner;
BApplet parent;
public imageDownloader(BApplet parent) {
this.parent = parent;
imagesToDownload = new Vector();
inbox = new Vector();
runner = new Thread(this);
}
public void downloadFile(String filename) {
imagesToDownload.addElement(filename);
if (!runner.isAlive()) {
runner.start();
}
}
public Vector fetchDownloadedImages() {
Vector theInbox = (Vector) inbox.clone();
if (inbox != null) {
inbox.removeAllElements();
}
if (imagesToDownload.size() < 1 && runner.isAlive()) {
runner.stop(); // done downloading files...
}
return theInbox;
}
public void run() {
Toolkit tk = Toolkit.getDefaultToolkit();
Image imageToDownload = null;
while(true) {
try {
if ((imageToDownload != null) && ((tk.checkImage(imageToDownload, -1, -1, null) & ImageObserver.ALLBITS) != 0)) { // the image has downloaded fully
int imageWidth = imageToDownload.getWidth(null);
for (int i=0; i<imageToDownload.getHeight(null) / imageWidth; i++) {
Image newImage = parent.createImage(imageWidth, imageWidth);
if (newImage == null) {
System.out.println("unable to allocate offscreen graphics. need more memory.");
break;
}
Graphics newImageGraphics = newImage.getGraphics();
newImageGraphics.drawImage(imageToDownload, 0, 0, 16, 16, 0, i*imageWidth, 16, (i+1)*imageWidth -1, null);
inbox.addElement(newImage);
}
imageToDownload = null;
}
Thread.sleep(200);
if (imageToDownload == null && imagesToDownload.size() > 0) {
String imageFilename = (String) imagesToDownload.elementAt(0);
imageToDownload = tk.getImage(getClass().getResource(imageFilename));
tk.prepareImage(imageToDownload, -1, -1, null);
imagesToDownload.removeElementAt(0);
}
} catch (Exception e) {
System.out.println("downloading image >>>>"+e.toString()); e.printStackTrace(System.out);
}
}
}
}
String logo[] = {"**",
"**",
"**",
"** ** ** ** **** ****** ***",
"** ** ***** ** ** ** **",
"**** ** ***** ** ** **",
"** ** ** ** ** ** ** **",
"** ** ** ***** ** ** **"};
static int MAX_NUM_IMAGES = 300;
static int NUM_IMAGE_FILES = 16;
imageDownloader theDownloader;
Vector frameImages = new Vector();
static int frameImageWidth = 16;
static int frameImageHeight = 16;
particle pixelParticles[][] = new particle[frameImageWidth][frameImageHeight];
int framePixels[] = new int[frameImageWidth * frameImageHeight];
Image frameOffImage;
Graphics frameOffGraphics;
PixelGrabber framePixelGrabber;
int numImagesLoaded = 0;
int thisImageIndex = 0;
long lastFrameTime = 0;
particle cameraRotation = new particle(3, 0.7f, PI, 1.0f, 1.0f);
float cameraRotationDestination[] = { 0.0f, 0.0f, 0.0f };
long creditTextTimer;
void setup()
{
size(300, 300);
background(49, 81, 74);
noStroke();
colorMode(RGB, 100);
for (int i=0; i<frameImageWidth; i++) {
for (int j=0; j<frameImageHeight; j++) {
pixelParticles[i][j] = new particle(4.0f, 0.8f, 0.0f, 0.0f, 0.0f);
}
}
creditTextTimer = millis();
}
void mousePressed() {
cameraRotationDestination[0] = (mouseX - width/2) / 2.0f * (PI/180.0f);
cameraRotationDestination[1] = (mouseY - height/2) / 2.0f * (PI/180.0f);
cameraRotationDestination[2] = 100;
}
void mouseDragged() {
cameraRotationDestination[0] = (mouseX - width/2) / 2.0f * (PI/180.0f);
cameraRotationDestination[1] = (mouseY - height/2) / 2.0f * (PI/180.0f);
cameraRotationDestination[2] = 100;
}
void mouseReleased() {
cameraRotationDestination[0] = 0;
cameraRotationDestination[1] = 0;
cameraRotationDestination[2] = 0;
}
void drawBoxTop(float x1, float x2,
float y1, float y2,
float z1, float z2) {
beginShape(QUADS);
vertex(x1, y2, z2); // draw front
vertex(x1, y1, z2);
vertex(x2, y1, z2);
vertex(x2, y2, z2);
vertex(x2, y2, z2); // draw right side
vertex(x2, y1, z2);
vertex(x2, y1, z1);
vertex(x2, y2, z1);
vertex(x2, y2, z1); // draw back
vertex(x2, y1, z1);
vertex(x1, y1, z1);
vertex(x1, y2, z1);
vertex(x1, y2, z1); // draw left side
vertex(x1, y1, z1);
vertex(x1, y1, z2);
vertex(x1, y2, z2);
endShape();
}
static Color
getPixelColor(int pixels[], int X, int Y, int w) {
int pixel = pixels[Y*w + X];
int alpha = (pixel >> 24) & 0xff;
int red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = (pixel ) & 0xff;
return new Color(red, green, blue);
}
void drawLogo(int x, int y) {
int c = color(100, 100, 100);
for (int i=0; i<logo.length; i++) {
String thisLine = logo[i];
for (int j=max(0, -x); j<thisLine.length(); j++) {
if (thisLine.charAt(j) != ' ') {
setPixel(x + j, y + i, c);
}
}
}
}
void loop()
{
if (frameOffImage == null || frameOffGraphics == null) {
theDownloader = new imageDownloader(this);
for (int i=0; i<NUM_IMAGE_FILES; i++) {
theDownloader.downloadFile("media/images"+i+".jpg");
}
frameOffImage = createImage(frameImageWidth, frameImageHeight);
frameOffGraphics = frameOffImage.getGraphics();
creditTextTimer = millis();
}
cameraRotation.iterate(cameraRotationDestination[0] - cameraRotation.x,
cameraRotationDestination[1] - cameraRotation.y,
cameraRotationDestination[2] - cameraRotation.z);
long curTime = millis();
Vector downloadedImages = theDownloader.fetchDownloadedImages();
if (downloadedImages != null) {
for (int i=0; i<downloadedImages.size(); i++) {
frameImages.addElement(downloadedImages.elementAt(i));
}
}
if (curTime - lastFrameTime > 450) {
if ((thisImageIndex < MAX_NUM_IMAGES-1) && (frameImages.size() > thisImageIndex+1) && ((checkImage((Image) frameImages.elementAt(thisImageIndex+1), null) & ImageObserver.ALLBITS) != 0)) {
thisImageIndex++;
} else {
thisImageIndex = 0;
}
lastFrameTime = curTime;
}
if (frameImages.size() < 1 || !((checkImage((Image) frameImages.elementAt(thisImageIndex), null) & ImageObserver.ALLBITS) != 0)) {
return;
}
frameOffGraphics.drawImage((Image) frameImages.elementAt(thisImageIndex), 0, 0, null);
framePixelGrabber = new PixelGrabber(frameOffImage, 0, 0, frameImageWidth, frameImageHeight, framePixels, 0, frameImageWidth);
try {
framePixelGrabber.grabPixels();
} catch (InterruptedException e) {
System.err.println("interrupted waiting for pixels!");
return;
} catch (Exception e) { System.out.println("grabbing pixels>>>>" + e.toString()); e.printStackTrace(System.out); }
if ((framePixelGrabber.getStatus() & ImageObserver.ABORT) != 0) {
System.err.println("image fetch aborted or errored");
return;
}
for (int X = 0; X < frameImageWidth-1; X++) {
for (int Y = 0; Y < frameImageHeight-1; Y++) {
Color pixelColor = getPixelColor(framePixels, X, Y, frameImageWidth);
pixelParticles[X][Y].iterate(
pixelColor.getRed()*100/255 - pixelParticles[X][Y].x,
pixelColor.getGreen()*100/255 - pixelParticles[X][Y].y,
pixelColor.getBlue()*100/255 - pixelParticles[X][Y].z);
}
}
push();
translate(width/2, height/2, 0);
rotateY( cameraRotation.x);
rotateX(-cameraRotation.y);
float xOffset = frameImageWidth/2.0f -1;
float yOffset = frameImageHeight/2.0f -1;
float scale = 4.0f;
for (int X = 0; X < frameImageWidth-1; X++) {
for (int Y = 0; Y < frameImageHeight-1; Y++) {
float x = 3*(X - xOffset);
float y = 3*(Y - yOffset);
int pixelColor = color(pixelParticles[X][Y].x, pixelParticles[X][Y].y, pixelParticles[X][Y].z);
float z = red(pixelColor)/6.0f;
push();
translate(scale*x, scale*y);
fill(red(pixelColor), green(pixelColor), blue(pixelColor));
drawBoxTop(-scale, scale,
-scale, scale,
-scale*z, scale*z);
pop();
}
}
pop();
if (curTime - creditTextTimer <= 15000) {
drawLogo(5, height-5 -8);
} else if (curTime - creditTextTimer < 18000) {
drawLogo((int)(5 - 60 * (curTime - creditTextTimer - 15000)/700.0), height-5 -8);
}
}
|
|