30 jun. 2009

CubesWithinACube [ejemplo de Processing]

Jugueteando y mezclando entre si algunos de los ejemplos de Processing, salió esto.

cubeswithincube.pde

import processing.opengl.*;

// Flock array
int birdCount = 20;
Bird[]birds = new Bird[birdCount];
float[]birdsx = new float[birdCount];
float[]birdsy = new float[birdCount];
float[]birdsz = new float[birdCount];
float[]birdsrx = new float[birdCount];
float[]birdsry = new float[birdCount];
float[]birdsrz = new float[birdCount];
float[]birdsspd = new float[birdCount];
float[]birdsrot = new float[birdCount];

Cube stage; // external large cube
int cubies = 50;
Cube[]c = new Cube[cubies]; // internal little cubes
color[][]quadBG = new color[cubies][6];

// Controls cubie's movement
float[]x = new float[cubies];
float[]y = new float[cubies];
float[]z = new float[cubies];
float[]xSpeed = new float[cubies];
float[]ySpeed = new float[cubies];
float[]zSpeed = new float[cubies];

// Controls cubie's rotation
float[]xRot = new float[cubies];
float[]yRot = new float[cubies];
float[]zRot = new float[cubies];

// Size of external cube
float bounds = 300;

void setup() {
size(400, 300, OPENGL);
colorMode(RGB, 1);
texmap = loadImage("world32k.jpg");
initializeSphere(sDetail);

for (int i = 0; i < cubies; i++){
// Each cube face has a random color component
float colorShift = random(0, 1);
quadBG[i][0] = color(0, 0, 0);
quadBG[i][1] = color(random(0, .1), random(0, .1), random(0, .1));
quadBG[i][2] = color(random(0, .2), random(0, .2), random(0, .2));
quadBG[i][3] = color(random(0, .3), random(0, .3), random(0, .3));
quadBG[i][4] = color(random(0, .4), random(0, .4), random(0, .4));
quadBG[i][5] = color(random(0, .5), random(0, .5), random(0, .5));

// Cubies are randomly sized
float cubieSizex = random(10, 250);
float cubieSizey = random(10, 250);
float cubieSizez = random(10, 250);
c[i] = new Cube(cubieSizex, cubieSizey, cubieSizez);

// Initialize cubie's position, speed and rotation
x[i] = random(-10, 10);
y[i] = random(-10, 10);
z[i] = random(-10, 10);

xSpeed[i] = random(-.25, .25);
ySpeed[i] = random(-.25, .25);
zSpeed[i] = random(-.25, .25);

xRot[i] = random(1000, 100000);
yRot[i] = random(1000, 100000);
zRot[i] = random(1000, 100000);
}


for (int i = 0; i < birdCount; i++){
birds[i] = new Bird(random(-300, 300), random(-300, 300), random(-500, -2500), random(5, 30), random(5, 30));

birdsx[i] = random(20, 340);
birdsy[i] = random(30, 350);
birdsz[i] = random(1000, 4800);
birdsrx[i] = random(-160, 160);
birdsry[i] = random(-55, 55);
birdsrz[i] = random(-20, 20);
birdsspd[i] = random(.1, 3.75);
birdsrot[i] = random(.025, .15);
}

// Instantiate external large cube
stage = new Cube(bounds, bounds, bounds);
}

void draw(){
background(random(0, .025));
lights();
renderGlobe();

for (int i = 0; i < birdCount; i++){
birds[i].setFlight(birdsx[i], birdsy[i], birdsz[i], birdsrx[i], birdsry[i], birdsrz[i]);
birds[i].setWingSpeed(birdsspd[i]);
birds[i].setRotSpeed(birdsrot[i]);
birds[i].fly();
}

// Center in display window
translate(width/2, height/2, -130);

// Outer transparent cube
noFill();

// Rotate everything, including external large cube
rotateX(frameCount * 0.001);
rotateY(frameCount * 0.002);
rotateZ(frameCount * 0.001);
stroke(255);

// Move and rotate cubies
for (int i = 0; i < cubies; i++){
pushMatrix();
translate(x[i], y[i], z[i]);
rotateX(frameCount*PI/xRot[i]);
rotateY(frameCount*PI/yRot[i]);
rotateX(frameCount*PI/zRot[i]);
noStroke();
c[i].create(quadBG[i]);
x[i] += xSpeed[i];
y[i] += ySpeed[i];
z[i] += zSpeed[i];
popMatrix();

// Draw lines connecting cubbies
stroke(0);
if (i < cubies-1){
line(x[i], y[i], z[i], x[i+1], y[i+1], z[i+1]);
}

}
}

// ----------------------------------------------------------------------------------------------

PImage bg;
PImage texmap;

int sDetail = 35; // Sphere detail setting
float rotationX = 0;
float rotationY = 0;
float velocityX = 0;
float velocityY = 0;
float globeRadius = 450;
float pushBack = 0;

float[] cx, cz, sphereX, sphereY, sphereZ;
float sinLUT[];
float cosLUT[];
float SINCOS_PRECISION = 0.5;
int SINCOS_LENGTH = int(360.0 / SINCOS_PRECISION);

void renderGlobe() {
pushMatrix();
translate(width/2,height/2,-130);
pushMatrix();
noFill();
stroke(255,200);
strokeWeight(2);
smooth();
popMatrix();
lights();
pushMatrix();
rotateX( radians(-rotationX) );
rotateY( radians(270 - rotationY) );
fill(200);
noStroke();
textureMode(IMAGE);
texturedSphere(globeRadius, texmap);
popMatrix();
popMatrix();
rotationX += velocityX;
rotationY += velocityY;
velocityX *= 0.95;
velocityY *= 0.95;

// Implements mouse control (interaction will be inverse when sphere is upside down)
if(mousePressed){
velocityX += (mouseY-pmouseY) * 0.01;
velocityY -= (mouseX-pmouseX) * 0.01;
}
}

void initializeSphere(int res)
{
sinLUT = new float[SINCOS_LENGTH];
cosLUT = new float[SINCOS_LENGTH];

for (int i = 0; i < SINCOS_LENGTH; i++) {
sinLUT[i] = (float) Math.sin(i * DEG_TO_RAD * SINCOS_PRECISION);
cosLUT[i] = (float) Math.cos(i * DEG_TO_RAD * SINCOS_PRECISION);
}

float delta = (float)SINCOS_LENGTH/res;
float[] cx = new float[res];
float[] cz = new float[res];

// Calc unit circle in XZ plane
for (int i = 0; i < res; i++) {
cx[i] = -cosLUT[(int) (i*delta) % SINCOS_LENGTH];
cz[i] = sinLUT[(int) (i*delta) % SINCOS_LENGTH];
}

// Computing vertexlist vertexlist starts at south pole
int vertCount = res * (res-1) + 2;
int currVert = 0;

// Re-init arrays to store vertices
sphereX = new float[vertCount];
sphereY = new float[vertCount];
sphereZ = new float[vertCount];
float angle_step = (SINCOS_LENGTH*0.5f)/res;
float angle = angle_step;

// Step along Y axis
for (int i = 1; i < res; i++) {
float curradius = sinLUT[(int) angle % SINCOS_LENGTH];
float currY = -cosLUT[(int) angle % SINCOS_LENGTH];
for (int j = 0; j < res; j++) {
sphereX[currVert] = cx[j] * curradius;
sphereY[currVert] = currY;
sphereZ[currVert++] = cz[j] * curradius;
}
angle += angle_step;
}
sDetail = res;
}

// Generic routine to draw textured sphere
void texturedSphere(float r, PImage t)
{
int v1,v11,v2;
r = (r + 100) * 0.2;
beginShape(TRIANGLE_STRIP);
texture(t);
float iu=(float)(t.width-1)/(sDetail);
float iv=(float)(t.height-1)/(sDetail);
float u=0,v=iv;
for (int i = 0; i < sDetail; i++) {
vertex(0, -r, 0,u,0);
vertex(sphereX[i]*r, sphereY[i]*r, sphereZ[i]*r, u, v);
u+=iu;
}
vertex(0, -r, 0,u,0);
vertex(sphereX[0]*r, sphereY[0]*r, sphereZ[0]*r, u, v);
endShape();

// Middle rings
int voff = 0;
for(int i = 2; i < sDetail; i++) {
v1=v11=voff;
voff += sDetail;
v2=voff;
u=0;
beginShape(TRIANGLE_STRIP);
texture(t);
for (int j = 0; j < sDetail; j++) {
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1++]*r, u, v);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2++]*r, u, v+iv);
u+=iu;
}

// Close each ring
v1=v11;
v2=voff;
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1]*r, u, v);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v+iv);
endShape();
v+=iv;
}
u=0;

// Add the northern cap
beginShape(TRIANGLE_STRIP);
texture(t);
for (int i = 0; i < sDetail; i++) {
v2 = voff + i;
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v);
vertex(0, r, 0,u,v+iv);
u+=iu;
}
vertex(sphereX[voff]*r, sphereY[voff]*r, sphereZ[voff]*r, u, v);
endShape();

}


bird.pde

class Bird {

// Properties
float offsetX, offsetY, offsetZ;
float w, h;
int bodyFill;
int wingFill;
float ang = 0, ang2 = 0, ang3 = 0, ang4 = 0;
float radiusX = 120, radiusY = 200, radiusZ = 700;
float rotX = 15, rotY = 10, rotZ = 5;
float flapSpeed = 0.4;
float rotSpeed = 0.1;

// Constructors
Bird(){
this(0, 0, 0, 60, 80);
}

Bird(float offsetX, float offsetY, float offsetZ, float w, float h){
this.offsetX = offsetX;
this.offsetY = offsetY;
this.offsetZ = offsetZ;
this.h = h;
this.w = w;
bodyFill = color(random(0, .5), random(0, .5), random(0, .5));
wingFill = color(random(0, .1), random(0, .1), random(0, .1));
}

void setFlight(float radiusX, float radiusY, float radiusZ,
float rotX, float rotY, float rotZ){
this.radiusX = radiusX;
this.radiusY = radiusY;
this.radiusZ = radiusZ;

this.rotX = rotX;
this.rotY = rotY;
this.rotZ = rotZ;
}

void setWingSpeed(float flapSpeed){
this.flapSpeed = flapSpeed;
}

void setRotSpeed(float rotSpeed){
this.rotSpeed = rotSpeed;
}

void fly() {
pushMatrix();
float px, py, pz;

// Flight
px = sin(radians(ang3)) * radiusX;
py = cos(radians(ang3)) * radiusY;
pz = sin(radians(ang4)) * radiusZ;

translate(width/2 + offsetX + px, height/2 + offsetY+py, -700 + offsetZ+pz);

rotateX(sin(radians(ang2)) * rotX);
rotateY(sin(radians(ang2)) * rotY);
rotateZ(sin(radians(ang2)) * rotZ);

// Body
fill(bodyFill);
box(w/5, h, w/5);

// Left wing
fill(wingFill);
pushMatrix();
rotateY(sin(radians(ang)) * 20);
rect(0, -h/2, w, h);
popMatrix();

// Right wing
pushMatrix();
rotateY(sin(radians(ang)) * -20);
rect(-w, -h/2, w, h);
popMatrix();

// Wing flap
ang += flapSpeed;
if (ang > 3) {
flapSpeed*=-1;
}
if (ang < -3) {
flapSpeed*=-1;
}

// Ang's run trig functions
ang2 += rotSpeed;
ang3 += 1.25;
ang4 += 0.55;
popMatrix();
}
}



cube.pde

// Custom Cube Class

class Cube{
PVector[] vertices = new PVector[24];
float w, h, d;

// Default constructor
Cube(){ }

// Constructor 2
Cube(float w, float h, float d) {
this.w = w;
this.h = h;
this.d = d;

// cube composed of 6 quads
//front
vertices[0] = new PVector(-w/2,-h/2,d/2);
vertices[1] = new PVector(w/2,-h/2,d/2);
vertices[2] = new PVector(w/2,h/2,d/2);
vertices[3] = new PVector(-w/2,h/2,d/2);
//left
vertices[4] = new PVector(-w/2,-h/2,d/2);
vertices[5] = new PVector(-w/2,-h/2,-d/2);
vertices[6] = new PVector(-w/2,h/2,-d/2);
vertices[7] = new PVector(-w/2,h/2,d/2);
//right
vertices[8] = new PVector(w/2,-h/2,d/2);
vertices[9] = new PVector(w/2,-h/2,-d/2);
vertices[10] = new PVector(w/2,h/2,-d/2);
vertices[11] = new PVector(w/2,h/2,d/2);
//back
vertices[12] = new PVector(-w/2,-h/2,-d/2);
vertices[13] = new PVector(w/2,-h/2,-d/2);
vertices[14] = new PVector(w/2,h/2,-d/2);
vertices[15] = new PVector(-w/2,h/2,-d/2);
//top
vertices[16] = new PVector(-w/2,-h/2,d/2);
vertices[17] = new PVector(-w/2,-h/2,-d/2);
vertices[18] = new PVector(w/2,-h/2,-d/2);
vertices[19] = new PVector(w/2,-h/2,d/2);
//bottom
vertices[20] = new PVector(-w/2,h/2,d/2);
vertices[21] = new PVector(-w/2,h/2,-d/2);
vertices[22] = new PVector(w/2,h/2,-d/2);
vertices[23] = new PVector(w/2,h/2,d/2);
}
void create(){
// Draw cube
for (int i=0; i<6; i++){
beginShape(QUADS);
for (int j=0; j<4; j++){
vertex(vertices[j+4*i].x, vertices[j+4*i].y, vertices[j+4*i].z);
}
endShape();
}
}
void create(color[]quadBG){
// Draw cube
for (int i=0; i<6; i++){
fill(quadBG[i]);
beginShape(QUADS);
for (int j=0; j<4; j++){
vertex(vertices[j+4*i].x, vertices[j+4*i].y, vertices[j+4*i].z);
}
endShape();
}
}
}


No hay comentarios:

Publicar un comentario