mirror of
https://github.com/processing/processing4.git
synced 2026-02-03 21:59:20 +01:00
Removed old opengl android examples
This commit is contained in:
@@ -1,116 +0,0 @@
|
||||
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(153);
|
||||
wingFill = color(204);
|
||||
}
|
||||
|
||||
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);
|
||||
pushMatrix();
|
||||
scale(w/5, h, w/5);
|
||||
if (usingPShape) {
|
||||
shape(body);
|
||||
} else {
|
||||
box(1, 1, 1);
|
||||
}
|
||||
popMatrix();
|
||||
|
||||
// Left wing
|
||||
fill(wingFill);
|
||||
pushMatrix();
|
||||
rotateY(sin(radians(ang)) * 20);
|
||||
translate(0, -h/2);
|
||||
scale(w, h);
|
||||
if (usingPShape) {
|
||||
shape(wing);
|
||||
} else {
|
||||
rect(0, 0, 1, 1);
|
||||
}
|
||||
popMatrix();
|
||||
|
||||
// Right wing
|
||||
pushMatrix();
|
||||
rotateY(sin(radians(ang)) * -20);
|
||||
|
||||
translate(-w, -h/2);
|
||||
scale(w, h);
|
||||
if (usingPShape) {
|
||||
shape(wing);
|
||||
} else {
|
||||
rect(0, 0, 1, 1);
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
// Crazy Flocking 3D Birds, by Ira Greenberg.
|
||||
// Android port by Andres Colubri
|
||||
// Simulates a flock of birds using a Bird class and nested
|
||||
// pushMatrix() / popMatrix() functions.
|
||||
// Trigonometry functions handle the flapping and sinuous movement.
|
||||
//
|
||||
// This example shows the shape recording functionality in A3D,
|
||||
// where an entire geometry drawn with the regular API can be
|
||||
// stored in a PShape3D object for later use. This greatly
|
||||
// improves the performance of the application.
|
||||
// Tap on the screen to enable/disable drawing with the recorded
|
||||
// shape.
|
||||
|
||||
// Flock array
|
||||
int birdCount = 200;
|
||||
Bird[]birds = new Bird[birdCount];
|
||||
float[]x = new float[birdCount];
|
||||
float[]y = new float[birdCount];
|
||||
float[]z = new float[birdCount];
|
||||
float[]rx = new float[birdCount];
|
||||
float[]ry = new float[birdCount];
|
||||
float[]rz = new float[birdCount];
|
||||
float[]spd = new float[birdCount];
|
||||
float[]rot = new float[birdCount];
|
||||
PShape body;
|
||||
PShape wing;
|
||||
|
||||
boolean usingPShape = false;
|
||||
|
||||
void setup() {
|
||||
size(screenWidth, screenHeight, P3D);
|
||||
orientation(PORTRAIT);
|
||||
|
||||
PFont font = createFont(PFont.list()[0], 24);
|
||||
textFont(font, 24);
|
||||
|
||||
noStroke();
|
||||
|
||||
// Initialize arrays with random values
|
||||
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));
|
||||
|
||||
x[i] = random(20, 340);
|
||||
y[i] = random(30, 350);
|
||||
z[i] = random(1000, 4800);
|
||||
rx[i] = random(-160, 160);
|
||||
ry[i] = random(-55, 55);
|
||||
rz[i] = random(-20, 20);
|
||||
spd[i] = random(.1, 3.75);
|
||||
rot[i] = random(.025, .15);
|
||||
}
|
||||
|
||||
// Saving box and rectangle used to draw birds
|
||||
// into PShape3D objects.
|
||||
body = beginRecord();
|
||||
box(1, 1, 1);
|
||||
endRecord();
|
||||
|
||||
wing = beginRecord();
|
||||
rect(0, 0, 1, 1);
|
||||
endRecord();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
lights();
|
||||
|
||||
for (int i = 0; i < birdCount; i++){
|
||||
birds[i].setFlight(x[i], y[i], z[i], rx[i], ry[i], rz[i]);
|
||||
birds[i].setWingSpeed(spd[i]);
|
||||
birds[i].setRotSpeed(rot[i]);
|
||||
birds[i].fly();
|
||||
}
|
||||
|
||||
fill(255);
|
||||
if (usingPShape) {
|
||||
text("With PShape3D. FPS: " + frameRate, 10, height - 30);
|
||||
} else {
|
||||
text("Without PShape3D. FPS: " + frameRate, 10, height - 30);
|
||||
}
|
||||
}
|
||||
|
||||
void mousePressed() {
|
||||
usingPShape = !usingPShape;
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
// Blending, by Andres Colubri
|
||||
// Images can be blended using one of the 10 blending modes
|
||||
// available in A3D (some of them might not work on specific hardware).
|
||||
// Images by Kevin Bjorke.
|
||||
|
||||
PImage pic1, pic2;
|
||||
int selMode = REPLACE;
|
||||
String name = "replace";
|
||||
int picAlpha = 255;
|
||||
|
||||
void setup() {
|
||||
size(screenWidth, screenHeight, P3D);
|
||||
orientation(LANDSCAPE);
|
||||
|
||||
PFont font = createFont(PFont.list()[0], 24);
|
||||
textFont(font, 24);
|
||||
|
||||
pic1 = loadImage("bjorke1.jpg");
|
||||
pic2 = loadImage("bjorke2.jpg");
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
|
||||
tint(255, 255);
|
||||
image(pic1, 0, 0, pic1.width, pic1.height);
|
||||
|
||||
screenBlend(selMode);
|
||||
tint(255, picAlpha);
|
||||
image(pic2, 0, 0, pic2.width, pic2.height);
|
||||
|
||||
screenBlend(REPLACE);
|
||||
fill(200, 50, 50);
|
||||
rect(0, height - 50, map(picAlpha, 0, 255, 0, width), 50);
|
||||
fill(255);
|
||||
text("Selected blend mode: " + name + ". Tap to move to next", 10, pic1.height + 30);
|
||||
text("Drag this bar to change alpha of image", 10, height - 18);
|
||||
}
|
||||
|
||||
void mousePressed() {
|
||||
if (height - 50 < mouseY) return;
|
||||
|
||||
if (selMode == REPLACE) {
|
||||
selMode = BLEND;
|
||||
name = "blend";
|
||||
} else if (selMode == BLEND) {
|
||||
selMode = ADD;
|
||||
name = "add";
|
||||
} else if (selMode == ADD) {
|
||||
selMode = SUBTRACT;
|
||||
name = "subtract";
|
||||
} else if (selMode == SUBTRACT) {
|
||||
selMode = LIGHTEST;
|
||||
name = "lightest";
|
||||
} else if (selMode == LIGHTEST) {
|
||||
selMode = DARKEST;
|
||||
name = "darkest";
|
||||
} else if (selMode == DARKEST) {
|
||||
selMode = DIFFERENCE;
|
||||
name = "difference";
|
||||
} else if (selMode == DIFFERENCE) {
|
||||
selMode = EXCLUSION;
|
||||
name = "exclusion";
|
||||
} else if (selMode == EXCLUSION) {
|
||||
selMode = MULTIPLY;
|
||||
name = "multiply";
|
||||
} else if (selMode == MULTIPLY) {
|
||||
selMode = SCREEN;
|
||||
name = "screen";
|
||||
} else if (selMode == SCREEN) {
|
||||
selMode = REPLACE;
|
||||
name = "replace";
|
||||
}
|
||||
}
|
||||
|
||||
void mouseDragged() {
|
||||
if (height - 50 < mouseY) {
|
||||
picAlpha = int(map(mouseX, 0, width, 0, 255));
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
// CameraLight, by Andres Colubri
|
||||
// Simple example showing a lit rotating cube. The projection
|
||||
// is set to orthographic if the screen is tapped.
|
||||
|
||||
float spin = 0.0;
|
||||
|
||||
void setup() {
|
||||
size(480, 800, P3D);
|
||||
orientation(PORTRAIT);
|
||||
|
||||
noStroke();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(51);
|
||||
lights();
|
||||
|
||||
if (mousePressed) {
|
||||
// The arguments of ortho are specified in screen coordinates, where (0,0)
|
||||
// is the upper left corner of the screen
|
||||
ortho(0, width, 0, height);
|
||||
} else {
|
||||
|
||||
float fov = PI/3.0;
|
||||
float cameraZ = (height/2.0) / tan(fov/2.0);
|
||||
perspective(fov, float(width)/float(height),
|
||||
cameraZ/2.0, cameraZ*2.0);
|
||||
}
|
||||
|
||||
spin += 0.01;
|
||||
|
||||
pushMatrix();
|
||||
translate(width/2, height/2, 100);
|
||||
rotateX(PI/9);
|
||||
rotateY(PI/5 + spin);
|
||||
box(150);
|
||||
popMatrix();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
// Concentric, by Andres Colubri
|
||||
// This example shows how to use the shape recording functionality
|
||||
// to create a PShape3D object with multiple child shapes that can
|
||||
// be later organized in a tree structure to apply geometrical
|
||||
// transformations to different levels of the tree.
|
||||
|
||||
PShape3D object;
|
||||
PShape group1, group2, group3;
|
||||
|
||||
void setup() {
|
||||
size(480, 800, P3D);
|
||||
orientation(PORTRAIT);
|
||||
noStroke();
|
||||
|
||||
// We record all the geometry in object.
|
||||
object = (PShape3D)beginRecord();
|
||||
|
||||
// By setting different names, the different shapes
|
||||
// drawn here will be stored in the tree as separate
|
||||
// child shapes.
|
||||
shapeName("sphere");
|
||||
fill(50, 200, 50);
|
||||
sphere(50);
|
||||
|
||||
fill(200, 50, 50);
|
||||
shapeName("torus1");
|
||||
drawTorus(80, 5, 12, 48, 0);
|
||||
|
||||
shapeName("torus2");
|
||||
drawTorus(80, 5, 12, 48, 1);
|
||||
|
||||
shapeName("torus3");
|
||||
drawTorus(80, 5, 12, 48, 3);
|
||||
|
||||
fill(50, 50, 200);
|
||||
shapeName("torus4");
|
||||
drawTorus(150, 10, 12, 48, 0);
|
||||
|
||||
shapeName("torus5");
|
||||
drawTorus(150, 10, 12, 48, 1);
|
||||
|
||||
shapeName("torus6");
|
||||
drawTorus(150, 10, 12, 48, 3);
|
||||
|
||||
endRecord();
|
||||
|
||||
println("BEFORE GROUPING");
|
||||
printShape(object, "");
|
||||
|
||||
// Now we group the child shapes by indicating the name of the shapes
|
||||
// we want to put together.
|
||||
group1 = object.groupChildren(new String[] {"torus1", "torus2", "torus3", "torus4", "torus5", "torus6"}, "group1");
|
||||
group2 = object.groupChildren(new String[] {"torus1", "torus2", "torus3"}, "group2");
|
||||
group3 = object.groupChildren(new String[] {"torus4", "torus5", "torus6"}, "group3");
|
||||
|
||||
println("AFTER GROUPING");
|
||||
printShape(object, "");
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
|
||||
// Transformations to parts of the shape can be applied
|
||||
// before drawing the entire object.
|
||||
object.resetMatrix();
|
||||
group1.resetMatrix();
|
||||
group2.resetMatrix();
|
||||
group3.resetMatrix();
|
||||
object.translate(0, 0, map(sin(frameCount * PI / 600), -1, 1, 550, 0));
|
||||
group1.scale(map(cos(frameCount * PI / 200), -1, 1, 1, 1.5));
|
||||
group2.rotateX(frameCount * PI / 100);
|
||||
group2.rotateY(frameCount * PI / 100);
|
||||
group3.rotateX(-frameCount * PI / 140);
|
||||
group3.rotateY(-frameCount * PI / 160);
|
||||
|
||||
pointLight(250, 250, 250, 0, 0, 400);
|
||||
|
||||
translate(width/2, height/2);
|
||||
shape(object);
|
||||
|
||||
println(frameRate);
|
||||
}
|
||||
|
||||
void printShape(PShape pshape, String tab) {
|
||||
int f = pshape.getFamily();
|
||||
if (f == PShape.GROUP) println(tab + "GROUP shape");
|
||||
else if (f == PShape.GEOMETRY) println(tab + "GEOMETRY shape");
|
||||
println(tab + "Name: " + pshape.getName());
|
||||
println(tab + "Children: " + pshape.getChildCount());
|
||||
|
||||
for (int i = 0; i < pshape.getChildCount(); i++) {
|
||||
PShape child = pshape.getChild(i);
|
||||
printShape(child, tab + " ");
|
||||
}
|
||||
println(tab + "-------------------");
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
void drawTorus(float outerRad, float innerRad, int numc, int numt, int axis) {
|
||||
float x, y, z, s, t, u, v;
|
||||
float nx, ny, nz;
|
||||
float aInner, aOuter;
|
||||
int idx = 0;
|
||||
|
||||
beginShape(QUAD_STRIP);
|
||||
for (int i = 0; i < numc; i++) {
|
||||
for (int j = 0; j <= numt; j++) {
|
||||
t = j;
|
||||
v = t / (float)numt;
|
||||
aOuter = v * TWO_PI;
|
||||
float cOut = cos(aOuter);
|
||||
float sOut = sin(aOuter);
|
||||
for (int k = 1; k >= 0; k--) {
|
||||
s = (i + k);
|
||||
u = s / (float)numc;
|
||||
aInner = u * TWO_PI;
|
||||
float cIn = cos(aInner);
|
||||
float sIn = sin(aInner);
|
||||
|
||||
if (axis == 0) {
|
||||
x = (outerRad + innerRad * cIn) * cOut;
|
||||
y = (outerRad + innerRad * cIn) * sOut;
|
||||
z = innerRad * sIn;
|
||||
} else if (axis == 1) {
|
||||
x = innerRad * sIn;
|
||||
y = (outerRad + innerRad * cIn) * sOut;
|
||||
z = (outerRad + innerRad * cIn) * cOut;
|
||||
} else {
|
||||
x = (outerRad + innerRad * cIn) * cOut;
|
||||
y = innerRad * sIn;
|
||||
z = (outerRad + innerRad * cIn) * sOut;
|
||||
}
|
||||
|
||||
nx = cIn * cOut;
|
||||
ny = cIn * sOut;
|
||||
nz = sIn;
|
||||
|
||||
normal(nx, ny, nz);
|
||||
vertex(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
endShape();
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
// Cubic QTVR effect, by Robert Hodgin (flight404)
|
||||
//
|
||||
// Elves Chasm Colorado River QTVR source images by Taylor Harnisch and Gene Cooper
|
||||
// From www.panoramas.dk
|
||||
// Please do not reuse this QTVR source image. It is included for example purposes only.
|
||||
//
|
||||
// Original Arcball code is by Ariel and V3ga.
|
||||
//
|
||||
// Android port by Andres Colubri:
|
||||
// * Locked in landscape mode
|
||||
// * Tap in the center of the screen to go inside/outside of the cube
|
||||
|
||||
int xMid, yMid;
|
||||
|
||||
int counter = 0;
|
||||
int totalDevices = 4;
|
||||
|
||||
Arcball arcball;
|
||||
POV pov;
|
||||
VRCube vr;
|
||||
|
||||
boolean outside = true;
|
||||
|
||||
void setup() {
|
||||
size(800, 480, P3D);
|
||||
orientation(LANDSCAPE);
|
||||
|
||||
xMid = width/2;
|
||||
yMid = height/2;
|
||||
|
||||
arcball = new Arcball(float(xMid), float(yMid), height);
|
||||
// arbitrary distance for PointOfView camera. if you change the
|
||||
// dimensions of the applet, you will need to tweak this number
|
||||
pov = new POV(400.0);
|
||||
vr = new VRCube("coloradoCube-quarter.jpg");
|
||||
|
||||
frameRate(30);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(20);
|
||||
noStroke();
|
||||
|
||||
pov.exist();
|
||||
arcball.run();
|
||||
vr.exist();
|
||||
}
|
||||
|
||||
void mousePressed(){
|
||||
if (dist(mouseX, mouseY, width/2, height/2) < 100) {
|
||||
outside = !outside;
|
||||
} else {
|
||||
arcball.mousePressed();
|
||||
}
|
||||
}
|
||||
|
||||
void mouseDragged(){
|
||||
arcball.mouseDragged();
|
||||
}
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
// Ariel and V3ga's arcball class with a couple tiny mods by Robert Hodgin
|
||||
|
||||
class Arcball{
|
||||
float center_x, center_y, radius;
|
||||
Vec3 v_down, v_drag;
|
||||
Quat q_now, q_down, q_drag;
|
||||
Vec3[] axisSet;
|
||||
int axis;
|
||||
float mxv, myv;
|
||||
float x, y;
|
||||
Arcball(float center_x, float center_y, float radius){
|
||||
this.center_x = center_x;
|
||||
this.center_y = center_y;
|
||||
this.radius = radius;
|
||||
|
||||
v_down = new Vec3();
|
||||
v_drag = new Vec3();
|
||||
|
||||
q_now = new Quat();
|
||||
q_down = new Quat();
|
||||
q_drag = new Quat();
|
||||
|
||||
axisSet = new Vec3[] {new Vec3(1.0f, 0.0f, 0.0f), new Vec3(0.0f, 1.0f, 0.0f), new Vec3(0.0f, 0.0f, 1.0f)};
|
||||
axis = -1; // no constraints...
|
||||
}
|
||||
|
||||
void mousePressed(){
|
||||
v_down = mouse_to_sphere(mouseX, mouseY);
|
||||
q_down.set(q_now);
|
||||
q_drag.reset();
|
||||
}
|
||||
|
||||
void mouseDragged(){
|
||||
v_drag = mouse_to_sphere(mouseX, mouseY);
|
||||
q_drag.set(Vec3.dot(v_down, v_drag), Vec3.cross(v_down, v_drag));
|
||||
}
|
||||
|
||||
void run(){
|
||||
|
||||
q_now = Quat.mul(q_drag, q_down);
|
||||
applyQuat2Matrix(q_now);
|
||||
|
||||
x += mxv;
|
||||
y += myv;
|
||||
mxv -= mxv * .01;
|
||||
myv -= myv * .01;
|
||||
}
|
||||
|
||||
Vec3 mouse_to_sphere(float x, float y){
|
||||
Vec3 v = new Vec3();
|
||||
v.x = (x - center_x) / radius;
|
||||
v.y = (y - center_y) / radius;
|
||||
|
||||
float mag = v.x * v.x + v.y * v.y;
|
||||
if (mag > 1.0f){
|
||||
v.normalize();
|
||||
} else {
|
||||
v.z = sqrt(1.0f - mag);
|
||||
}
|
||||
|
||||
return (axis == -1) ? v : constrain_vector(v, axisSet[axis]);
|
||||
}
|
||||
|
||||
Vec3 constrain_vector(Vec3 vector, Vec3 axis){
|
||||
Vec3 res = new Vec3();
|
||||
res.sub(vector, Vec3.mul(axis, Vec3.dot(axis, vector)));
|
||||
res.normalize();
|
||||
return res;
|
||||
}
|
||||
|
||||
void applyQuat2Matrix(Quat q){
|
||||
// instead of transforming q into a matrix and applying it...
|
||||
|
||||
float[] aa = q.getValue();
|
||||
rotate(aa[0], aa[1], aa[2], aa[3]);
|
||||
}
|
||||
}
|
||||
|
||||
static class Vec3{
|
||||
float x, y, z;
|
||||
|
||||
Vec3(){
|
||||
}
|
||||
|
||||
Vec3(float x, float y, float z){
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
void normalize(){
|
||||
float length = length();
|
||||
x /= length;
|
||||
y /= length;
|
||||
z /= length;
|
||||
}
|
||||
|
||||
float length(){
|
||||
return (float) Math.sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
static Vec3 cross(Vec3 v1, Vec3 v2){
|
||||
Vec3 res = new Vec3();
|
||||
res.x = v1.y * v2.z - v1.z * v2.y;
|
||||
res.y = v1.z * v2.x - v1.x * v2.z;
|
||||
res.z = v1.x * v2.y - v1.y * v2.x;
|
||||
return res;
|
||||
}
|
||||
|
||||
static float dot(Vec3 v1, Vec3 v2){
|
||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
|
||||
}
|
||||
|
||||
static Vec3 mul(Vec3 v, float d){
|
||||
Vec3 res = new Vec3();
|
||||
res.x = v.x * d;
|
||||
res.y = v.y * d;
|
||||
res.z = v.z * d;
|
||||
return res;
|
||||
}
|
||||
|
||||
void sub(Vec3 v1, Vec3 v2){
|
||||
x = v1.x - v2.x;
|
||||
y = v1.y - v2.y;
|
||||
z = v1.z - v2.z;
|
||||
}
|
||||
}
|
||||
|
||||
static class Quat{
|
||||
float w, x, y, z;
|
||||
|
||||
Quat(){
|
||||
reset();
|
||||
}
|
||||
|
||||
Quat(float w, float x, float y, float z){
|
||||
this.w = w;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
void reset(){
|
||||
w = 1.0f;
|
||||
x = 0.0f;
|
||||
y = 0.0f;
|
||||
z = 0.0f;
|
||||
}
|
||||
|
||||
void set(float w, Vec3 v){
|
||||
this.w = w;
|
||||
x = v.x;
|
||||
y = v.y;
|
||||
z = v.z;
|
||||
}
|
||||
|
||||
void set(Quat q){
|
||||
w = q.w;
|
||||
x = q.x;
|
||||
y = q.y;
|
||||
z = q.z;
|
||||
}
|
||||
|
||||
static Quat mul(Quat q1, Quat q2){
|
||||
Quat res = new Quat();
|
||||
res.w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z;
|
||||
res.x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y;
|
||||
res.y = q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z;
|
||||
res.z = q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x;
|
||||
return res;
|
||||
}
|
||||
|
||||
float[] getValue(){
|
||||
// transforming this quat into an angle and an axis vector...
|
||||
|
||||
float[] res = new float[4];
|
||||
|
||||
float sa = (float) Math.sqrt(1.0f - w * w);
|
||||
if (sa < EPSILON){
|
||||
sa = 1.0f;
|
||||
}
|
||||
|
||||
res[0] = (float) Math.acos(w) * 2.0f;
|
||||
res[1] = x / sa;
|
||||
res[2] = y / sa;
|
||||
res[3] = z / sa;
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
// my basic Point Of View camera class.
|
||||
|
||||
class POV{
|
||||
float x,y,z;
|
||||
|
||||
float elevation;
|
||||
float azimuth;
|
||||
float distance;
|
||||
|
||||
POV (float sentDistance){
|
||||
distance = sentDistance;
|
||||
x = xMid;
|
||||
y = yMid;
|
||||
azimuth = 0;
|
||||
elevation = 0;
|
||||
}
|
||||
|
||||
void exist(){
|
||||
setPosition();
|
||||
setCamera();
|
||||
}
|
||||
|
||||
void setPosition(){
|
||||
x -= (x - xMid) * .2;
|
||||
y -= (y - yMid) * .2;
|
||||
if (outside){
|
||||
z -= (z + distance) * .2;
|
||||
} else {
|
||||
z -= (z - distance) * .2;
|
||||
}
|
||||
}
|
||||
|
||||
void setCamera(){
|
||||
translate(x, y, z);
|
||||
rotateY(elevation);
|
||||
rotateZ(-azimuth);
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
// QTVR style cube.
|
||||
|
||||
class VRCube{
|
||||
int totalSides = 6;
|
||||
int dim;
|
||||
int cDim;
|
||||
PImage[] sides;
|
||||
PImage mainImage;
|
||||
|
||||
VRCube (String sentFileName){
|
||||
noStroke();
|
||||
imageMode(CORNER);
|
||||
mainImage = loadImage(sentFileName);
|
||||
dim = mainImage.width/3;
|
||||
cDim = dim/2;
|
||||
|
||||
sides = new PImage[totalSides];
|
||||
sides[0] = mainImage.get(dim, 0, dim,dim);
|
||||
sides[1] = mainImage.get(0, dim, dim,dim);
|
||||
sides[2] = mainImage.get(dim, dim, dim,dim);
|
||||
sides[3] = mainImage.get(dim*2, dim, dim,dim);
|
||||
sides[4] = mainImage.get(dim, dim*2, dim,dim);
|
||||
sides[5] = mainImage.get(dim, dim*3, dim,dim);
|
||||
}
|
||||
|
||||
void exist(){
|
||||
renderCube();
|
||||
}
|
||||
|
||||
void renderCube(){
|
||||
pushMatrix();
|
||||
drawFace(sides[1]);
|
||||
rotateY(-HALF_PI);
|
||||
drawFace(sides[2]);
|
||||
rotateY(-HALF_PI);
|
||||
drawFace(sides[3]);
|
||||
rotateY(-HALF_PI);
|
||||
rotateZ(PI);
|
||||
drawFace(sides[5]);
|
||||
rotateX(HALF_PI);
|
||||
drawFace(sides[0]);
|
||||
rotateX(PI);
|
||||
drawFace(sides[4]);
|
||||
popMatrix();
|
||||
}
|
||||
|
||||
void drawFace(PImage sentImage){
|
||||
pushMatrix();
|
||||
translate(0,0,-cDim+.5);
|
||||
beginShape();
|
||||
texture(sentImage);
|
||||
vertex(-cDim,-cDim,0,0,0);
|
||||
vertex(-cDim,cDim,0,0,dim);
|
||||
vertex(cDim,cDim,0,dim,dim);
|
||||
vertex(cDim,-cDim,0,dim,0);
|
||||
endShape();
|
||||
popMatrix();
|
||||
}
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
// Earth
|
||||
// by Mike 'Flux' Chang (cleaned up by Aaron Koblin).
|
||||
// Based on code by Toxi.
|
||||
// Android port by Andres Colubri
|
||||
//
|
||||
// This example shows the shape recording functionality in A3D,
|
||||
// where an entire geometry drawn with the regular API can be
|
||||
// stored in a PShape3D object for later use. This greatly
|
||||
// improves the performance of the application.
|
||||
// Tap on the screen to enable/disable drawing with the recorded
|
||||
// shape.
|
||||
|
||||
PShape globe;
|
||||
PImage texmap;
|
||||
|
||||
int sDetail = 32; // Sphere detail setting
|
||||
float rotationY = 0;
|
||||
float globeRadius = 450;
|
||||
float pushBack = 0;
|
||||
|
||||
float[] cx, cz, sphereX, sphereY, sphereZ;
|
||||
float sinLUT[];
|
||||
float cosLUT[];
|
||||
float SINCOS_PRECISION = 0.5f;
|
||||
int SINCOS_LENGTH = (int)(360.0f / SINCOS_PRECISION);
|
||||
|
||||
boolean usingPShape = false;
|
||||
|
||||
public void setup() {
|
||||
size(480, 800, P3D);
|
||||
orientation(PORTRAIT);
|
||||
|
||||
PFont font = createFont(PFont.list()[0], 24);
|
||||
textFont(font, 24);
|
||||
|
||||
texmap = loadImage("world32k.jpg");
|
||||
initializeSphere(sDetail);
|
||||
|
||||
autoNormal(false);
|
||||
noStroke();
|
||||
|
||||
// Everything that is drawn between beginRecord/endRecord
|
||||
// is saved into the PShape3D returned by beginRecord.
|
||||
// Drawing the PShape3D object is much faster than redrawing
|
||||
// all the geometry again in the draw() function.
|
||||
globe = beginRecord();
|
||||
texturedSphere(globeRadius, texmap);
|
||||
endRecord();
|
||||
}
|
||||
|
||||
public void draw() {
|
||||
background(0);
|
||||
renderGlobe();
|
||||
|
||||
fill(255);
|
||||
if (usingPShape) {
|
||||
text("With PShape3D. FPS: " + frameRate, 10, height - 30);
|
||||
} else {
|
||||
text("Without PShape3D. FPS: " + frameRate, 10, height - 30);
|
||||
}
|
||||
}
|
||||
|
||||
void mousePressed() {
|
||||
usingPShape = !usingPShape;
|
||||
}
|
||||
|
||||
public void renderGlobe() {
|
||||
pushMatrix();
|
||||
translate(width/2.0f, height/2.0f, pushBack);
|
||||
lights();
|
||||
|
||||
pushMatrix();
|
||||
|
||||
rotateY(rotationY);
|
||||
|
||||
if (usingPShape) {
|
||||
shape(globe);
|
||||
} else {
|
||||
texturedSphere(globeRadius, texmap);
|
||||
}
|
||||
|
||||
popMatrix();
|
||||
popMatrix();
|
||||
|
||||
rotationY += 0.01;
|
||||
}
|
||||
|
||||
public 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 + 240 ) * 0.33;
|
||||
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++) {
|
||||
normal(0, -1, 0);
|
||||
vertex(0, -r, 0,u,0);
|
||||
normal(sphereX[i], sphereY[i], sphereZ[i]);
|
||||
vertex(sphereX[i]*r, sphereY[i]*r, sphereZ[i]*r, u, v);
|
||||
u+=iu;
|
||||
}
|
||||
vertex(0, -r, 0,u,0);
|
||||
normal(sphereX[0], sphereY[0], sphereZ[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++) {
|
||||
normal(sphereX[v1], sphereY[v1], sphereZ[v1]);
|
||||
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1++]*r, u, v);
|
||||
normal(sphereX[v2], sphereY[v2], sphereZ[v2]);
|
||||
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2++]*r, u, v+iv);
|
||||
u+=iu;
|
||||
}
|
||||
|
||||
// Close each ring
|
||||
v1=v11;
|
||||
v2=voff;
|
||||
normal(sphereX[v1], sphereY[v1], sphereZ[v1]);
|
||||
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1]*r, u, v);
|
||||
normal(sphereX[v2], sphereY[v2], sphereZ[v2]);
|
||||
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;
|
||||
normal(sphereX[v2], sphereY[v2], sphereZ[v2]);
|
||||
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v);
|
||||
normal(0, 1, 0);
|
||||
vertex(0, r, 0, u, v+iv);
|
||||
u+=iu;
|
||||
}
|
||||
normal(sphereX[voff], sphereY[voff], sphereZ[voff]);
|
||||
vertex(sphereX[voff]*r, sphereY[voff]*r, sphereZ[voff]*r, u, v);
|
||||
|
||||
endShape();
|
||||
}
|
||||
@@ -1,261 +0,0 @@
|
||||
// Earth
|
||||
// by Mike 'Flux' Chang (cleaned up by Aaron Koblin).
|
||||
// Based on code by Toxi.
|
||||
// Android port by Andres Colubri
|
||||
//
|
||||
// This example shows the shape recording functionality in A3D,
|
||||
// using the object-oriented mode, where the drawing calls are methods
|
||||
// in the PShape3D object.
|
||||
|
||||
PShape3D globe;
|
||||
PImage texmap;
|
||||
|
||||
int sDetail = 32; // Sphere detail setting
|
||||
float rotationY = 0;
|
||||
float globeRadius = 450;
|
||||
float pushBack = 0;
|
||||
|
||||
float[] cx, cz, sphereX, sphereY, sphereZ;
|
||||
float sinLUT[];
|
||||
float cosLUT[];
|
||||
float SINCOS_PRECISION = 0.5f;
|
||||
int SINCOS_LENGTH = (int)(360.0f / SINCOS_PRECISION);
|
||||
|
||||
boolean usingPShape = false;
|
||||
|
||||
public void setup() {
|
||||
size(480, 800, P3D);
|
||||
orientation(PORTRAIT);
|
||||
|
||||
PFont font = createFont(PFont.list()[0], 24);
|
||||
textFont(font, 24);
|
||||
|
||||
texmap = loadImage("world32k.jpg");
|
||||
initializeSphere(sDetail);
|
||||
|
||||
autoNormal(false);
|
||||
noStroke();
|
||||
|
||||
// Everything that is drawn between beginRecord/endRecord
|
||||
// is saved into the PShape3D object.
|
||||
// Drawing the PShape3D object is much faster than redrawing
|
||||
// all the geometry again in the draw() function.
|
||||
globe = new PShape3D(this);
|
||||
globe.beginRecord();
|
||||
recTexSphere(globe, globeRadius, texmap);
|
||||
globe.endRecord();
|
||||
}
|
||||
|
||||
public void draw() {
|
||||
background(0);
|
||||
renderGlobe();
|
||||
|
||||
fill(255);
|
||||
if (usingPShape) {
|
||||
text("With PShape3D. FPS: " + frameRate, 10, height - 30);
|
||||
} else {
|
||||
text("Without PShape3D. FPS: " + frameRate, 10, height - 30);
|
||||
}
|
||||
}
|
||||
|
||||
void mousePressed() {
|
||||
usingPShape = !usingPShape;
|
||||
}
|
||||
|
||||
public void renderGlobe() {
|
||||
pushMatrix();
|
||||
translate(width/2.0f, height/2.0f, pushBack);
|
||||
lights();
|
||||
|
||||
pushMatrix();
|
||||
|
||||
rotateY(rotationY);
|
||||
|
||||
if (usingPShape) {
|
||||
shape(globe);
|
||||
} else {
|
||||
drawTexSphere(globeRadius, texmap);
|
||||
}
|
||||
|
||||
popMatrix();
|
||||
popMatrix();
|
||||
|
||||
rotationY += 0.01;
|
||||
}
|
||||
|
||||
public 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 drawTexSphere(float r, PImage t) {
|
||||
int v1,v11,v2;
|
||||
r = (r + 240 ) * 0.33;
|
||||
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++) {
|
||||
normal(0, -1, 0);
|
||||
vertex(0, -r, 0,u,0);
|
||||
normal(sphereX[i], sphereY[i], sphereZ[i]);
|
||||
vertex(sphereX[i]*r, sphereY[i]*r, sphereZ[i]*r, u, v);
|
||||
u+=iu;
|
||||
}
|
||||
vertex(0, -r, 0,u,0);
|
||||
normal(sphereX[0], sphereY[0], sphereZ[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++) {
|
||||
normal(sphereX[v1], sphereY[v1], sphereZ[v1]);
|
||||
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1++]*r, u, v);
|
||||
normal(sphereX[v2], sphereY[v2], sphereZ[v2]);
|
||||
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2++]*r, u, v+iv);
|
||||
u+=iu;
|
||||
}
|
||||
|
||||
// Close each ring
|
||||
v1=v11;
|
||||
v2=voff;
|
||||
normal(sphereX[v1], sphereY[v1], sphereZ[v1]);
|
||||
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1]*r, u, v);
|
||||
normal(sphereX[v2], sphereY[v2], sphereZ[v2]);
|
||||
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;
|
||||
normal(sphereX[v2], sphereY[v2], sphereZ[v2]);
|
||||
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v);
|
||||
normal(0, 1, 0);
|
||||
vertex(0, r, 0, u, v+iv);
|
||||
u+=iu;
|
||||
}
|
||||
normal(sphereX[voff], sphereY[voff], sphereZ[voff]);
|
||||
vertex(sphereX[voff]*r, sphereY[voff]*r, sphereZ[voff]*r, u, v);
|
||||
|
||||
endShape();
|
||||
}
|
||||
|
||||
void recTexSphere(PShape3D obj, float r, PImage t) {
|
||||
int v1,v11,v2;
|
||||
r = (r + 240 ) * 0.33;
|
||||
obj.beginShape(TRIANGLE_STRIP);
|
||||
obj.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++) {
|
||||
obj.normal(0, -1, 0);
|
||||
obj.vertex(0, -r, 0,u,0);
|
||||
obj.normal(sphereX[i], sphereY[i], sphereZ[i]);
|
||||
obj.vertex(sphereX[i]*r, sphereY[i]*r, sphereZ[i]*r, u, v);
|
||||
u+=iu;
|
||||
}
|
||||
obj.vertex(0, -r, 0,u,0);
|
||||
obj.normal(sphereX[0], sphereY[0], sphereZ[0]);
|
||||
obj.vertex(sphereX[0]*r, sphereY[0]*r, sphereZ[0]*r, u, v);
|
||||
obj.endShape();
|
||||
|
||||
// Middle rings
|
||||
int voff = 0;
|
||||
for(int i = 2; i < sDetail; i++) {
|
||||
v1=v11=voff;
|
||||
voff += sDetail;
|
||||
v2=voff;
|
||||
u=0;
|
||||
obj.beginShape(TRIANGLE_STRIP);
|
||||
obj.texture(t);
|
||||
for (int j = 0; j < sDetail; j++) {
|
||||
normal(sphereX[v1], sphereY[v1], sphereZ[v1]);
|
||||
obj.vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1++]*r, u, v);
|
||||
obj.normal(sphereX[v2], sphereY[v2], sphereZ[v2]);
|
||||
obj.vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2++]*r, u, v+iv);
|
||||
u+=iu;
|
||||
}
|
||||
|
||||
// Close each ring
|
||||
v1=v11;
|
||||
v2=voff;
|
||||
obj.normal(sphereX[v1], sphereY[v1], sphereZ[v1]);
|
||||
obj.vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1]*r, u, v);
|
||||
obj.normal(sphereX[v2], sphereY[v2], sphereZ[v2]);
|
||||
obj.vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v+iv);
|
||||
obj.endShape();
|
||||
v+=iv;
|
||||
}
|
||||
u=0;
|
||||
|
||||
// Add the northern cap
|
||||
obj.beginShape(TRIANGLE_STRIP);
|
||||
obj.texture(t);
|
||||
for (int i = 0; i < sDetail; i++) {
|
||||
v2 = voff + i;
|
||||
obj.normal(sphereX[v2], sphereY[v2], sphereZ[v2]);
|
||||
obj.vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v);
|
||||
obj.normal(0, 1, 0);
|
||||
obj.vertex(0, r, 0, u, v+iv);
|
||||
u+=iu;
|
||||
}
|
||||
obj.normal(sphereX[voff], sphereY[voff], sphereZ[voff]);
|
||||
obj.vertex(sphereX[voff]*r, sphereY[voff]*r, sphereZ[voff]*r, u, v);
|
||||
|
||||
obj.endShape();
|
||||
}
|
||||
@@ -1,276 +0,0 @@
|
||||
// Electric by Andor Salga
|
||||
// Ported from Processing.JS by Andres Colubri. Original
|
||||
// code available at
|
||||
// http://matrix.senecac.on.ca/~asalga/pjswebide/index.php
|
||||
|
||||
float r = 0;
|
||||
int bolts = 0;
|
||||
float lightningOpacity = 255;
|
||||
int level = -1;
|
||||
int startTime = 0;
|
||||
|
||||
ArrayList LBolts;
|
||||
|
||||
void setup() {
|
||||
size(480, 800, P3D);
|
||||
orientation(PORTRAIT);
|
||||
|
||||
LBolts = new ArrayList();
|
||||
|
||||
for (int i=0; i < 12; i++) {
|
||||
LBolts.add(new Lightning());
|
||||
}
|
||||
|
||||
startTime = millis();
|
||||
}
|
||||
|
||||
void update(int deltaTime) {
|
||||
level = 0;
|
||||
for (int i=0; i < 12; i++) {
|
||||
Lightning l = (Lightning)LBolts.get(i);
|
||||
l.update(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background( abs(250* sin(frameCount/100)),
|
||||
abs(100* cos(frameCount/50)), abs(150* cos(frameCount/150)));
|
||||
|
||||
translate(width/2, height/2, 0);
|
||||
|
||||
rotate(r+=0.005);
|
||||
rotateX(-r);
|
||||
rotateZ(r);
|
||||
|
||||
update(millis()-startTime);
|
||||
|
||||
for (int i=0; i < 12; i++) {
|
||||
Lightning l = (Lightning)LBolts.get(i);
|
||||
l.draw();
|
||||
}
|
||||
}
|
||||
|
||||
class PVector3D
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
PVector3D() {
|
||||
set(0, 0, 0);
|
||||
}
|
||||
|
||||
PVector3D(float x, float y, float z) {
|
||||
set(x, y, z);
|
||||
}
|
||||
|
||||
void set(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
|
||||
PVector3D add(PVector3D v1, PVector3D v2) {
|
||||
return new PVector3D(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
|
||||
}
|
||||
|
||||
PVector3D sub(PVector3D initialPoint, PVector3D terminalPoint) {
|
||||
return new PVector3D(
|
||||
terminalPoint.x - initialPoint.x,
|
||||
terminalPoint.y - initialPoint.y,
|
||||
terminalPoint.z - initialPoint.z);
|
||||
}
|
||||
|
||||
float len(PVector3D v) {
|
||||
return sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
|
||||
}
|
||||
|
||||
PVector3D scale(PVector3D v, float s) {
|
||||
return new PVector3D(v.x*s, v.y*s, v.z*s);
|
||||
}
|
||||
|
||||
class LightningBolt {
|
||||
PVector3D start;
|
||||
PVector3D end;
|
||||
|
||||
ArrayList nodes = new ArrayList();
|
||||
ArrayList onodes = new ArrayList();
|
||||
|
||||
int deviation;
|
||||
int bounds;
|
||||
int numNodes;
|
||||
boolean isInit;
|
||||
|
||||
LightningBolt() {
|
||||
bounds = 0;
|
||||
isInit = false;
|
||||
start = new PVector3D();
|
||||
end = new PVector3D();
|
||||
numNodes = 0;
|
||||
deviation = 0;
|
||||
nodes = new ArrayList();
|
||||
onodes = new ArrayList();
|
||||
}
|
||||
|
||||
void init() {
|
||||
PVector3D startToEnd = sub(start, end);
|
||||
float lineLen = len(startToEnd);
|
||||
|
||||
print(startToEnd);
|
||||
|
||||
float nodeSeparation = lineLen / numNodes;
|
||||
|
||||
for (int i = 1; i <= numNodes; i++) {
|
||||
|
||||
PVector3D p = add(scale(startToEnd, i/(float)numNodes), start);
|
||||
PVector3D o = add(scale(startToEnd, i/(float)numNodes), start);
|
||||
|
||||
nodes.add(p);
|
||||
onodes.add(o);
|
||||
}
|
||||
isInit = true;
|
||||
}
|
||||
|
||||
void setDeviation(int d) {
|
||||
deviation = d;
|
||||
}
|
||||
|
||||
void setNumNodes(int n) {
|
||||
numNodes = n;
|
||||
}
|
||||
|
||||
void setBounds(int b) {
|
||||
bounds = b;
|
||||
}
|
||||
|
||||
void setStartPoint(PVector3D p) {
|
||||
start = p;
|
||||
}
|
||||
|
||||
void setEndPoint(PVector3D p) {
|
||||
end = p;
|
||||
}
|
||||
|
||||
void update(int deltaTime) {
|
||||
if (isInit == false) {
|
||||
init();
|
||||
}
|
||||
else {
|
||||
for (int i=1; i < nodes.size()-1; i++) {
|
||||
PVector3D p = (PVector3D)nodes.get(i);
|
||||
PVector3D op = (PVector3D)onodes.get(i);
|
||||
|
||||
float rx = random(-deviation, deviation);
|
||||
if ( abs((rx + p.x - op.x)) < bounds) {
|
||||
p.x += rx;
|
||||
nodes.set(i, p);
|
||||
}
|
||||
|
||||
float ry = random(-deviation, deviation);
|
||||
if ( abs((ry + p.y - op.y)) < bounds) {
|
||||
p.y += ry;
|
||||
nodes.set(i, p);
|
||||
}
|
||||
|
||||
float rz = random(-deviation, deviation);
|
||||
if ( abs((rz + p.z - op.z)) < bounds) {
|
||||
p.z += rz;
|
||||
nodes.set(i, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
PVector3D lastNode = start;
|
||||
int b = 250;
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
PVector3D node = (PVector3D)nodes.get(i);
|
||||
|
||||
strokeWeight(1);
|
||||
stroke(10, 10, 100, lightningOpacity);
|
||||
line(lastNode.x, lastNode.y, lastNode.z, node.x, node.y, node.z);
|
||||
lastNode = node;
|
||||
}
|
||||
|
||||
lastNode = start;
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
PVector3D node = (PVector3D)nodes.get(i);
|
||||
|
||||
strokeWeight(1);
|
||||
stroke(255, 150);
|
||||
lastNode = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Lightning {
|
||||
LightningBolt bolt;
|
||||
|
||||
Lightning() {
|
||||
bolts++;
|
||||
bolt = new LightningBolt();
|
||||
bolt.setDeviation(13);
|
||||
bolt.setBounds(10);
|
||||
bolt.setNumNodes(7);
|
||||
|
||||
if ( bolts == 1) {
|
||||
bolt.setEndPoint(new PVector3D(-100, 100, -100));
|
||||
bolt.setStartPoint(new PVector3D(100, 100, -100));
|
||||
}
|
||||
else if ( bolts == 2) {
|
||||
bolt.setEndPoint(new PVector3D(-100, 100, 100));
|
||||
bolt.setStartPoint(new PVector3D(100, 100, 100));
|
||||
}
|
||||
else if ( bolts == 3) {
|
||||
bolt.setEndPoint(new PVector3D(-100, 100, -100));
|
||||
bolt.setStartPoint(new PVector3D(-100, 100, 100));
|
||||
}
|
||||
else if ( bolts == 4) {
|
||||
bolt.setEndPoint(new PVector3D(100, 100, -100));
|
||||
bolt.setStartPoint(new PVector3D(100, 100, 100));
|
||||
}
|
||||
else if (bolts == 5) {
|
||||
bolt.setEndPoint(new PVector3D(100, -100, -100));
|
||||
bolt.setStartPoint(new PVector3D(100, -100, 100));
|
||||
}
|
||||
else if (bolts == 6) {
|
||||
bolt.setEndPoint(new PVector3D(-100, -100, 100));
|
||||
bolt.setStartPoint(new PVector3D(100, -100, 100));
|
||||
}
|
||||
else if (bolts == 7) {
|
||||
bolt.setEndPoint(new PVector3D(-100, -100, -100));
|
||||
bolt.setStartPoint(new PVector3D(-100, -100, 100));
|
||||
}
|
||||
else if (bolts == 8) {
|
||||
bolt.setEndPoint(new PVector3D(-100, -100, -100));
|
||||
bolt.setStartPoint(new PVector3D(100, -100, -100));
|
||||
}
|
||||
else if (bolts == 9) {
|
||||
bolt.setEndPoint(new PVector3D(100, 100, 100));
|
||||
bolt.setStartPoint(new PVector3D(100, -100, 100));
|
||||
}
|
||||
else if (bolts == 10) {
|
||||
bolt.setEndPoint(new PVector3D(-100, 100, -100));
|
||||
bolt.setStartPoint(new PVector3D(-100, -100, -100));
|
||||
}
|
||||
else if (bolts == 11) {
|
||||
bolt.setEndPoint(new PVector3D(100, 100, -100));
|
||||
bolt.setStartPoint(new PVector3D(100, -100, -100));
|
||||
}
|
||||
else if (bolts == 12) {
|
||||
bolt.setEndPoint(new PVector3D(-100, 100, 100));
|
||||
bolt.setStartPoint(new PVector3D(-100, -100, 100));
|
||||
}
|
||||
bolt.init();
|
||||
}
|
||||
|
||||
void update(int deltaTime) {
|
||||
bolt.update(deltaTime);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
bolt.draw();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
// Esfera, by David Pena.
|
||||
// Uniform random distribution over the surface of a sphere.
|
||||
//
|
||||
// PERFORMANCE ON ANDROID of this example is very low because
|
||||
// line drawing in A3D needs to be reimplemented. See this bug
|
||||
// report: http://code.google.com/p/processing/issues/detail?id=123
|
||||
|
||||
int cuantos = 1000;
|
||||
pelo[] lista ;
|
||||
float[] z = new float[cuantos];
|
||||
float[] phi = new float[cuantos];
|
||||
float[] largos = new float[cuantos];
|
||||
float radio = 200;
|
||||
float rx = 0;
|
||||
float ry =0;
|
||||
|
||||
void setup() {
|
||||
size(480, 800, P3D);
|
||||
orientation(PORTRAIT);
|
||||
|
||||
radio = height/3.5;
|
||||
|
||||
lista = new pelo[cuantos];
|
||||
for (int i=0; i<cuantos; i++){
|
||||
lista[i] = new pelo();
|
||||
}
|
||||
noiseDetail(3);
|
||||
|
||||
//autoNormal(false);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
translate(width/2,height/2);
|
||||
|
||||
float rxp = ((mouseX-(width/2))*0.005);
|
||||
float ryp = ((mouseY-(height/2))*0.005);
|
||||
rx = (rx*0.9)+(rxp*0.1);
|
||||
ry = (ry*0.9)+(ryp*0.1);
|
||||
|
||||
rotateY(rx);
|
||||
rotateX(ry);
|
||||
fill(0);
|
||||
noStroke();
|
||||
sphere(radio);
|
||||
|
||||
for (int i=0;i<cuantos;i++){
|
||||
lista[i].dibujar();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class pelo
|
||||
{
|
||||
float z = random(-radio,radio);
|
||||
float phi = random(TWO_PI);
|
||||
float largo = random(1.15,1.2);
|
||||
float theta = asin(z/radio);
|
||||
|
||||
void dibujar(){
|
||||
|
||||
float off = (noise(millis() * 0.0005,sin(phi))-0.5) * 0.3;
|
||||
float offb = (noise(millis() * 0.0007,sin(z) * 0.01)-0.5) * 0.3;
|
||||
|
||||
float thetaff = theta+off;
|
||||
float phff = phi+offb;
|
||||
float x = radio * cos(theta) * cos(phi);
|
||||
float y = radio * cos(theta) * sin(phi);
|
||||
float z = radio * sin(theta);
|
||||
float msx= screenX(x,y,z);
|
||||
float msy= screenY(x,y,z);
|
||||
|
||||
float xo = radio * cos(thetaff) * cos(phff);
|
||||
float yo = radio * cos(thetaff) * sin(phff);
|
||||
float zo = radio * sin(thetaff);
|
||||
|
||||
float xb = xo * largo;
|
||||
float yb = yo * largo;
|
||||
float zb = zo * largo;
|
||||
|
||||
beginShape(LINES);
|
||||
stroke(0);
|
||||
vertex(x,y,z);
|
||||
stroke(200,150);
|
||||
vertex(xb,yb,zb);
|
||||
endShape();
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
// Extrusion.
|
||||
// Converts a flat image into spatial data points and rotates the points
|
||||
// around the center.
|
||||
//
|
||||
// PERFORMANCE ON ANDROID of this example is very low because
|
||||
// line drawing in A3D needs to be reimplemented. See this bug
|
||||
// report: http://code.google.com/p/processing/issues/detail?id=123
|
||||
|
||||
PImage a;
|
||||
boolean onetime = true;
|
||||
int[][] aPixels;
|
||||
int[][] values;
|
||||
float angle;
|
||||
|
||||
void setup() {
|
||||
size(480, 800, P3D);
|
||||
orientation(PORTRAIT);
|
||||
|
||||
aPixels = new int[width][height];
|
||||
values = new int[width][height];
|
||||
noFill();
|
||||
|
||||
// Load the image into a new array
|
||||
// Extract the values and store in an array
|
||||
a = loadImage("ystone08.jpg");
|
||||
a.loadPixels();
|
||||
for (int i = 0; i < a.height; i++) {
|
||||
for (int j = 0; j < a.width; j++) {
|
||||
aPixels[j][i] = a.pixels[i*a.width + j];
|
||||
values[j][i] = int(blue(aPixels[j][i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(255);
|
||||
translate(width/2, height/2, 0);
|
||||
scale(2.0);
|
||||
|
||||
// Update and constrain the angle
|
||||
angle += 0.05;
|
||||
rotateY(angle);
|
||||
|
||||
// Display the image mass
|
||||
for (int i = 0; i < a.height; i += 2) {
|
||||
for (int j = 0; j < a.width; j += 2) {
|
||||
stroke(values[j][i], 153);
|
||||
line(j-a.width/2, i-a.height/2, -values[j][i], j-a.width/2, i-a.height/2, -values[j][i]-10);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
// Geometry, by Marius Watz.
|
||||
//
|
||||
// Using sin/cos lookup tables, blends colors, and draws a series of
|
||||
// rotating arcs on the screen.
|
||||
//
|
||||
// PERFORMANCE ON ANDROID of this example is very low because
|
||||
// line drawing in A3D needs to be reimplemented. See this bug
|
||||
// report: http://code.google.com/p/processing/issues/detail?id=123
|
||||
|
||||
// Trig lookup tables borrowed from Toxi; cryptic but effective.
|
||||
float sinLUT[];
|
||||
float cosLUT[];
|
||||
float SINCOS_PRECISION=1.0;
|
||||
int SINCOS_LENGTH= int((360.0/SINCOS_PRECISION));
|
||||
|
||||
// System data
|
||||
boolean dosave=false;
|
||||
int num;
|
||||
float pt[];
|
||||
int style[];
|
||||
|
||||
void setup() {
|
||||
size(480, 800, P3D);
|
||||
orientation(PORTRAIT);
|
||||
|
||||
background(255);
|
||||
|
||||
// Fill the tables
|
||||
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);
|
||||
}
|
||||
|
||||
num = 50;
|
||||
pt = new float[6*num]; // rotx, roty, deg, rad, w, speed
|
||||
style = new int[2*num]; // color, render style
|
||||
|
||||
// Set up arc shapes
|
||||
int index=0;
|
||||
float prob;
|
||||
for (int i=0; i<num; i++) {
|
||||
pt[index++] = random(PI*2); // Random X axis rotation
|
||||
pt[index++] = random(PI*2); // Random Y axis rotation
|
||||
|
||||
pt[index++] = random(60,80); // Short to quarter-circle arcs
|
||||
if(random(100)>90) pt[index]=(int)random(8,27)*10;
|
||||
|
||||
pt[index++] = int(random(2,50)*5); // Radius. Space them out nicely
|
||||
|
||||
pt[index++] = random(4,32); // Width of band
|
||||
if(random(100)>90) pt[index]=random(40,60); // Width of band
|
||||
|
||||
pt[index++] = radians(random(5,30))/5; // Speed of rotation
|
||||
|
||||
// get colors
|
||||
prob = random(100);
|
||||
if(prob<30) style[i*2]=colorBlended(random(1), 255,0,100, 255,0,0, 210);
|
||||
else if(prob<70) style[i*2]=colorBlended(random(1), 0,153,255, 170,225,255, 210);
|
||||
else if(prob<90) style[i*2]=colorBlended(random(1), 200,255,0, 150,255,0, 210);
|
||||
else style[i*2]=color(255,255,255, 220);
|
||||
|
||||
if(prob<50) style[i*2]=colorBlended(random(1), 200,255,0, 50,120,0, 210);
|
||||
else if(prob<90) style[i*2]=colorBlended(random(1), 255,100,0, 255,255,0, 210);
|
||||
else style[i*2]=color(255,255,255, 220);
|
||||
|
||||
style[i*2+1]=(int)(random(100))%3;
|
||||
}
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
|
||||
int index=0;
|
||||
translate(width/2, height/2, 0);
|
||||
rotateX(PI/6);
|
||||
rotateY(PI/6);
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
pushMatrix();
|
||||
|
||||
rotateX(pt[index++]);
|
||||
rotateY(pt[index++]);
|
||||
|
||||
if(style[i*2+1]==0) {
|
||||
stroke(style[i*2]);
|
||||
noFill();
|
||||
strokeWeight(1);
|
||||
arcLine(0,0, pt[index++],pt[index++],pt[index++]);
|
||||
}
|
||||
else if(style[i*2+1]==1) {
|
||||
fill(style[i*2]);
|
||||
noStroke();
|
||||
arcLineBars(0,0, pt[index++],pt[index++],pt[index++]);
|
||||
}
|
||||
else {
|
||||
fill(style[i*2]);
|
||||
noStroke();
|
||||
arc(0,0, pt[index++],pt[index++],pt[index++]);
|
||||
}
|
||||
|
||||
// increase rotation
|
||||
pt[index-5]+=pt[index]/10;
|
||||
pt[index-4]+=pt[index++]/20;
|
||||
|
||||
popMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get blend of two colors
|
||||
int colorBlended(float fract,
|
||||
float r, float g, float b,
|
||||
float r2, float g2, float b2, float a) {
|
||||
|
||||
r2 = (r2 - r);
|
||||
g2 = (g2 - g);
|
||||
b2 = (b2 - b);
|
||||
return color(r + r2 * fract, g + g2 * fract, b + b2 * fract, a);
|
||||
}
|
||||
|
||||
|
||||
// Draw arc line
|
||||
void arcLine(float x,float y,float deg,float rad,float w) {
|
||||
int a=(int)(min (deg/SINCOS_PRECISION,SINCOS_LENGTH-1));
|
||||
int numlines=(int)(w/2);
|
||||
|
||||
for (int j=0; j<numlines; j++) {
|
||||
beginShape();
|
||||
for (int i=0; i<a; i++) {
|
||||
vertex(cosLUT[i]*rad+x,sinLUT[i]*rad+y);
|
||||
}
|
||||
endShape();
|
||||
rad += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw arc line with bars
|
||||
void arcLineBars(float x,float y,float deg,float rad,float w) {
|
||||
int a = int((min (deg/SINCOS_PRECISION,SINCOS_LENGTH-1)));
|
||||
a /= 4;
|
||||
|
||||
beginShape(QUADS);
|
||||
for (int i=0; i<a; i+=4) {
|
||||
vertex(cosLUT[i]*(rad)+x,sinLUT[i]*(rad)+y);
|
||||
vertex(cosLUT[i]*(rad+w)+x,sinLUT[i]*(rad+w)+y);
|
||||
vertex(cosLUT[i+2]*(rad+w)+x,sinLUT[i+2]*(rad+w)+y);
|
||||
vertex(cosLUT[i+2]*(rad)+x,sinLUT[i+2]*(rad)+y);
|
||||
}
|
||||
endShape();
|
||||
}
|
||||
|
||||
// Draw solid arc
|
||||
void arc(float x,float y,float deg,float rad,float w) {
|
||||
int a = int(min (deg/SINCOS_PRECISION,SINCOS_LENGTH-1));
|
||||
beginShape(QUAD_STRIP);
|
||||
for (int i = 0; i < a; i++) {
|
||||
vertex(cosLUT[i]*(rad)+x,sinLUT[i]*(rad)+y);
|
||||
vertex(cosLUT[i]*(rad+w)+x,sinLUT[i]*(rad+w)+y);
|
||||
}
|
||||
endShape();
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
// Kinetic Type, by Zach Lieberman.
|
||||
//
|
||||
// Using push() and pop() to define the curves of the lines of type.
|
||||
|
||||
Line ln;
|
||||
Line lns[];
|
||||
|
||||
String words[] = {
|
||||
"sometimes it's like", "the lines of text", "are so happy", "that they want to dance",
|
||||
"or leave the page or jump", "can you blame them?", "living on the page like that",
|
||||
"waiting to be read..."
|
||||
};
|
||||
|
||||
void setup() {
|
||||
size(800, 480, P3D);
|
||||
orientation(LANDSCAPE);
|
||||
|
||||
// Array of line objects
|
||||
lns = new Line[8];
|
||||
|
||||
// Load the font from the sketch's data directory
|
||||
textFont(loadFont("Univers-66.vlw"), 1.0);
|
||||
|
||||
// White type
|
||||
fill(255);
|
||||
|
||||
// Creating the line objects
|
||||
for(int i = 0; i < 8; i++) {
|
||||
// For every line in the array, create a Line object to animate
|
||||
// i * 70 is the spacing
|
||||
ln = new Line(words[i], 0, i * 70);
|
||||
lns[i] = ln;
|
||||
}
|
||||
|
||||
hint(DISABLE_DEPTH_MASK);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
|
||||
translate(-200, -50, -450);
|
||||
rotateY(0.3);
|
||||
|
||||
// Now animate every line object & draw it...
|
||||
for(int i = 0; i < 8; i++) {
|
||||
float f1 = sin((i + 1.0) * (millis() / 10000.0) * TWO_PI);
|
||||
float f2 = sin((8.0 - i) * (millis() / 10000.0) * TWO_PI);
|
||||
Line line = lns[i];
|
||||
pushMatrix();
|
||||
translate(0.0, line.yPosition, 0.0);
|
||||
for(int j = 0; j < line.myLetters.length; j++) {
|
||||
if(j != 0) {
|
||||
translate(textWidth(line.myLetters[j - 1].myChar) * 75, 0.0, 0.0);
|
||||
}
|
||||
rotateY(f1 * 0.005 * f2);
|
||||
pushMatrix();
|
||||
scale(75.0);
|
||||
text(line.myLetters[j].myChar, 0.0, 0.0);
|
||||
popMatrix();
|
||||
}
|
||||
popMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
class Letter
|
||||
{
|
||||
char myChar;
|
||||
float x;
|
||||
float y;
|
||||
|
||||
Letter(char c, float f, float f1)
|
||||
{
|
||||
myChar = c;
|
||||
x = f;
|
||||
y = f1;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
class Line
|
||||
{
|
||||
String myString;
|
||||
int xPosition;
|
||||
int yPosition;
|
||||
int highlightNum;
|
||||
float speed;
|
||||
float curlInX;
|
||||
Letter myLetters[];
|
||||
|
||||
Line(String s, int i, int j)
|
||||
{
|
||||
myString = s;
|
||||
xPosition = i;
|
||||
yPosition = j;
|
||||
myLetters = new Letter[s.length()];
|
||||
float f1 = 0.0;
|
||||
for(int k = 0; k < s.length(); k++)
|
||||
{
|
||||
char c = s.charAt(k);
|
||||
f1 += textWidth(c);
|
||||
Letter letter = new Letter(c, f1, 0.0);
|
||||
myLetters[k] = letter;
|
||||
}
|
||||
|
||||
curlInX = 0.1;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
class Word
|
||||
{
|
||||
String myName;
|
||||
int x;
|
||||
|
||||
Word(String s)
|
||||
{
|
||||
myName = s;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -1,45 +0,0 @@
|
||||
// Lights
|
||||
// Modified from an example by Simon Greenwold.
|
||||
// Display a box with three different kinds of lights.
|
||||
|
||||
void setup() {
|
||||
size(480, 800, P3D);
|
||||
orientation(PORTRAIT);
|
||||
|
||||
noStroke();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
defineLights();
|
||||
background(0);
|
||||
|
||||
fill(150);
|
||||
|
||||
for (int x = 0; x <= width + 100; x += 100) {
|
||||
for (int y = 0; y <= height + 100; y += 100) {
|
||||
pushMatrix();
|
||||
translate(x, y);
|
||||
rotateY(map(mouseX, 0, width, 0, PI));
|
||||
rotateX(map(mouseY, 0, height, 0, PI));
|
||||
box(90);
|
||||
popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void defineLights() {
|
||||
// Orange point light on the right
|
||||
pointLight(150, 100, 0, // Color
|
||||
300, -200, 0); // Position
|
||||
|
||||
// Blue directional light from the left
|
||||
directionalLight(0, 102, 255, // Color
|
||||
1, 0, 0); // The x-, y-, z-axis direction
|
||||
|
||||
// Yellow spotlight from the front
|
||||
spotLight(255, 255, 109, // Color
|
||||
0, 40, 200, // Position
|
||||
0, -0.5f, -0.5f, // Direction
|
||||
PI / 2, 2); // Angle, concentration
|
||||
}
|
||||
|
||||
@@ -1,225 +0,0 @@
|
||||
// Nehe by Andres Colubri
|
||||
// Example of direct OpenGL use inside Processing in Android mode.
|
||||
// Ported from NeHe tutorial 8:
|
||||
// http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=08
|
||||
|
||||
import javax.microedition.khronos.opengles.*;
|
||||
import android.opengl.*;
|
||||
import android.graphics.*;
|
||||
import java.nio.*;
|
||||
|
||||
boolean lighting = true;
|
||||
boolean blending = true;
|
||||
boolean depthTest = true;
|
||||
boolean depthMask = false;
|
||||
boolean texturing = true;
|
||||
|
||||
int selBlend = 1;
|
||||
int selFilter = 0;
|
||||
float transparency = 0.5f;
|
||||
|
||||
// The color depth of the sketch can be set with this
|
||||
// method. The 6 numbers separated by colons correspond
|
||||
// to the red, green, blue, alpha, depth and stencil bits.
|
||||
// If this method is not defined, then Processing will let
|
||||
// OpenGL to automatically choose the color depth.
|
||||
String sketchColordepth() {
|
||||
return "8:8:8:8:16:0";
|
||||
}
|
||||
|
||||
// Whether the sketch surface supports translucenty or not.
|
||||
boolean sketchTranslucency() {
|
||||
return true;
|
||||
}
|
||||
|
||||
FloatBuffer[] cubeVertexBfr;
|
||||
FloatBuffer[] cubeNormalBfr;
|
||||
FloatBuffer[] cubeTextureBfr;
|
||||
|
||||
FloatBuffer lightAmbBfr;
|
||||
FloatBuffer lightDifBfr;
|
||||
FloatBuffer lightPosBfr;
|
||||
|
||||
private IntBuffer texturesBuffer;
|
||||
|
||||
private float xRot;
|
||||
private float yRot;
|
||||
float xSpeed = 0.2f;
|
||||
float ySpeed = 0.2f;
|
||||
|
||||
void setup() {
|
||||
size(480, 800, P3D);
|
||||
orientation(PORTRAIT);
|
||||
|
||||
int SIZEOF_FLOAT = Float.SIZE / 8;
|
||||
|
||||
cubeVertexBfr = new FloatBuffer[6];
|
||||
cubeNormalBfr = new FloatBuffer[6];
|
||||
cubeTextureBfr = new FloatBuffer[6];
|
||||
for (int i = 0; i < 6; i++) {
|
||||
ByteBuffer vbb = ByteBuffer.allocateDirect(4 * 3 * SIZEOF_FLOAT);
|
||||
vbb.order(ByteOrder.nativeOrder());
|
||||
cubeVertexBfr[i] = vbb.asFloatBuffer();
|
||||
cubeVertexBfr[i].put(cubeVertexCoords[i]);
|
||||
cubeVertexBfr[i].flip();
|
||||
|
||||
ByteBuffer nbb = ByteBuffer.allocateDirect(4 * 3 * SIZEOF_FLOAT);
|
||||
nbb.order(ByteOrder.nativeOrder());
|
||||
cubeNormalBfr[i] = nbb.asFloatBuffer();
|
||||
cubeNormalBfr[i].put(cubeNormalCoords[i]);
|
||||
cubeNormalBfr[i].flip();
|
||||
|
||||
ByteBuffer tbb = ByteBuffer.allocateDirect(4 * 2 * SIZEOF_FLOAT);
|
||||
tbb.order(ByteOrder.nativeOrder());
|
||||
cubeTextureBfr[i] = tbb.asFloatBuffer();
|
||||
cubeTextureBfr[i].put(cubeTextureCoords[i]);
|
||||
cubeTextureBfr[i].flip();
|
||||
}
|
||||
|
||||
lightAmbBfr = FloatBuffer.wrap(lightAmb);
|
||||
lightDifBfr = FloatBuffer.wrap(lightDif);
|
||||
lightPosBfr = FloatBuffer.wrap(lightPos);
|
||||
|
||||
PGraphicsAndroid3D a3d = (PGraphicsAndroid3D)g;
|
||||
GL10 gl = a3d.beginGL();
|
||||
|
||||
texturesBuffer = IntBuffer.allocate(3);
|
||||
a3d.gl.glGenTextures(3, texturesBuffer);
|
||||
|
||||
InputStream stream = createInput("glass.bmp");
|
||||
Bitmap bitmap = BitmapFactory.decodeStream(stream);
|
||||
try {
|
||||
stream.close();
|
||||
stream = null;
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
|
||||
gl.glEnable(GL10.GL_TEXTURE_2D);
|
||||
// setup texture 0 with nearest filtering
|
||||
gl.glBindTexture(GL10.GL_TEXTURE_2D, texturesBuffer.get(0));
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
|
||||
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
|
||||
|
||||
// setup texture 1 with linear filtering for both minification and magnification,
|
||||
// this is usually called bilinear sampling
|
||||
gl.glBindTexture(GL10.GL_TEXTURE_2D, texturesBuffer.get(1));
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
|
||||
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
|
||||
|
||||
// setup texture 2 with linear filtering for magnification and linear-linear mipmapping
|
||||
// (trilinear sampling)
|
||||
gl.glBindTexture(GL10.GL_TEXTURE_2D, texturesBuffer.get(2));
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR_MIPMAP_NEAREST);
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
|
||||
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
|
||||
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
|
||||
gl.glDisable(GL10.GL_TEXTURE_2D);
|
||||
|
||||
a3d.endGL();
|
||||
}
|
||||
|
||||
public void draw() {
|
||||
background(0);
|
||||
|
||||
PGraphicsAndroid3D a3d = (PGraphicsAndroid3D)g;
|
||||
GL10 gl = a3d.beginGL();
|
||||
|
||||
gl.glShadeModel(GL10.GL_SMOOTH);
|
||||
gl.glClearColor(0, 0, 0, 0);
|
||||
|
||||
if (depthTest) {
|
||||
gl.glClearDepthf(1.0f);
|
||||
gl.glEnable(GL10.GL_DEPTH_TEST);
|
||||
gl.glDepthFunc(GL10.GL_LEQUAL);
|
||||
}
|
||||
else {
|
||||
gl.glDisable(GL10.GL_DEPTH_TEST);
|
||||
}
|
||||
gl.glDepthMask(depthMask);
|
||||
|
||||
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
|
||||
|
||||
// lighting
|
||||
gl.glEnable(GL10.GL_LIGHT0);
|
||||
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbBfr);
|
||||
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDifBfr);
|
||||
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPosBfr);
|
||||
|
||||
// blending
|
||||
gl.glEnable(GL10.GL_COLOR_MATERIAL);
|
||||
gl.glColor4f(1.0f, 1.0f, 1.0f, transparency);
|
||||
if (selBlend == 0) {
|
||||
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
|
||||
}
|
||||
else if (selBlend == 1) {
|
||||
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
gl.glViewport(0, 0, width, height);
|
||||
// setup projection matrix
|
||||
gl.glMatrixMode(GL10.GL_PROJECTION);
|
||||
gl.glLoadIdentity();
|
||||
GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 1.0f, 100.0f);
|
||||
|
||||
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
|
||||
gl.glMatrixMode(GL10.GL_MODELVIEW);
|
||||
gl.glLoadIdentity();
|
||||
|
||||
// update lighting
|
||||
if (lighting) {
|
||||
gl.glEnable(GL10.GL_LIGHTING);
|
||||
}
|
||||
else {
|
||||
gl.glDisable(GL10.GL_LIGHTING);
|
||||
}
|
||||
|
||||
// update blending
|
||||
if (blending) {
|
||||
gl.glEnable(GL10.GL_BLEND);
|
||||
gl.glDisable(GL10.GL_CULL_FACE);
|
||||
}
|
||||
else {
|
||||
gl.glDisable(GL10.GL_BLEND);
|
||||
gl.glEnable(GL10.GL_CULL_FACE);
|
||||
}
|
||||
|
||||
gl.glTranslatef(0, 0, -6);
|
||||
gl.glRotatef(xRot, 1, 0, 0);
|
||||
gl.glRotatef(yRot, 0, 1, 0);
|
||||
|
||||
if (texturing) {
|
||||
gl.glEnable(GL10.GL_TEXTURE_2D);
|
||||
gl.glBindTexture(GL10.GL_TEXTURE_2D, texturesBuffer.get(selFilter));
|
||||
}
|
||||
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
|
||||
if (texturing) gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
|
||||
for (int i = 0; i < 6; i++) // draw each face
|
||||
{
|
||||
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeVertexBfr[i]);
|
||||
if (texturing) gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, cubeTextureBfr[i]);
|
||||
gl.glNormalPointer(GL10.GL_FLOAT, 0, cubeNormalBfr[i]);
|
||||
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
|
||||
if (texturing) {
|
||||
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
|
||||
gl.glDisable(GL10.GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
// update rotations
|
||||
xRot += xSpeed;
|
||||
yRot += ySpeed;
|
||||
|
||||
a3d.endGL();
|
||||
}
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
float[][] cubeVertexCoords = new float[][] {
|
||||
new float[] { // top
|
||||
1, 1,-1,
|
||||
-1, 1,-1,
|
||||
-1, 1, 1,
|
||||
1, 1, 1
|
||||
}
|
||||
,
|
||||
new float[] { // bottom
|
||||
1,-1, 1,
|
||||
-1,-1, 1,
|
||||
-1,-1,-1,
|
||||
1,-1,-1
|
||||
}
|
||||
,
|
||||
new float[] { // front
|
||||
1, 1, 1,
|
||||
-1, 1, 1,
|
||||
-1,-1, 1,
|
||||
1,-1, 1
|
||||
}
|
||||
,
|
||||
new float[] { // back
|
||||
1,-1,-1,
|
||||
-1,-1,-1,
|
||||
-1, 1,-1,
|
||||
1, 1,-1
|
||||
}
|
||||
,
|
||||
new float[] { // left
|
||||
-1, 1, 1,
|
||||
-1, 1,-1,
|
||||
-1,-1,-1,
|
||||
-1,-1, 1
|
||||
}
|
||||
,
|
||||
new float[] { // right
|
||||
1, 1,-1,
|
||||
1, 1, 1,
|
||||
1,-1, 1,
|
||||
1,-1,-1
|
||||
}
|
||||
,
|
||||
};
|
||||
|
||||
float[][] cubeNormalCoords = new float[][] {
|
||||
new float[] { // top
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 0
|
||||
}
|
||||
,
|
||||
new float[] { // bottom
|
||||
0,-1, 0,
|
||||
0,-1, 0,
|
||||
0,-1, 0,
|
||||
0,-1, 0
|
||||
}
|
||||
,
|
||||
new float[] { // front
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 1,
|
||||
0, 0, 1
|
||||
}
|
||||
,
|
||||
new float[] { // back
|
||||
0, 0,-1,
|
||||
0, 0,-1,
|
||||
0, 0,-1,
|
||||
0, 0,-1
|
||||
}
|
||||
,
|
||||
new float[] { // left
|
||||
-1, 0, 0,
|
||||
-1, 0, 0,
|
||||
-1, 0, 0,
|
||||
-1, 0, 0
|
||||
}
|
||||
,
|
||||
new float[] { // right
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 0, 0
|
||||
}
|
||||
,
|
||||
};
|
||||
|
||||
float[][] cubeTextureCoords = new float[][] {
|
||||
new float[] { // top
|
||||
1, 0,
|
||||
1, 1,
|
||||
0, 1,
|
||||
0, 0
|
||||
}
|
||||
,
|
||||
new float[] { // bottom
|
||||
0, 0,
|
||||
1, 0,
|
||||
1, 1,
|
||||
0, 1
|
||||
}
|
||||
,
|
||||
new float[] { // front
|
||||
1, 1,
|
||||
0, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
}
|
||||
,
|
||||
new float[] { // back
|
||||
0, 1,
|
||||
0, 0,
|
||||
1, 0,
|
||||
1, 1
|
||||
}
|
||||
,
|
||||
new float[] { // left
|
||||
1, 1,
|
||||
0, 1,
|
||||
0, 0,
|
||||
1, 0
|
||||
}
|
||||
,
|
||||
new float[] { // right
|
||||
0, 1,
|
||||
0, 0,
|
||||
1, 0,
|
||||
1, 1
|
||||
}
|
||||
,
|
||||
};
|
||||
|
||||
float lightAmb[]= {
|
||||
0.5f, 0.5f, 0.5f, 1.0f
|
||||
};
|
||||
|
||||
float lightDif[]= {
|
||||
1.0f, 1.0f, 1.0f, 1.0f
|
||||
};
|
||||
|
||||
float lightPos[]= {
|
||||
0.0f, 0.0f, 2.0f, 1.0f
|
||||
};
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 48 KiB |
@@ -1,261 +0,0 @@
|
||||
// Implementation of 1D, 2D, and 3D Perlin noise. Based on the
|
||||
// C code by Paul Bourke:
|
||||
// http://local.wasp.uwa.edu.au/~pbourke/texture_colour/perlin/
|
||||
class Perlin {
|
||||
int B = 0x100;
|
||||
int BM = 0xff;
|
||||
int N = 0x1000;
|
||||
int NP = 12;
|
||||
int NM = 0xfff;
|
||||
|
||||
int p[];
|
||||
float g3[][];
|
||||
float g2[][];
|
||||
float g1[];
|
||||
|
||||
void normalize2(float v[]) {
|
||||
float s = sqrt(v[0] * v[0] + v[1] * v[1]);
|
||||
v[0] = v[0] / s;
|
||||
v[1] = v[1] / s;
|
||||
}
|
||||
|
||||
void normalize3(float v[]) {
|
||||
float s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||
v[0] = v[0] / s;
|
||||
v[1] = v[1] / s;
|
||||
v[2] = v[2] / s;
|
||||
}
|
||||
|
||||
float sCurve(float t) {
|
||||
return t * t * (3.0 - 2.0 * t);
|
||||
}
|
||||
|
||||
float at2(float q[], float rx, float ry) {
|
||||
return rx * q[0] + ry * q[1];
|
||||
}
|
||||
|
||||
float at3(float q[], float rx, float ry, float rz) {
|
||||
return rx * q[0] + ry * q[1] + rz * q[2];
|
||||
}
|
||||
|
||||
Perlin() {
|
||||
p = new int[B + B + 2];
|
||||
g3 = new float[B + B + 2][3];
|
||||
g2 = new float[B + B + 2][2];
|
||||
g1 = new float[B + B + 2];
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
void init() {
|
||||
int i, j, k;
|
||||
|
||||
for (i = 0 ; i < B ; i++) {
|
||||
p[i] = i;
|
||||
g1[i] = (random(B + B) - B) / B;
|
||||
|
||||
for (j = 0 ; j < 2 ; j++)
|
||||
g2[i][j] = (random(B + B) - B) / B;
|
||||
normalize2(g2[i]);
|
||||
|
||||
for (j = 0 ; j < 3 ; j++)
|
||||
g3[i][j] = (random(B + B) - B) / B;
|
||||
normalize3(g3[i]);
|
||||
}
|
||||
|
||||
while (0 < --i) {
|
||||
k = p[i];
|
||||
p[i] = p[j = int(random(B))];
|
||||
p[j] = k;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < B + 2 ; i++) {
|
||||
p[B + i] = p[i];
|
||||
g1[B + i] = g1[i];
|
||||
for (j = 0 ; j < 2 ; j++)
|
||||
g2[B + i][j] = g2[i][j];
|
||||
for (j = 0 ; j < 3 ; j++)
|
||||
g3[B + i][j] = g3[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
float noise1(float[] vec) {
|
||||
int bx0, bx1;
|
||||
float rx0, rx1, sx, t, u, v;
|
||||
|
||||
t = vec[0] + N;
|
||||
bx0 = int(t) & BM;
|
||||
bx1 = (bx0 + 1) & BM;
|
||||
rx0 = t - int(t);
|
||||
rx1 = rx0 - 1.0;
|
||||
|
||||
sx = sCurve(rx0);
|
||||
u = rx0 * g1[p[bx0]];
|
||||
v = rx1 * g1[p[bx1]];
|
||||
|
||||
return lerp(u, v, sx);
|
||||
}
|
||||
|
||||
float noise2(float[] vec) {
|
||||
int bx0, bx1, by0, by1, b00, b10, b01, b11;
|
||||
float rx0, rx1, ry0, ry1, sx, sy, a, b, t, u, v;
|
||||
float[] q;
|
||||
int i, j;
|
||||
|
||||
t = vec[0] + N;
|
||||
bx0 = int(t) & BM;
|
||||
bx1 = (bx0 + 1) & BM;
|
||||
rx0 = t - int(t);
|
||||
rx1 = rx0 - 1.0;
|
||||
|
||||
t = vec[1] + N;
|
||||
by0 = int(t) & BM;
|
||||
by1 = (by0 + 1) & BM;
|
||||
ry0 = t - int(t);
|
||||
ry1 = ry0 - 1.0;
|
||||
|
||||
i = p[bx0];
|
||||
j = p[bx1];
|
||||
|
||||
b00 = p[i + by0];
|
||||
b10 = p[j + by0];
|
||||
b01 = p[i + by1];
|
||||
b11 = p[j + by1];
|
||||
|
||||
sx = sCurve(rx0);
|
||||
sy = sCurve(ry0);
|
||||
|
||||
q = g2[b00];
|
||||
u = at2(q, rx0, ry0);
|
||||
q = g2[b10];
|
||||
v = at2(q, rx1, ry0);
|
||||
a = lerp(u, v, sx);
|
||||
|
||||
q = g2[b01] ;
|
||||
u = at2(q, rx0, ry1);
|
||||
q = g2[b11] ;
|
||||
v = at2(q, rx1, ry1);
|
||||
b = lerp(u, v, sx);
|
||||
|
||||
return lerp(a, b, sy);
|
||||
}
|
||||
|
||||
float noise3(float[] vec) {
|
||||
int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
|
||||
float rx0, rx1, ry0, ry1, rz0, rz1, sy, sz, a, b, c, d, t, u, v;
|
||||
float[] q;
|
||||
int i, j;
|
||||
|
||||
t = vec[0] + N;
|
||||
bx0 = int(t) & BM;
|
||||
bx1 = (bx0 + 1) & BM;
|
||||
rx0 = t - int(t);
|
||||
rx1 = rx0 - 1.0;
|
||||
|
||||
t = vec[1] + N;
|
||||
by0 = int(t) & BM;
|
||||
by1 = (by0 + 1) & BM;
|
||||
ry0 = t - int(t);
|
||||
ry1 = ry0 - 1.0;
|
||||
|
||||
t = vec[2] + N;
|
||||
bz0 = int(t) & BM;
|
||||
bz1 = (bz0 + 1) & BM;
|
||||
rz0 = t - int(t);
|
||||
rz1 = rz0 - 1.0;
|
||||
|
||||
i = p[bx0];
|
||||
j = p[bx1];
|
||||
|
||||
b00 = p[i + by0];
|
||||
b10 = p[j + by0];
|
||||
b01 = p[i + by1];
|
||||
b11 = p[j + by1];
|
||||
|
||||
t = sCurve(rx0);
|
||||
sy = sCurve(ry0);
|
||||
sz = sCurve(rz0);
|
||||
|
||||
q = g3[b00 + bz0];
|
||||
u = at3(q, rx0, ry0, rz0);
|
||||
q = g3[b10 + bz0];
|
||||
v = at3(q, rx1, ry0, rz0);
|
||||
a = lerp(u, v, t);
|
||||
|
||||
q = g3[b01 + bz0];
|
||||
u = at3(q, rx0, ry1, rz0);
|
||||
q = g3[b11 + bz0];
|
||||
v = at3(q, rx1, ry1, rz0);
|
||||
b = lerp(u, v, t);
|
||||
|
||||
c = lerp(a, b, sy);
|
||||
|
||||
q = g3[b00 + bz1];
|
||||
u = at3(q, rx0, ry0, rz1);
|
||||
q = g3[b10 + bz1];
|
||||
v = at3(q, rx1, ry0, rz1);
|
||||
a = lerp(u, v, t);
|
||||
|
||||
q = g3[b01 + bz1];
|
||||
u = at3(q, rx0, ry1, rz1);
|
||||
q = g3[b11 + bz1];
|
||||
v = at3(q, rx1, ry1, rz1);
|
||||
b = lerp(u, v, t);
|
||||
|
||||
d = lerp(a, b, sy);
|
||||
|
||||
return lerp(c, d, sz);
|
||||
}
|
||||
|
||||
// In what follows "nalpha" is the weight when the sum is formed.
|
||||
// Typically it is 2, as this approaches 1 the function is noisier.
|
||||
// "nbeta" is the harmonic scaling/spacing, typically 2. n is the
|
||||
// number of harmonics added up in the final result. Higher number
|
||||
// results in more detailed noise.
|
||||
|
||||
float noise1D(float x, float nalpha, float nbeta, int n) {
|
||||
float val, sum = 0;
|
||||
float v[] = {x};
|
||||
float nscale = 1;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
val = noise1(v);
|
||||
sum += val / nscale;
|
||||
nscale *= nalpha;
|
||||
v[0] *= nbeta;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
float noise2D(float x, float y, float nalpha, float nbeta, int n) {
|
||||
float val,sum = 0;
|
||||
float v[] = {x, y};
|
||||
float nscale = 1;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
val = noise2(v);
|
||||
sum += val / nscale;
|
||||
nscale *= nalpha;
|
||||
v[0] *= nbeta;
|
||||
v[1] *= nbeta;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
float noise3D(float x, float y, float z, float nalpha, float nbeta, int n) {
|
||||
float val, sum = 0;
|
||||
float v[] = {x, y, z};
|
||||
float nscale = 1;
|
||||
|
||||
for (int i = 0 ; i < n; i++) {
|
||||
val = noise3(v);
|
||||
sum += val / nscale;
|
||||
nscale *= nalpha;
|
||||
v[0] *= nbeta;
|
||||
v[1] *= nbeta;
|
||||
v[2] *= nbeta;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
// Planets, by Andres Colubri
|
||||
// This example uses the beginRecord/endRecord method to save
|
||||
// an entire shape geometry into a PShape3D object for faster
|
||||
// drawing. It also demonstrates mulitexturing and displacement
|
||||
// of texture coordinates
|
||||
// Sun and mercury textures from http://planetpixelemporium.com
|
||||
// Star field picture from http://www.galacticimages.com/
|
||||
|
||||
PImage starfield;
|
||||
|
||||
PShape sun;
|
||||
PImage suntex;
|
||||
|
||||
PShape planet1;
|
||||
PImage surftex1;
|
||||
PImage cloudtex;
|
||||
|
||||
PShape planet2;
|
||||
PImage surftex2;
|
||||
|
||||
void setup() {
|
||||
size(480, 800, P3D);
|
||||
orientation(PORTRAIT);
|
||||
|
||||
starfield = loadImage("starfield.jpg");
|
||||
suntex = loadImage("sun.jpg");
|
||||
surftex1 = loadImage("planet.jpg");
|
||||
|
||||
// We need trilinear sampling for this texture so it looks good
|
||||
// even when rendered very small.
|
||||
PTexture.Parameters params1 = PTexture.newParameters(ARGB, TRILINEAR);
|
||||
surftex2 = loadImage("mercury.jpg", params1);
|
||||
|
||||
// The clouds texture will "move" having the values of its u
|
||||
// texture coordinates displaced by adding a constant increment
|
||||
// in each frame. This requires REPEAT wrapping mode so texture
|
||||
// coordinates can be larger than 1.
|
||||
PTexture.Parameters params2 = PTexture.newParameters();
|
||||
params2.wrapU = REPEAT;
|
||||
cloudtex = createImage(512, 256, ARGB, params2);
|
||||
|
||||
// Using 3D Perlin noise to generate a clouds texture that is seamless on
|
||||
// its edges so it can be applied on a sphere.
|
||||
println("Generating clouds texture. It takes some time, please wait...");
|
||||
cloudtex.loadPixels();
|
||||
Perlin perlin = new Perlin();
|
||||
for (int j = 0; j < cloudtex.height; j++) {
|
||||
for (int i = 0; i < cloudtex.width; i++) {
|
||||
// The angle values corresponding to each u,v pair:
|
||||
float u = float(i) / cloudtex.width;
|
||||
float v = float(j) / cloudtex.height;
|
||||
float phi = map(u, 0, 1, TWO_PI, 0);
|
||||
float theta = map(v, 0, 1, -HALF_PI, HALF_PI);
|
||||
// The x, y, z point corresponding to these angles:
|
||||
float x = cos(phi) * cos(theta);
|
||||
float y = sin(theta);
|
||||
float z = sin(phi) * cos(theta);
|
||||
float n = perlin.noise3D(x, y, z, 1.2, 2, 8);
|
||||
cloudtex.pixels[j * cloudtex.width + i] = color(255, 255, 255, 255 * n * n);
|
||||
}
|
||||
}
|
||||
cloudtex.updatePixels();
|
||||
println("Done.");
|
||||
|
||||
textureMode(NORMAL);
|
||||
noStroke();
|
||||
fill(255);
|
||||
|
||||
sun = beginRecord();
|
||||
drawSphere(150, 20, suntex, null);
|
||||
endRecord();
|
||||
|
||||
planet1 = beginRecord();
|
||||
drawSphere(150, 20, surftex1, cloudtex);
|
||||
endRecord();
|
||||
|
||||
planet2 = beginRecord();
|
||||
drawSphere(50, 15, surftex2, null);
|
||||
endRecord();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
// Even we draw a full screen image after this, it is recommended to use
|
||||
// background to clear the screen anyways, otherwise A3D will think
|
||||
// you want to keep each drawn frame in the framebuffer, which results in
|
||||
// slower rendering.
|
||||
background(0);
|
||||
|
||||
// Disabling writing to the depth mask so the
|
||||
// background image doesn't occludes any 3D object.
|
||||
hint(DISABLE_DEPTH_MASK);
|
||||
image(starfield, 0, 0, width, height);
|
||||
hint(ENABLE_DEPTH_MASK);
|
||||
|
||||
// Displacing the u texture coordinate of layer 1 in planet
|
||||
// so it creates the effect of moving clouds.
|
||||
PShape3D p = (PShape3D)planet1;
|
||||
p.loadTexcoords(1);
|
||||
for (int i = 0; i < p.getVertexCount(); i++) {
|
||||
float u = p.texcoords[2 * i + 0];
|
||||
u += 0.002;
|
||||
p.texcoords[2 * i + 0] = u;
|
||||
}
|
||||
p.updateTexcoords();
|
||||
|
||||
pushMatrix();
|
||||
translate(width/2, height/2, -100);
|
||||
|
||||
pushMatrix();
|
||||
rotateY(PI * frameCount / 500);
|
||||
shape(sun);
|
||||
popMatrix();
|
||||
|
||||
pointLight(255, 255, 255, 0, 0, 0);
|
||||
rotateY(PI * frameCount / 300);
|
||||
translate(0, 0, 300);
|
||||
|
||||
shape(planet2);
|
||||
|
||||
popMatrix();
|
||||
|
||||
noLights();
|
||||
pointLight(255, 255, 255, 0, 0, 100);
|
||||
|
||||
translate(0.75 * width, 0.6 * height, 350);
|
||||
shape(planet1);
|
||||
}
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
// Just draws an sphere of the given radius and resolutoin, using up to
|
||||
// two images for texturing.
|
||||
void drawSphere(float r, int n, PImage tex0, PImage tex1) {
|
||||
float startLat = -90;
|
||||
float startLon = 0.0;
|
||||
|
||||
float latInc = 180.0 / n;
|
||||
float lonInc = 360.0 / n;
|
||||
|
||||
float u, v;
|
||||
float phi1, phi2;
|
||||
float theta1, theta2;
|
||||
PVector p0 = new PVector();
|
||||
PVector p1 = new PVector();
|
||||
PVector p2 = new PVector();
|
||||
beginShape(TRIANGLES);
|
||||
if (tex1 != null) {
|
||||
texture(tex0, tex1);
|
||||
} else {
|
||||
texture(tex0);
|
||||
}
|
||||
|
||||
for (int col = 0; col < n; col++) {
|
||||
phi1 = (startLon + col * lonInc) * DEG_TO_RAD;
|
||||
phi2 = (startLon + (col + 1) * lonInc) * DEG_TO_RAD;
|
||||
for (int row = 0; row < n; row++) {
|
||||
theta1 = (startLat + row * latInc) * DEG_TO_RAD;
|
||||
theta2 = (startLat + (row + 1) * latInc) * DEG_TO_RAD;
|
||||
|
||||
p0.x = cos(phi1) * cos(theta1);
|
||||
p0.y = sin(theta1);
|
||||
p0.z = sin(phi1) * cos(theta1);
|
||||
|
||||
p1.x = cos(phi1) * cos(theta2);
|
||||
p1.y = sin(theta2);
|
||||
p1.z = sin(phi1) * cos(theta2);
|
||||
|
||||
p2.x = cos(phi2) * cos(theta2);
|
||||
p2.y = sin(theta2);
|
||||
p2.z = sin(phi2) * cos(theta2);
|
||||
|
||||
normal(p0.x, p0.y, p0.z);
|
||||
u = map(phi1, TWO_PI, 0, 0, 1);
|
||||
v = map(theta1, -HALF_PI, HALF_PI, 0, 1);
|
||||
vertex(r * p0.x, r * p0.y, r * p0.z, u, v);
|
||||
|
||||
normal(p1.x, p1.y, p1.z);
|
||||
u = map(phi1, TWO_PI, 0, 0, 1);
|
||||
v = map(theta2, -HALF_PI, HALF_PI, 0, 1);
|
||||
vertex(r * p1.x, r * p1.y, r * p1.z, u, v);
|
||||
|
||||
normal(p2.x, p2.y, p2.z);
|
||||
u = map(phi2, TWO_PI, 0, 0, 1);
|
||||
v = map(theta2, -HALF_PI, HALF_PI, 0, 1);
|
||||
vertex(r * p2.x, r * p2.y, r * p2.z, u, v);
|
||||
|
||||
p1.x = cos(phi2) * cos(theta1);
|
||||
p1.y = sin(theta1);
|
||||
p1.z = sin(phi2) * cos(theta1);
|
||||
|
||||
normal(p0.x, p0.y, p0.z);
|
||||
u = map(phi1, TWO_PI, 0, 0, 1);
|
||||
v = map(theta1, -HALF_PI, HALF_PI, 0, 1);
|
||||
vertex(r * p0.x, r * p0.y, r * p0.z, u, v);
|
||||
|
||||
normal(p2.x, p2.y, p2.z);
|
||||
u = map(phi2, TWO_PI, 0, 0, 1);
|
||||
v = map(theta2, -HALF_PI, HALF_PI, 0, 1);
|
||||
vertex(r * p2.x, r * p2.y, r * p2.z, u, v);
|
||||
|
||||
normal(p1.x, p1.y, p1.z);
|
||||
u = map(phi2, TWO_PI, 0, 0, 1);
|
||||
v = map(theta1, -HALF_PI, HALF_PI, 0, 1);
|
||||
vertex(r * p1.x, r * p1.y, r * p1.z, u, v);
|
||||
}
|
||||
}
|
||||
|
||||
endShape();
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
// Ariel and V3ga's arcball class with a couple tiny mods by Robert Hodgin
|
||||
|
||||
class Arcball{
|
||||
float center_x, center_y, radius;
|
||||
Vec3 v_down, v_drag;
|
||||
Quat q_now, q_down, q_drag;
|
||||
Vec3[] axisSet;
|
||||
int axis;
|
||||
float mxv, myv;
|
||||
float x, y;
|
||||
|
||||
Arcball(float center_x, float center_y, float radius){
|
||||
this.center_x = center_x;
|
||||
this.center_y = center_y;
|
||||
this.radius = radius;
|
||||
|
||||
v_down = new Vec3();
|
||||
v_drag = new Vec3();
|
||||
|
||||
q_now = new Quat();
|
||||
q_down = new Quat();
|
||||
q_drag = new Quat();
|
||||
|
||||
axisSet = new Vec3[] {new Vec3(1.0f, 0.0f, 0.0f), new Vec3(0.0f, 1.0f, 0.0f), new Vec3(0.0f, 0.0f, 1.0f)};
|
||||
axis = -1; // no constraints...
|
||||
}
|
||||
|
||||
void mousePressed(){
|
||||
v_down = mouse_to_sphere(mouseX, mouseY);
|
||||
q_down.set(q_now);
|
||||
q_drag.reset();
|
||||
}
|
||||
|
||||
void mouseDragged(){
|
||||
v_drag = mouse_to_sphere(mouseX, mouseY);
|
||||
q_drag.set(Vec3.dot(v_down, v_drag), Vec3.cross(v_down, v_drag));
|
||||
}
|
||||
|
||||
void run(){
|
||||
|
||||
q_now = Quat.mul(q_drag, q_down);
|
||||
applyQuat2Matrix(q_now);
|
||||
|
||||
x += mxv;
|
||||
y += myv;
|
||||
mxv -= mxv * .01;
|
||||
myv -= myv * .01;
|
||||
}
|
||||
|
||||
Vec3 mouse_to_sphere(float x, float y){
|
||||
Vec3 v = new Vec3();
|
||||
v.x = (x - center_x) / radius;
|
||||
v.y = (y - center_y) / radius;
|
||||
|
||||
float mag = v.x * v.x + v.y * v.y;
|
||||
if (mag > 1.0f){
|
||||
v.normalize();
|
||||
} else {
|
||||
v.z = sqrt(1.0f - mag);
|
||||
}
|
||||
|
||||
return (axis == -1) ? v : constrain_vector(v, axisSet[axis]);
|
||||
}
|
||||
|
||||
Vec3 constrain_vector(Vec3 vector, Vec3 axis){
|
||||
Vec3 res = new Vec3();
|
||||
res.sub(vector, Vec3.mul(axis, Vec3.dot(axis, vector)));
|
||||
res.normalize();
|
||||
return res;
|
||||
}
|
||||
|
||||
void applyQuat2Matrix(Quat q){
|
||||
// instead of transforming q into a matrix and applying it...
|
||||
|
||||
float[] aa = q.getValue();
|
||||
rotate(aa[0], aa[1], aa[2], aa[3]);
|
||||
}
|
||||
}
|
||||
|
||||
static class Vec3{
|
||||
float x, y, z;
|
||||
|
||||
Vec3(){
|
||||
}
|
||||
|
||||
Vec3(float x, float y, float z){
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
void normalize(){
|
||||
float length = length();
|
||||
x /= length;
|
||||
y /= length;
|
||||
z /= length;
|
||||
}
|
||||
|
||||
float length(){
|
||||
return (float) Math.sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
static Vec3 cross(Vec3 v1, Vec3 v2){
|
||||
Vec3 res = new Vec3();
|
||||
res.x = v1.y * v2.z - v1.z * v2.y;
|
||||
res.y = v1.z * v2.x - v1.x * v2.z;
|
||||
res.z = v1.x * v2.y - v1.y * v2.x;
|
||||
return res;
|
||||
}
|
||||
|
||||
static float dot(Vec3 v1, Vec3 v2){
|
||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
|
||||
}
|
||||
|
||||
static Vec3 mul(Vec3 v, float d){
|
||||
Vec3 res = new Vec3();
|
||||
res.x = v.x * d;
|
||||
res.y = v.y * d;
|
||||
res.z = v.z * d;
|
||||
return res;
|
||||
}
|
||||
|
||||
void sub(Vec3 v1, Vec3 v2){
|
||||
x = v1.x - v2.x;
|
||||
y = v1.y - v2.y;
|
||||
z = v1.z - v2.z;
|
||||
}
|
||||
}
|
||||
|
||||
static class Quat{
|
||||
float w, x, y, z;
|
||||
|
||||
Quat(){
|
||||
reset();
|
||||
}
|
||||
|
||||
Quat(float w, float x, float y, float z){
|
||||
this.w = w;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
void reset(){
|
||||
w = 1.0f;
|
||||
x = 0.0f;
|
||||
y = 0.0f;
|
||||
z = 0.0f;
|
||||
}
|
||||
|
||||
void set(float w, Vec3 v){
|
||||
this.w = w;
|
||||
x = v.x;
|
||||
y = v.y;
|
||||
z = v.z;
|
||||
}
|
||||
|
||||
void set(Quat q){
|
||||
w = q.w;
|
||||
x = q.x;
|
||||
y = q.y;
|
||||
z = q.z;
|
||||
}
|
||||
|
||||
static Quat mul(Quat q1, Quat q2){
|
||||
Quat res = new Quat();
|
||||
res.w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z;
|
||||
res.x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y;
|
||||
res.y = q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z;
|
||||
res.z = q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x;
|
||||
return res;
|
||||
}
|
||||
|
||||
float[] getValue(){
|
||||
// transforming this quat into an angle and an axis vector...
|
||||
|
||||
float[] res = new float[4];
|
||||
|
||||
float sa = (float) Math.sqrt(1.0f - w * w);
|
||||
if (sa < EPSILON){
|
||||
sa = 1.0f;
|
||||
}
|
||||
|
||||
res[0] = (float) Math.acos(w) * 2.0f;
|
||||
res[1] = x / sa;
|
||||
res[2] = y / sa;
|
||||
res[3] = z / sa;
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -1,301 +0,0 @@
|
||||
final int MAX_BEZIER_ORDER = 10; // Maximum curve order.
|
||||
|
||||
final float[][] BSplineMatrix = {
|
||||
{-1.0/6.0, 1.0/2.0, -1.0/2.0, 1.0/6.0},
|
||||
{ 1.0/2.0, -1.0, 1.0/2.0, 0.0},
|
||||
{-1.0/2.0, 0.0, 1.0/2.0, 0.0},
|
||||
{ 1.0/6.0, 2.0/3.0, 1.0/6.0, 0.0}
|
||||
};
|
||||
|
||||
// The element(i, n) of this array contains the binomial coefficient
|
||||
// C(i, n) = n!/(i!(n-i)!)
|
||||
final int[][] BinomialCoefTable = {
|
||||
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
{0, 1, 3, 6, 10, 15, 21, 28, 36, 45},
|
||||
{0, 0, 1, 4, 10, 20, 35, 56, 84, 120},
|
||||
{0, 0, 0, 1, 5, 15, 35, 70, 126, 210},
|
||||
{0, 0, 0, 0, 1, 6, 21, 56, 126, 252},
|
||||
{0, 0, 0, 0, 0, 1, 7, 28, 84, 210},
|
||||
{0, 0, 0, 0, 0, 0, 1, 8, 36, 120},
|
||||
{0, 0, 0, 0, 0, 0, 0, 1, 9, 45},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 1, 10},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
|
||||
};
|
||||
|
||||
// The element of this(i, j) of this table contains(i/10)^(3-j).
|
||||
final float[][] TVectorTable = {
|
||||
// t^3, t^2, t^1, t^0
|
||||
{ 0, 0, 0, 1}, // t = 0.0
|
||||
{0.001, 0.01, 0.1, 1}, // t = 0.1
|
||||
{0.008, 0.04, 0.2, 1}, // t = 0.2
|
||||
{0.027, 0.09, 0.3, 1}, // t = 0.3
|
||||
{0.064, 0.16, 0.4, 1}, // t = 0.4
|
||||
{0.125, 0.25, 0.5, 1}, // t = 0.5
|
||||
{0.216, 0.36, 0.6, 1}, // t = 0.6
|
||||
{0.343, 0.49, 0.7, 1}, // t = 0.7
|
||||
{0.512, 0.64, 0.8, 1}, // u = 0.8
|
||||
{0.729, 0.81, 0.9, 1}, // t = 0.9
|
||||
{ 1, 1, 1, 1} // t = 1.0
|
||||
};
|
||||
|
||||
// The element of this(i, j) of this table contains(3-j)*(i/10)^(2-j) if
|
||||
// j < 3, 0 otherwise.
|
||||
final float[][] DTVectorTable = {
|
||||
// 3t^2, 2t^1, t^0
|
||||
{ 0, 0, 1, 0}, // t = 0.0
|
||||
{0.03, 0.2, 1, 0}, // t = 0.1
|
||||
{0.12, 0.4, 1, 0}, // t = 0.2
|
||||
{0.27, 0.6, 1, 0}, // t = 0.3
|
||||
{0.48, 0.8, 1, 0}, // t = 0.4
|
||||
{0.75, 1.0, 1, 0}, // t = 0.5
|
||||
{1.08, 1.2, 1, 0}, // t = 0.6
|
||||
{1.47, 1.4, 1, 0}, // t = 0.7
|
||||
{1.92, 1.6, 1, 0}, // t = 0.8
|
||||
{2.43, 1.8, 1, 0}, // t = 0.9
|
||||
{ 3, 2, 1, 0} // t = 1.0
|
||||
};
|
||||
|
||||
abstract class Curve3D {
|
||||
abstract void feval(float t, PVector p);
|
||||
abstract void deval(float t, PVector d);
|
||||
|
||||
abstract float fevalX(float t);
|
||||
abstract float fevalY(float t);
|
||||
abstract float fevalZ(float t);
|
||||
|
||||
abstract float devalX(float t);
|
||||
abstract float devalY(float t);
|
||||
abstract float devalZ(float t);
|
||||
}
|
||||
|
||||
abstract class Spline extends Curve3D {
|
||||
// The factorial of n.
|
||||
int factorial(int n) {
|
||||
return n <= 0 ? 1 : n * factorial(n - 1);
|
||||
}
|
||||
// Gives n!/(i!(n-i)!).
|
||||
int binomialCoef(int i, int n) {
|
||||
if ((i <= MAX_BEZIER_ORDER) &&(n <= MAX_BEZIER_ORDER)) return BinomialCoefTable[i][n - 1];
|
||||
else return int(factorial(n) /(factorial(i) * factorial(n - i)));
|
||||
}
|
||||
// Evaluates the Berstein polinomial(i, n) at u.
|
||||
float bersteinPol(int i, int n, float u) {
|
||||
return binomialCoef(i, n) * pow(u, i) * pow(1 - u, n - i);
|
||||
}
|
||||
// The derivative of the Berstein polinomial.
|
||||
float dbersteinPol(int i, int n, float u) {
|
||||
float s1, s2;
|
||||
if (i == 0) s1 = 0;
|
||||
else s1 = i * pow(u, i-1) * pow(1 - u, n - i);
|
||||
if (n == i) s2 = 0;
|
||||
else s2 = -(n - i) * pow(u, i) * pow(1 - u, n - i - 1);
|
||||
return binomialCoef(i, n) *(s1 + s2);
|
||||
}
|
||||
}
|
||||
|
||||
class BSpline extends Spline {
|
||||
BSpline() {
|
||||
initParameters(true);
|
||||
}
|
||||
BSpline(boolean t) {
|
||||
initParameters(t);
|
||||
}
|
||||
|
||||
// Sets lookup table use.
|
||||
void initParameters(boolean t) {
|
||||
bsplineCPoints = new float[4][3];
|
||||
TVector = new float[4];
|
||||
DTVector = new float[4];
|
||||
M3 = new float[4][3];
|
||||
pt = new float[3];
|
||||
tg = new float[3];
|
||||
lookup = t;
|
||||
}
|
||||
// Sets n-th control point.
|
||||
void setCPoint(int n, PVector P) {
|
||||
bsplineCPoints[n][0] = P.x;
|
||||
bsplineCPoints[n][1] = P.y;
|
||||
bsplineCPoints[n][2] = P.z;
|
||||
updateMatrix3();
|
||||
}
|
||||
|
||||
// Gets n-th control point.
|
||||
void getCPoint(int n, PVector P) {
|
||||
P.set(bsplineCPoints[n]);
|
||||
}
|
||||
|
||||
// Replaces the current B-spline control points(0, 1, 2) with(1, 2, 3). This
|
||||
// is used when a new spline is to be joined to the recently drawn.
|
||||
void shiftBSplineCPoints() {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
bsplineCPoints[0][i] = bsplineCPoints[1][i];
|
||||
bsplineCPoints[1][i] = bsplineCPoints[2][i];
|
||||
bsplineCPoints[2][i] = bsplineCPoints[3][i];
|
||||
}
|
||||
updateMatrix3();
|
||||
}
|
||||
|
||||
void copyCPoints(int n_source, int n_dest) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
bsplineCPoints[n_dest][i] = bsplineCPoints[n_source][i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Updates the temporal matrix used in order 3 calculations.
|
||||
void updateMatrix3() {
|
||||
float s;
|
||||
int i, j, k;
|
||||
for(i = 0; i < 4; i++) {
|
||||
for(j = 0; j < 3; j++) {
|
||||
s = 0;
|
||||
for(k = 0; k < 4; k++) s += BSplineMatrix[i][k] * bsplineCPoints[k][j];
|
||||
M3[i][j] = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void feval(float t, PVector p) {
|
||||
evalPoint(t);
|
||||
p.set(pt);
|
||||
}
|
||||
void deval(float t, PVector d) {
|
||||
evalTangent(t);
|
||||
d.set(tg);
|
||||
}
|
||||
|
||||
float fevalX(float t) {
|
||||
evalPoint(t);
|
||||
return pt[0];
|
||||
}
|
||||
float fevalY(float t) {
|
||||
evalPoint(t);
|
||||
return pt[1];
|
||||
}
|
||||
float fevalZ(float t) {
|
||||
evalPoint(t);
|
||||
return pt[2];
|
||||
}
|
||||
|
||||
float devalX(float t) {
|
||||
evalTangent(t);
|
||||
return tg[0];
|
||||
}
|
||||
float devalY(float t) {
|
||||
evalTangent(t);
|
||||
return tg[1];
|
||||
}
|
||||
float devalZ(float t) {
|
||||
evalTangent(t);
|
||||
return tg[2];
|
||||
}
|
||||
|
||||
// Point evaluation.
|
||||
void evalPoint(float t) {
|
||||
if (lookup) {
|
||||
bsplinePointI(int(10 * t));
|
||||
} else {
|
||||
bsplinePoint(t);
|
||||
}
|
||||
}
|
||||
|
||||
// Tangent evaluation.
|
||||
void evalTangent(float t) {
|
||||
if (lookup) {
|
||||
bsplineTangentI(int(10 * t));
|
||||
} else {
|
||||
bsplineTangent(t);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculates the point on the cubic spline corresponding to the parameter value t in [0, 1].
|
||||
void bsplinePoint(float t) {
|
||||
// Q(u) = UVector * BSplineMatrix * BSplineCPoints
|
||||
|
||||
float s;
|
||||
int i, j, k;
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
TVector[i] = pow(t, 3 - i);
|
||||
}
|
||||
|
||||
for(j = 0; j < 3; j++) {
|
||||
s = 0;
|
||||
for(k = 0; k < 4; k++) {
|
||||
s += TVector[k] * M3[k][j];
|
||||
}
|
||||
pt[j] = s;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculates the tangent vector of the spline at t.
|
||||
void bsplineTangent(float t) {
|
||||
// Q(u) = DTVector * BSplineMatrix * BSplineCPoints
|
||||
|
||||
float s;
|
||||
int i, j, k;
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
if (i < 3) {
|
||||
DTVector[i] = (3 - i) * pow(t, 2 - i);
|
||||
} else {
|
||||
DTVector[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for(j = 0; j < 3; j++) {
|
||||
s = 0;
|
||||
for(k = 0; k < 4; k++) {
|
||||
s += DTVector[k] * M3[k][j];
|
||||
}
|
||||
tg[j] = s;
|
||||
}
|
||||
}
|
||||
|
||||
// Gives the point on the cubic spline corresponding to t/10(using the lookup table).
|
||||
void bsplinePointI(int t) {
|
||||
// Q(u) = TVectorTable[u] * BSplineMatrix * BSplineCPoints
|
||||
|
||||
float s;
|
||||
int j, k;
|
||||
|
||||
for(j = 0; j < 3; j++) {
|
||||
s = 0;
|
||||
for(k = 0; k < 4; k++) {
|
||||
s += TVectorTable[t][k] * M3[k][j];
|
||||
}
|
||||
pt[j] = s;
|
||||
}
|
||||
}
|
||||
|
||||
// Calulates the tangent vector of the spline at t/10.
|
||||
void bsplineTangentI(int t) {
|
||||
// Q(u) = DTVectorTable[u] * BSplineMatrix * BSplineCPoints
|
||||
|
||||
float s;
|
||||
int j, k;
|
||||
|
||||
for(j = 0; j < 3; j++) {
|
||||
s = 0;
|
||||
for(k = 0; k < 4; k++) {
|
||||
s += DTVectorTable[t][k] * M3[k][j];
|
||||
}
|
||||
tg[j] = s;
|
||||
}
|
||||
}
|
||||
|
||||
// Control points.
|
||||
float[][] bsplineCPoints;
|
||||
|
||||
// Parameters.
|
||||
boolean lookup;
|
||||
|
||||
// Auxiliary arrays used in the calculations.
|
||||
float[][] M3;
|
||||
float[] TVector, DTVector;
|
||||
|
||||
// Point and tangent vectors.
|
||||
float[] pt, tg;
|
||||
}
|
||||
|
||||
@@ -1,460 +0,0 @@
|
||||
BSpline splineSide1;
|
||||
BSpline splineCenter;
|
||||
BSpline splineSide2;
|
||||
PVector flipTestV;
|
||||
int uspacing;
|
||||
|
||||
int HELIX = 0;
|
||||
int STRAND = 1;
|
||||
int COIL = 2;
|
||||
int LHANDED = -1;
|
||||
int RHANDED = 1;
|
||||
|
||||
void createRibbonModel(ArrayList residues, PShape3D model, ArrayList trj) {
|
||||
ArrayList vertices;
|
||||
ArrayList normals;
|
||||
vertices = new ArrayList();
|
||||
normals = new ArrayList();
|
||||
|
||||
if (ribbonDetail == 1) uspacing = 10;
|
||||
else if (ribbonDetail == 2) uspacing = 5;
|
||||
else if (ribbonDetail == 3) uspacing = 2;
|
||||
else uspacing = 1;
|
||||
|
||||
flipTestV = new PVector();
|
||||
splineSide1 = new BSpline(false);
|
||||
splineCenter = new BSpline(false);
|
||||
splineSide2 = new BSpline(false);
|
||||
|
||||
int[] ss = new int[residues.size()];
|
||||
int[] handness = new int[residues.size()];
|
||||
|
||||
calculateSecStr(residues, ss, handness);
|
||||
|
||||
for (int i = 0; i < residues.size(); i++) {
|
||||
constructControlPoints(residues, i, ss[i], handness[i]);
|
||||
|
||||
if (renderMode == 0) {
|
||||
generateSpline(0, vertices);
|
||||
generateSpline(1, vertices);
|
||||
generateSpline(2, vertices);
|
||||
}
|
||||
else generateFlatRibbon(vertices, normals);
|
||||
}
|
||||
|
||||
if (renderMode == 0) {
|
||||
PShape3D.Parameters params = PShape3D.newParameters(LINES, STATIC);
|
||||
model = (PShape3D)createShape(vertices.size(), params);
|
||||
model.setVertices(vertices);
|
||||
} else {
|
||||
PShape3D.Parameters params = PShape3D.newParameters(TRIANGLES, STATIC);
|
||||
model = (PShape3D)createShape(vertices.size(), params);
|
||||
model.setVertices(vertices);
|
||||
model.setNormals(normals);
|
||||
}
|
||||
model.setColor(ribbonColor);
|
||||
|
||||
trj.add(model);
|
||||
|
||||
println("Adding new model with " + vertices.size() + " vertices.");
|
||||
}
|
||||
|
||||
float calculateGyrRadius(ArrayList atoms) {
|
||||
PVector ati, atj;
|
||||
float dx, dy, dz;
|
||||
float r = 0;
|
||||
for (int i = 0; i < atoms.size(); i++) {
|
||||
ati = (PVector)atoms.get(i);
|
||||
for (int j = i + 1; j < atoms.size(); j++) {
|
||||
atj = (PVector)atoms.get(j);
|
||||
|
||||
dx = ati.x - atj.x;
|
||||
dy = ati.y - atj.y;
|
||||
dz = ati.z - atj.z;
|
||||
r += dx * dx + dy * dy + dz * dz;
|
||||
}
|
||||
}
|
||||
return sqrt(r) / (atoms.size() + 1);
|
||||
}
|
||||
|
||||
// Does a cheap and dirty secondary structure assignment to the protein
|
||||
// residues given in the array.
|
||||
void calculateSecStr(ArrayList residues, int[] ss, int[] handness) {
|
||||
PVector c0, n1, ca1, c1, n2;
|
||||
HashMap res0, res1, res2;
|
||||
int n = residues.size();
|
||||
|
||||
float[] phi = new float[n];
|
||||
float[] psi = new float[n];
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i == 0 || i == n - 1) {
|
||||
phi[i] = 90;
|
||||
psi[i] = 90;
|
||||
} else {
|
||||
res0 = (HashMap)residues.get(i - 1);
|
||||
res1 = (HashMap)residues.get(i);
|
||||
res2 = (HashMap)residues.get(i + 1);
|
||||
|
||||
c0 = (PVector)res0.get("C");
|
||||
n1 = (PVector)res1.get("N");
|
||||
ca1 = (PVector)res1.get("CA");
|
||||
c1 = (PVector)res1.get("C");
|
||||
n2 = (PVector)res2.get("N");
|
||||
|
||||
phi[i] = calculateTorsionalAngle(c0, n1, ca1, c1);
|
||||
psi[i] = calculateTorsionalAngle(n1, ca1, c1, n2);
|
||||
}
|
||||
}
|
||||
|
||||
int firstHelix = 0;
|
||||
int nconsRHelix = 0;
|
||||
int nconsLHelix = 0;
|
||||
int firstStrand = 0;
|
||||
int nconsStrand = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
// Right-handed helix
|
||||
if ((dist(phi[i], psi[i], -60, -45) < 30) && (i < n - 1)) {
|
||||
if (nconsRHelix == 0) firstHelix = i;
|
||||
nconsRHelix++;
|
||||
}
|
||||
else {
|
||||
if (3 <= nconsRHelix) {
|
||||
for (int k = firstHelix; k < i; k++) {
|
||||
ss[k] = HELIX;
|
||||
handness[k] = RHANDED;
|
||||
}
|
||||
}
|
||||
nconsRHelix = 0;
|
||||
}
|
||||
|
||||
// Left-handed helix
|
||||
if ((dist(phi[i], psi[i], +60, +45) < 30) && (i < n - 1)) {
|
||||
if (nconsLHelix == 0) firstHelix = i;
|
||||
nconsLHelix++;
|
||||
|
||||
} else {
|
||||
if (3 <= nconsLHelix) {
|
||||
for (int k = firstHelix; k < i; k++) {
|
||||
ss[k] = HELIX;
|
||||
handness[k] = LHANDED;
|
||||
}
|
||||
}
|
||||
nconsLHelix = 0;
|
||||
}
|
||||
|
||||
// Strand
|
||||
if ((dist(phi[i], psi[i], -110, +130) < 30) && (i < n - 1)) {
|
||||
if (nconsStrand == 0) firstStrand = i;
|
||||
nconsStrand++;
|
||||
} else {
|
||||
if (2 <= nconsStrand) {
|
||||
for (int k = firstStrand; k < i; k++) {
|
||||
ss[k] = STRAND;
|
||||
handness[k] = RHANDED;
|
||||
|
||||
}
|
||||
}
|
||||
nconsStrand = 0;
|
||||
}
|
||||
|
||||
ss[i] = COIL;
|
||||
handness[i] = RHANDED;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculates the torsional angle defined by four atoms with positions at0, at1, at2 and at3.
|
||||
float calculateTorsionalAngle(PVector at0, PVector at1, PVector at2, PVector at3) {
|
||||
PVector r01 = PVector.sub(at0, at1);
|
||||
PVector r32 = PVector.sub(at3, at2);
|
||||
PVector r12 = PVector.sub(at1, at2);
|
||||
|
||||
PVector p = r12.cross(r01);
|
||||
PVector q = r12.cross(r32);
|
||||
PVector r = r12.cross(q);
|
||||
|
||||
float u = q.dot(q);
|
||||
float v = r.dot(r);
|
||||
|
||||
float a;
|
||||
if (u <= 0.0 || v <= 0.0) {
|
||||
a = 360.0;
|
||||
} else {
|
||||
float u1 = p.dot(q); // u1 = p * q
|
||||
float v1 = p.dot(r); // v1 = p * r
|
||||
|
||||
u = u1 / sqrt(u);
|
||||
v = v1 / sqrt(v);
|
||||
|
||||
if (abs(u) > 0.01 || abs(v) > 0.01) a = degrees(atan2(v, u));
|
||||
else a = 360.0;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
void generateSpline(int n, ArrayList vertices) {
|
||||
int ui;
|
||||
float u;
|
||||
PVector v0, v1;
|
||||
|
||||
v0 = new PVector();
|
||||
v1 = new PVector();
|
||||
|
||||
if (n == 0) splineSide1.feval(0, v1);
|
||||
else if (n == 1) splineCenter.feval(0, v1);
|
||||
else splineSide2.feval(0, v1);
|
||||
|
||||
for (ui = 1; ui <= 10; ui ++) {
|
||||
if (ui % uspacing == 0) {
|
||||
u = 0.1 * ui;
|
||||
v0.set(v1);
|
||||
|
||||
if (n == 0) splineSide1.feval(u, v1);
|
||||
else if (n == 1) splineCenter.feval(u, v1);
|
||||
else splineSide2.feval(u, v1);
|
||||
|
||||
vertices.add(new PVector(v0.x, v0.y, v0.z));
|
||||
vertices.add(new PVector(v1.x, v1.y, v1.z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void generateFlatRibbon(ArrayList vertices, ArrayList normals) {
|
||||
PVector CentPoint0, CentPoint1;
|
||||
PVector Sid1Point0, Sid1Point1;
|
||||
PVector Sid2Point0, Sid2Point1;
|
||||
PVector Transversal, Tangent;
|
||||
PVector Normal0, Normal1;
|
||||
int ui;
|
||||
float u;
|
||||
|
||||
CentPoint0 = new PVector();
|
||||
CentPoint1 = new PVector();
|
||||
Sid1Point0 = new PVector();
|
||||
Sid1Point1 = new PVector();
|
||||
Sid2Point0 = new PVector();
|
||||
Sid2Point1 = new PVector();
|
||||
Transversal = new PVector();
|
||||
Tangent = new PVector();
|
||||
Normal0 = new PVector();
|
||||
Normal1 = new PVector();
|
||||
|
||||
// The initial geometry is generated.
|
||||
splineSide1.feval(0, Sid1Point1);
|
||||
splineCenter.feval(0, CentPoint1);
|
||||
splineSide2.feval(0, Sid2Point1);
|
||||
|
||||
// The tangents at the three previous points are the same.
|
||||
splineSide2.deval(0, Tangent);
|
||||
|
||||
// Vector transversal to the ribbon.
|
||||
Transversal = PVector.sub(Sid1Point1, Sid2Point1);
|
||||
|
||||
// The normal is calculated.
|
||||
Normal1 = Transversal.cross(Tangent);
|
||||
Normal1.normalize();
|
||||
|
||||
for (ui = 1; ui <= 10; ui ++) {
|
||||
if (ui % uspacing == 0) {
|
||||
u = 0.1 * ui;
|
||||
|
||||
// The geometry of the previous iteration is saved.
|
||||
Sid1Point0.set(Sid1Point1);
|
||||
CentPoint0.set(CentPoint1);
|
||||
Sid2Point0.set(Sid2Point1);
|
||||
Normal0.set(Normal1);
|
||||
|
||||
// The new geometry is generated.
|
||||
splineSide1.feval(u, Sid1Point1);
|
||||
splineCenter.feval(u, CentPoint1);
|
||||
splineSide2.feval(u, Sid2Point1);
|
||||
|
||||
// The tangents at the three previous points are the same.
|
||||
splineSide2.deval(u, Tangent);
|
||||
// Vector transversal to the ribbon.
|
||||
Transversal = PVector.sub(Sid1Point1, Sid2Point1);
|
||||
// The normal is calculated.
|
||||
Normal1 = Transversal.cross(Tangent);
|
||||
Normal1.normalize();
|
||||
|
||||
// The (Sid1Point0, Sid1Point1, CentPoint1) triangle is added.
|
||||
vertices.add(new PVector(Sid1Point0.x, Sid1Point0.y, Sid1Point0.z));
|
||||
normals.add(new PVector(Normal0.x, Normal0.y, Normal0.z));
|
||||
|
||||
vertices.add(new PVector(Sid1Point1.x, Sid1Point1.y, Sid1Point1.z));
|
||||
normals.add(new PVector(Normal1.x, Normal1.y, Normal1.z));
|
||||
|
||||
vertices.add(new PVector(CentPoint1.x, CentPoint1.y, CentPoint1.z));
|
||||
normals.add(new PVector(Normal1.x, Normal1.y, Normal1.z));
|
||||
|
||||
// The (Sid1Point0, CentPoint1, CentPoint0) triangle is added.
|
||||
vertices.add(new PVector(Sid1Point0.x, Sid1Point0.y, Sid1Point0.z));
|
||||
normals.add(new PVector(Normal0.x, Normal0.y, Normal0.z));
|
||||
|
||||
vertices.add(new PVector(CentPoint1.x, CentPoint1.y, CentPoint1.z));
|
||||
normals.add(new PVector(Normal1.x, Normal1.y, Normal1.z));
|
||||
|
||||
vertices.add(new PVector(CentPoint0.x, CentPoint0.y, CentPoint0.z));
|
||||
normals.add(new PVector(Normal0.x, Normal0.y, Normal0.z));
|
||||
|
||||
// (Sid2Point0, Sid2Point1, CentPoint1) triangle is added.
|
||||
vertices.add(new PVector(Sid2Point0.x, Sid2Point0.y, Sid2Point0.z));
|
||||
normals.add(new PVector(Normal0.x, Normal0.y, Normal0.z));
|
||||
|
||||
vertices.add(new PVector(Sid2Point1.x, Sid2Point1.y, Sid2Point1.z));
|
||||
normals.add(new PVector(Normal1.x, Normal1.y, Normal1.z));
|
||||
|
||||
vertices.add(new PVector(CentPoint1.x, CentPoint1.y, CentPoint1.z));
|
||||
normals.add(new PVector(Normal1.x, Normal1.y, Normal1.z));
|
||||
|
||||
// (Sid2Point0, CentPoint1, CentPoint0) triangle is added.
|
||||
vertices.add(new PVector(Sid2Point0.x, Sid2Point0.y, Sid2Point0.z));
|
||||
normals.add(new PVector(Normal0.x, Normal0.y, Normal0.z));
|
||||
|
||||
vertices.add(new PVector(CentPoint1.x, CentPoint1.y, CentPoint1.z));
|
||||
normals.add(new PVector(Normal1.x, Normal1.y, Normal1.z));
|
||||
|
||||
vertices.add(new PVector(CentPoint0.x, CentPoint0.y, CentPoint0.z));
|
||||
normals.add(new PVector(Normal0.x, Normal0.y, Normal0.z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* The code in the following three functions is based in the method introduced
|
||||
* in this paper:
|
||||
* "Algorithm for ribbon models of proteins."
|
||||
* Authors: Mike Carson and Charles E. Bugg
|
||||
* Published in: J.Mol.Graphics 4, pp. 121-122 (1986)
|
||||
******************************************************************************/
|
||||
|
||||
// Shifts the control points one place to the left.
|
||||
void shiftControlPoints() {
|
||||
splineSide1.shiftBSplineCPoints();
|
||||
splineCenter.shiftBSplineCPoints();
|
||||
splineSide2.shiftBSplineCPoints();
|
||||
}
|
||||
|
||||
// Adds a new control point to the arrays CPCenter, CPRight and CPLeft
|
||||
void addControlPoints(PVector ca0, PVector ox0, PVector ca1, int ss, int handness) {
|
||||
PVector A, B, C, D, p0, cpt0, cpt1, cpt2;
|
||||
|
||||
A = PVector.sub(ca1, ca0);
|
||||
B = PVector.sub(ox0, ca0);
|
||||
|
||||
// Vector normal to the peptide plane (pointing outside in the case of the
|
||||
// alpha helix).
|
||||
C = A.cross(B);
|
||||
|
||||
// Vector contained in the peptide plane (perpendicular to its direction).
|
||||
D = C.cross(A);
|
||||
|
||||
// Normalizing vectors.
|
||||
C.normalize();
|
||||
D.normalize();
|
||||
|
||||
// Flipping test (to avoid self crossing in the strands).
|
||||
if ((ss != HELIX) && (90.0 < degrees(PVector.angleBetween(flipTestV, D)))) {
|
||||
// Flip detected. The plane vector is inverted.
|
||||
D.mult(-1.0);
|
||||
}
|
||||
|
||||
// The central control point is constructed.
|
||||
cpt0 = linearComb(0.5, ca0, 0.5, ca1);
|
||||
splineCenter.setCPoint(3, cpt0);
|
||||
|
||||
if (ss == HELIX) {
|
||||
// When residue i is contained in a helix, the control point is moved away
|
||||
// from the helix axis, along the C direction.
|
||||
p0 = new PVector();
|
||||
splineCenter.getCPoint(3, p0);
|
||||
cpt0 = linearComb(1.0, p0, handness * helixDiam, C);
|
||||
splineCenter.setCPoint(3, cpt0);
|
||||
}
|
||||
|
||||
// The control points for the side ribbons are constructed.
|
||||
cpt1 = linearComb(1.0, cpt0, +ribbonWidth[ss], D);
|
||||
splineSide1.setCPoint(3, cpt1);
|
||||
|
||||
cpt2 = linearComb(1.0, cpt0, -ribbonWidth[ss], D);
|
||||
splineSide2.setCPoint(3, cpt2);
|
||||
|
||||
// Saving the plane vector (for the flipping test in the next call).
|
||||
flipTestV.set(D);
|
||||
}
|
||||
|
||||
void constructControlPoints(ArrayList residues, int res, int ss, int handness) {
|
||||
PVector ca0, ox0, ca1;
|
||||
PVector p0, p1, p2, p3;
|
||||
|
||||
p1 = new PVector();
|
||||
p2 = new PVector();
|
||||
p3 = new PVector();
|
||||
|
||||
HashMap res0, res1;
|
||||
|
||||
res0 = res1 = null;
|
||||
if (res == 0) {
|
||||
// The control points 2 and 3 are created.
|
||||
flipTestV.set(0, 0, 0);
|
||||
|
||||
res0 = (HashMap)residues.get(res);
|
||||
res1 = (HashMap)residues.get(res + 1);
|
||||
ca0 = (PVector)res0.get("CA");
|
||||
ox0 = (PVector)res0.get("O");
|
||||
ca1 = (PVector)res1.get("CA");
|
||||
addControlPoints(ca0, ox0, ca1, ss, handness);
|
||||
splineSide1.copyCPoints(3, 2);
|
||||
splineCenter.copyCPoints(3, 2);
|
||||
splineSide2.copyCPoints(3, 2);
|
||||
|
||||
res0 = (HashMap)residues.get(res + 1);
|
||||
res1 = (HashMap)residues.get(res + 2);
|
||||
ca0 = (PVector)res0.get("CA");
|
||||
ox0 = (PVector)res0.get("O");
|
||||
ca1 = (PVector)res1.get("CA");
|
||||
addControlPoints(ca0, ox0, ca1, ss, handness);
|
||||
|
||||
// We still need the two first control points.
|
||||
// Moving backwards along the cp_center[2] - cp_center[3] direction.
|
||||
splineCenter.getCPoint(2, p2);
|
||||
splineCenter.getCPoint(3, p3);
|
||||
|
||||
p1 = linearComb(2.0, p2, -1, p3);
|
||||
splineCenter.setCPoint(1, p1);
|
||||
splineSide1.setCPoint(1, linearComb(1.0, p1, +ribbonWidth[ss], flipTestV));
|
||||
splineSide2.setCPoint(1, linearComb(1.0, p1, -ribbonWidth[ss], flipTestV));
|
||||
|
||||
p0 = linearComb(2.0, p1, -1, p2);
|
||||
splineCenter.setCPoint(0, p0);
|
||||
splineSide1.setCPoint(0, linearComb(1.0, p0, +ribbonWidth[ss], flipTestV));
|
||||
splineSide2.setCPoint(0, linearComb(1.0, p0, -ribbonWidth[ss], flipTestV));
|
||||
} else {
|
||||
shiftControlPoints();
|
||||
if ((residues.size() - 1 == res) || (residues.size() - 2 == res)) {
|
||||
// Moving forward along the cp_center[1] - cp_center[2] direction.
|
||||
splineCenter.getCPoint(1, p1);
|
||||
splineCenter.getCPoint(2, p2);
|
||||
|
||||
p3 = linearComb(2.0, p2, -1, p1);
|
||||
splineCenter.setCPoint(3, p3);
|
||||
splineSide1.setCPoint(3, linearComb(1.0, p3, +ribbonWidth[ss], flipTestV));
|
||||
splineSide2.setCPoint(3, linearComb(1.0, p3, -ribbonWidth[ss], flipTestV));
|
||||
} else {
|
||||
res0 = (HashMap)residues.get(res + 1);
|
||||
res1 = (HashMap)residues.get(res + 2);
|
||||
ca0 = (PVector)res0.get("CA");
|
||||
ox0 = (PVector)res0.get("O");
|
||||
ca1 = (PVector)res1.get("CA");
|
||||
addControlPoints(ca0, ox0, ca1, ss, handness);
|
||||
}
|
||||
}
|
||||
splineSide1.updateMatrix3();
|
||||
splineCenter.updateMatrix3();
|
||||
splineSide2.updateMatrix3();
|
||||
}
|
||||
|
||||
PVector linearComb(float scalar0, PVector vector0, float scalar1, PVector vector1) {
|
||||
return PVector.add(PVector.mult(vector0, scalar0), PVector.mult(vector1, scalar1));
|
||||
}
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
void readPDB(String filename) {
|
||||
String strLines[];
|
||||
|
||||
float xmin, xmax, ymin, ymax, zmin, zmax;
|
||||
|
||||
String xstr, ystr, zstr;
|
||||
float x, y, z;
|
||||
int res, res0;
|
||||
int nmdl;
|
||||
String atstr, resstr;
|
||||
|
||||
PShape3D model;
|
||||
ArrayList atoms;
|
||||
ArrayList residues;
|
||||
HashMap residue;
|
||||
PVector v;
|
||||
String s;
|
||||
strLines = loadStrings(filename);
|
||||
|
||||
models = new ArrayList();
|
||||
|
||||
xmin = ymin = zmin = 10000;
|
||||
xmax = ymax = zmax = -10000;
|
||||
|
||||
atoms = null;
|
||||
residues = null;
|
||||
residue = null;
|
||||
model = null;
|
||||
res0 = -1;
|
||||
nmdl = -1;
|
||||
for (int i = 0; i < strLines.length; i++) {
|
||||
s = strLines[i];
|
||||
|
||||
if (s.startsWith("MODEL") || (s.startsWith("ATOM") && res0 == -1)) {
|
||||
nmdl++;
|
||||
|
||||
res0 = -1;
|
||||
|
||||
atoms = new ArrayList();
|
||||
residues = new ArrayList();
|
||||
}
|
||||
|
||||
if (s.startsWith("ATOM")) {
|
||||
atstr = s.substring(12, 15);
|
||||
atstr = atstr.trim();
|
||||
resstr = s.substring(22, 26);
|
||||
resstr = resstr.trim();
|
||||
res = parseInt(resstr);
|
||||
|
||||
xstr = s.substring(30, 37);
|
||||
xstr = xstr.trim();
|
||||
ystr = s.substring(38, 45);
|
||||
ystr = ystr.trim();
|
||||
zstr = s.substring(46, 53);
|
||||
zstr = zstr.trim();
|
||||
|
||||
x = scaleFactor * parseFloat(xstr);
|
||||
y = scaleFactor * parseFloat(ystr);
|
||||
z = scaleFactor * parseFloat(zstr);
|
||||
v = new PVector(x, y, z);
|
||||
|
||||
xmin = min(xmin, x);
|
||||
xmax = max(xmax, x);
|
||||
|
||||
ymin = min(ymin, y);
|
||||
ymax = max(ymax, y);
|
||||
|
||||
zmin = min(zmin, z);
|
||||
zmax = max(zmax, z);
|
||||
|
||||
atoms.add(v);
|
||||
|
||||
if (res0 != res) {
|
||||
if (residue != null) residues.add(residue);
|
||||
residue = new HashMap();
|
||||
}
|
||||
residue.put(atstr, v);
|
||||
|
||||
res0 = res;
|
||||
}
|
||||
|
||||
if (s.startsWith("ENDMDL") || s.startsWith("TER")) {
|
||||
if (residue != null) residues.add(residue);
|
||||
|
||||
createRibbonModel(residues, model, models);
|
||||
float rgyr = calculateGyrRadius(atoms);
|
||||
|
||||
res0 = -1;
|
||||
residue = null;
|
||||
atoms = null;
|
||||
residues = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (residue != null) {
|
||||
if (residue != null) residues.add(residue);
|
||||
|
||||
createRibbonModel(residues, model, models);
|
||||
float rgyr = calculateGyrRadius(atoms);
|
||||
|
||||
atoms = null;
|
||||
residues = null;
|
||||
}
|
||||
|
||||
// Centering models at (0, 0, 0).
|
||||
float dx = -0.5f * (xmin + xmax);
|
||||
float dy = -0.5f * (ymin + ymax);
|
||||
float dz = -0.5f * (zmin + zmax);
|
||||
for (int n = 0; n < models.size(); n++) {
|
||||
model = (PShape3D)models.get(n);
|
||||
model.loadVertices();
|
||||
for (int i = 0; i < model.getVertexCount(); i++) {
|
||||
model.vertices[3 * i + 0] += dx;
|
||||
model.vertices[3 * i + 1] += dy;
|
||||
model.vertices[3 * i + 2] += dz;
|
||||
}
|
||||
model.updateVertices();
|
||||
}
|
||||
|
||||
println("Loaded PDB file with " + models.size() + " models.");
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
// Ribbons, by Andres Colubri
|
||||
// ArcBall class by Ariel, V3ga and Robert Hodgin (flight404)
|
||||
// This sketch loads 3D atomic coordinates of a protein molecule
|
||||
// from a file in PDB format (http://www.pdb.org/) and displays
|
||||
// the structure using a ribbon representation.
|
||||
|
||||
String pdbFile = "4HHB.pdb"; // PDB file to read
|
||||
//String pdbFile = "2POR.pdb";
|
||||
//String pdbFile = "1CBS.pdb";
|
||||
|
||||
// Some parameters to control the visual appearance:
|
||||
float scaleFactor = 5; // Size factor
|
||||
int renderMode = 1; // 0 = lines, 1 = flat ribbons
|
||||
int ribbonDetail = 3; // Ribbon detail: from 1 (lowest) to 4 (highest)
|
||||
float helixDiam = 10; // Helix diameter.
|
||||
int[] ribbonWidth = {10, 7, 2}; // Ribbon widths for helix, strand and coil
|
||||
color ribbonColor = color(20, 30, 200, 255); // Ribbon color
|
||||
|
||||
// All the molecular models read from the PDB file (it could contain more than one)
|
||||
ArrayList models;
|
||||
|
||||
Arcball arcball;
|
||||
|
||||
void setup() {
|
||||
size(480, 800, P3D);
|
||||
orientation(PORTRAIT);
|
||||
|
||||
arcball = new Arcball(width/2, height/2, 600);
|
||||
readPDB(pdbFile);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
|
||||
if (renderMode == 1) {
|
||||
lights();
|
||||
}
|
||||
|
||||
translate(width/2, height/2, 300);
|
||||
arcball.run();
|
||||
|
||||
for (int i = 0; i < models.size(); i++) {
|
||||
PShape3D model = (PShape3D)models.get(i);
|
||||
shape(model);
|
||||
}
|
||||
}
|
||||
|
||||
void mousePressed(){
|
||||
arcball.mousePressed();
|
||||
}
|
||||
|
||||
void mouseDragged(){
|
||||
arcball.mouseDragged();
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,159 +0,0 @@
|
||||
// Rocket, by Andres Colubri.
|
||||
// This example shows the OBJ load functionality and the use of
|
||||
// the PShape3D class to create a particle system.
|
||||
// Rocket model from http://keleb.free.fr/codecorner/models-en.htm
|
||||
|
||||
PShape3D rocket;
|
||||
PShape3D particles;
|
||||
int[] lifetimes;
|
||||
|
||||
int numParticlesTotal = 600;
|
||||
int numParticlesPerFrame = 10;
|
||||
int particleLifetime;
|
||||
|
||||
float time;
|
||||
float timeInc = 0.03;
|
||||
|
||||
PVector axis, pos, vel;
|
||||
|
||||
void setup() {
|
||||
size(480, 800, P3D);
|
||||
orientation(PORTRAIT);
|
||||
|
||||
rocket = (PShape3D)loadShape("rocket.obj");
|
||||
// Adjusting the size, orientation and position of the object.
|
||||
// The bulk scale, rotate and translate operations done on the
|
||||
// shape are permanent.
|
||||
rocket.scaleVertices(0.2);
|
||||
rocket.rotateVerticesX(-PI);
|
||||
rocket.translateVertices(-5, 25, 0);
|
||||
|
||||
// The particle system is stored in a PShape3D object set to
|
||||
// POINT_SPRITES mode
|
||||
particles = (PShape3D)createShape(numParticlesTotal, PShape3D.newParameters(POINT_SPRITES, DYNAMIC));
|
||||
particleLifetime = numParticlesTotal / numParticlesPerFrame;
|
||||
lifetimes = new int[numParticlesTotal];
|
||||
|
||||
// Loading and setting the sprite image.
|
||||
PImage sprite = loadImage("smoke.png");
|
||||
particles.setTexture(sprite);
|
||||
// The default maximum sprite size is determined by the graphics
|
||||
// hardware (it usually ranges between 32 and 128 pixels).
|
||||
println("Maximum sprite size: " + particles.getMaxSpriteSize());
|
||||
// The maximum size can be set with setMaxSpriteSize(), but will be
|
||||
// capped by the maximum size supported by the hardware.
|
||||
particles.setMaxSpriteSize(32);
|
||||
// The actual sprite size depends on the distance d from the sprite
|
||||
// to the camera as follows:
|
||||
// s = smax / (1 + c * d * d) (quadratic dependence on d)
|
||||
// or
|
||||
// s = smax / (1 + c * d) (linear dependence on d)
|
||||
// where smax is the maximum sprite size and c an adjustable constant.
|
||||
// In the next call, the constant is adjusted so that the actual sprite
|
||||
// size is 10 when the distance is 400. A quadratic dependence on d is used.
|
||||
particles.setSpriteSize(10, 400, QUADRATIC);
|
||||
// PShape3D objects automatically update their bounding boxes, but we don't
|
||||
// want this for the particle system object.
|
||||
particles.autoBounds(false);
|
||||
particles.setColor(color(0)); // Making sure that all particles start as black.
|
||||
|
||||
// Initialzing particles with negative lifetimes so they are added
|
||||
// progresively into the scene during the first frames of the program
|
||||
int t = -1;
|
||||
for (int i = 0; i < numParticlesTotal; i++) {
|
||||
if (i % numParticlesPerFrame == 0) {
|
||||
t++;
|
||||
}
|
||||
lifetimes[i] = -t;
|
||||
}
|
||||
|
||||
pos = new PVector(0, 0, 0);
|
||||
vel = new PVector(0, 0, 0);
|
||||
|
||||
// The rocket object is originally aligned to the Y axis. We
|
||||
// use this vector to calculate the rotation needed to make
|
||||
// the rocket aligned to the velocity vector
|
||||
axis = new PVector(0, 1, 0);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
|
||||
updatePosition();
|
||||
updateParticles();
|
||||
|
||||
ambient(250, 250, 250);
|
||||
pointLight(255, 255, 255, 500, height/2, 400);
|
||||
|
||||
pushMatrix();
|
||||
translate(pos.x, pos.y, pos.z);
|
||||
|
||||
PVector rotAxis = axis.cross(vel);
|
||||
float angle = PVector.angleBetween(axis, vel);
|
||||
rotate(angle, rotAxis.x, rotAxis.y, rotAxis.z);
|
||||
|
||||
rotateY(2 * time);
|
||||
|
||||
shape(rocket);
|
||||
popMatrix();
|
||||
|
||||
// The particles are not lit.
|
||||
noLights();
|
||||
|
||||
// Writing to the depth mask is disabled to avoid rendering artifacts due
|
||||
// to the fact that the particles are transparent but not depth sorted
|
||||
hint(DISABLE_DEPTH_MASK);
|
||||
shape(particles);
|
||||
hint(ENABLE_DEPTH_MASK);
|
||||
|
||||
time += timeInc;
|
||||
}
|
||||
|
||||
void updatePosition() {
|
||||
pos.x = width/2 + 150 * cos(time);
|
||||
pos.y = 50 + height/2 + 200 * cos(2 * time);
|
||||
pos.z = 150 + 200 * sin(time);
|
||||
|
||||
vel.x = 150 * sin(time);
|
||||
vel.y = 400 * sin(2 * time);
|
||||
vel.z = -150 * cos(time);
|
||||
}
|
||||
|
||||
void updateParticles() {
|
||||
// Respawn dead particles
|
||||
particles.loadVertices();
|
||||
for (int i = 0; i < numParticlesTotal; i++) {
|
||||
if (lifetimes[i] == 0) {
|
||||
particles.vertices[3 * i + 0] = random(pos.x - 8, pos.x + 8);
|
||||
particles.vertices[3 * i + 1] = random(pos.y - 8, pos.y + 8);
|
||||
particles.vertices[3 * i + 2] = random(pos.z - 8, pos.z + 8);
|
||||
}
|
||||
}
|
||||
particles.updateVertices();
|
||||
|
||||
// Update colors and lifetimes of particles
|
||||
particles.loadColors();
|
||||
for (int i = 0; i < numParticlesTotal; i++) {
|
||||
if (0 <= lifetimes[i]) {
|
||||
// Interpolating between alpha 1 to 0:
|
||||
float a = 1.0 - float(lifetimes[i]) / particleLifetime;
|
||||
|
||||
// Interpolating from orange to white during the first
|
||||
// quarter of the particle's life (the color shoud be specified
|
||||
// in normalized RGBA components)
|
||||
float f = min(float(lifetimes[i]) / (0.25 * particleLifetime), 1);
|
||||
particles.colors[4 * i + 0] = (1 - f) * 0.98 + f;
|
||||
particles.colors[4 * i + 1] = (1 - f) * 0.75 + f;
|
||||
particles.colors[4 * i + 2] = (1 - f) * 0.26 + f;
|
||||
particles.colors[4 * i + 3] = a;
|
||||
|
||||
}
|
||||
lifetimes[i]++;
|
||||
if (lifetimes[i] == particleLifetime) {
|
||||
lifetimes[i] = 0;
|
||||
}
|
||||
}
|
||||
particles.updateColors();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
newmtl Default
|
||||
illum 2
|
||||
Ka 0.698039 0.698039 0.698039
|
||||
Kd 0.698039 0.698039 0.698039
|
||||
Ks 0.710000 0.710000 0.710000
|
||||
Ns 76.109253
|
||||
map_Kd rocket.png
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,74 +0,0 @@
|
||||
|
||||
class Cube {
|
||||
|
||||
// Properties
|
||||
int w, h, d;
|
||||
int shiftX, shiftY, shiftZ;
|
||||
|
||||
// Constructor
|
||||
Cube(int w, int h, int d, int shiftX, int shiftY, int shiftZ){
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
this.d = d;
|
||||
this.shiftX = shiftX;
|
||||
this.shiftY = shiftY;
|
||||
this.shiftZ = shiftZ;
|
||||
}
|
||||
|
||||
// Main cube drawing method, which looks
|
||||
// more confusing than it really is. It's
|
||||
// just a bunch of rectangles drawn for
|
||||
// each cube face
|
||||
void drawCube(){
|
||||
beginShape(QUADS);
|
||||
// Front face
|
||||
//normal(0, 0, +1);
|
||||
vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
|
||||
vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
|
||||
vertex(w + shiftX, h + shiftY, -d/2 + shiftZ);
|
||||
vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ);
|
||||
|
||||
// Back face
|
||||
//normal(0, 0, -1);
|
||||
vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ);
|
||||
vertex(w + shiftX, -h/2 + shiftY, d + shiftZ);
|
||||
vertex(w + shiftX, h + shiftY, d + shiftZ);
|
||||
vertex(-w/2 + shiftX, h + shiftY, d + shiftZ);
|
||||
|
||||
// Left face
|
||||
//normal(-1, 0, 0);
|
||||
vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
|
||||
vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ);
|
||||
vertex(-w/2 + shiftX, h + shiftY, d + shiftZ);
|
||||
vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ);
|
||||
|
||||
// Right face
|
||||
//normal(+1, 0, 0);
|
||||
vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
|
||||
vertex(w + shiftX, -h/2 + shiftY, d + shiftZ);
|
||||
vertex(w + shiftX, h + shiftY, d + shiftZ);
|
||||
vertex(w + shiftX, h + shiftY, -d/2 + shiftZ);
|
||||
|
||||
// Top face
|
||||
//normal(0, +1, 0);
|
||||
vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
|
||||
vertex(w + shiftX, -h/2 + shiftY, -d/2 + shiftZ);
|
||||
vertex(w + shiftX, -h/2 + shiftY, d + shiftZ);
|
||||
vertex(-w/2 + shiftX, -h/2 + shiftY, d + shiftZ);
|
||||
|
||||
// Bottom face
|
||||
//normal(0, -1, 0);
|
||||
vertex(-w/2 + shiftX, h + shiftY, -d/2 + shiftZ);
|
||||
vertex(w + shiftX, h + shiftY, -d/2 + shiftZ);
|
||||
vertex(w + shiftX, h + shiftY, d + shiftZ);
|
||||
vertex(-w/2 + shiftX, h + shiftY, d + shiftZ);
|
||||
|
||||
endShape();
|
||||
|
||||
// Add some rotation to each box for pizazz.
|
||||
rotateY(radians(1));
|
||||
rotateX(radians(1));
|
||||
rotateZ(radians(1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
// Space Junk, by Ira Greenberg.
|
||||
// Zoom suggestion by Danny Greenberg.
|
||||
//
|
||||
// Rotating cubes in space using a custom Cube class.
|
||||
// Color controlled by light sources. Swipe the finger left
|
||||
// and right (in landscape mode) to zoom.
|
||||
|
||||
// Used for oveall rotation
|
||||
float ang;
|
||||
|
||||
// Cube count-lower/raise to test performance
|
||||
int limit = 200;
|
||||
|
||||
// Array for all cubes
|
||||
Cube[]cubes = new Cube[limit];
|
||||
|
||||
void setup() {
|
||||
size(800, 480, P3D);
|
||||
orientation(LANDSCAPE);
|
||||
|
||||
background(0);
|
||||
noStroke();
|
||||
|
||||
// Instantiate cubes, passing in random vals for size and postion
|
||||
for (int i = 0; i< cubes.length; i++){
|
||||
cubes[i] = new Cube(int(random(-10, 10)), int(random(-10, 10)),
|
||||
int(random(-10, 10)), int(random(-140, 140)), int(random(-140, 140)),
|
||||
int(random(-140, 140)));
|
||||
}
|
||||
|
||||
// Automatic normal calculation can be turned on/off.
|
||||
autoNormal(true);
|
||||
}
|
||||
|
||||
void draw(){
|
||||
background(0);
|
||||
fill(200);
|
||||
|
||||
// Set up some different colored lights
|
||||
pointLight(51, 102, 255, 65, 60, 100);
|
||||
pointLight(200, 40, 60, -65, -60, -150);
|
||||
|
||||
// Raise overall light in scene
|
||||
ambientLight(70, 70, 10);
|
||||
|
||||
// Center geometry in display windwow.
|
||||
// you can change 3rd argument ('0')
|
||||
// to move block group closer(+)/further(-)
|
||||
translate(width/2, height/2, -200 + mouseX * 0.65);
|
||||
|
||||
// Rotate around y and x axes
|
||||
rotateY(radians(ang));
|
||||
rotateX(radians(ang));
|
||||
|
||||
// Draw cubes
|
||||
for (int i = 0; i < cubes.length; i++){
|
||||
cubes[i].drawCube();
|
||||
}
|
||||
|
||||
// Used in rotate function calls above
|
||||
ang++;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
// TexCube by Andres Colubri
|
||||
// Creating a textured cube vertex by vertex using the
|
||||
// PShape3D class.
|
||||
|
||||
PShape3D cube;
|
||||
|
||||
float angleX;
|
||||
float angleY;
|
||||
|
||||
void setup() {
|
||||
size(480, 800, P3D);
|
||||
orientation(PORTRAIT);
|
||||
|
||||
// The 3D shape has to be created with the total name of vertices
|
||||
// it will hold (this number cannot be changed later). Also, how
|
||||
// the vertices will be connected is specified here (this can be
|
||||
// changed later though).
|
||||
cube = (PShape3D)createShape(36, PShape3D.newParameters(TRIANGLES));
|
||||
|
||||
// The vertices array gives access to all the vertex data
|
||||
// in the PShape3D object. It can only be used between
|
||||
// loadVertices and updateVertices. Similar thing can be done
|
||||
// for colors, normals and texture coordinates (see below).
|
||||
cube.loadVertices();
|
||||
arrayCopy(vertArray, cube.vertices);
|
||||
cube.updateVertices();
|
||||
|
||||
// 6 child shapes are created in order to assign different
|
||||
// textures each face of the cube.
|
||||
cube.addChild("Face 0", 0, 5); // First face from vertex 0 to 5.
|
||||
cube.addChild("Face 1", 6, 11); // Second face from vertex 6 to 11.
|
||||
cube.addChild("Face 2", 12, 17); // ...and so on.
|
||||
cube.addChild("Face 3", 18, 23);
|
||||
cube.addChild("Face 4", 24, 29);
|
||||
cube.addChild("Face 5", 30, 35);
|
||||
|
||||
// The entire shape is red.
|
||||
cube.setColor(color(200, 50, 50));
|
||||
|
||||
// Setting the normal for each face.
|
||||
cube.setNormal(0, 0, 0, -1);
|
||||
cube.setNormal(1, +1, 0, 0);
|
||||
cube.setNormal(2, 0, 0, +1);
|
||||
cube.setNormal(3, -1, 0, 0);
|
||||
cube.setNormal(4, 0, +1, 0);
|
||||
cube.setNormal(5, 0, -1, 0);
|
||||
|
||||
// Finally, setting texture images...
|
||||
cube.setTexture(0, loadImage("1.jpg"));
|
||||
cube.setTexture(1, loadImage("2.jpg"));
|
||||
cube.setTexture(2, loadImage("3.jpg"));
|
||||
cube.setTexture(3, loadImage("4.jpg"));
|
||||
cube.setTexture(4, loadImage("5.jpg"));
|
||||
cube.setTexture(5, loadImage("6.jpg"));
|
||||
|
||||
// ...and texture coordinates.
|
||||
cube.loadTexcoords();
|
||||
arrayCopy(tcoordArray, cube.texcoords);
|
||||
cube.updateTexcoords();
|
||||
}
|
||||
|
||||
public void draw() {
|
||||
background(0);
|
||||
|
||||
ambient(250, 250, 250);
|
||||
pointLight(255, 255, 255, 0, 0, 200);
|
||||
|
||||
translate(width/2, height/2, 200);
|
||||
|
||||
angleX += 0.01;
|
||||
angleY += 0.01;
|
||||
rotateX(angleX);
|
||||
rotateY(angleY);
|
||||
|
||||
shape(cube);
|
||||
}
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
float[] vertArray = new float[] {
|
||||
-100, +100, -100,
|
||||
-100, -100, -100,
|
||||
+100, -100, -100,
|
||||
-100, +100, -100,
|
||||
+100, -100, -100,
|
||||
+100, +100, -100,
|
||||
|
||||
+100, -100, +100,
|
||||
+100, +100, +100,
|
||||
+100, +100, -100,
|
||||
+100, -100, +100,
|
||||
+100, +100, -100,
|
||||
+100, -100, -100,
|
||||
|
||||
-100, -100, +100,
|
||||
-100, +100, +100,
|
||||
+100, +100, +100,
|
||||
-100, -100, +100,
|
||||
+100, +100, +100,
|
||||
+100, -100, +100,
|
||||
|
||||
-100, +100, +100,
|
||||
-100, -100, +100,
|
||||
-100, -100, -100,
|
||||
-100, +100, +100,
|
||||
-100, -100, -100,
|
||||
-100, +100, -100,
|
||||
|
||||
+100, +100, +100,
|
||||
-100, +100, +100,
|
||||
-100, +100, -100,
|
||||
+100, +100, +100,
|
||||
-100, +100, -100,
|
||||
+100, +100, -100,
|
||||
|
||||
-100, -100, -100,
|
||||
-100, -100, +100,
|
||||
+100, -100, +100,
|
||||
-100, -100, -100,
|
||||
+100, -100, +100,
|
||||
+100, -100, -100 };
|
||||
|
||||
float[] tcoordArray = new float[] {
|
||||
1, 1,
|
||||
1, 0,
|
||||
0, 0,
|
||||
1, 1,
|
||||
0, 0,
|
||||
0, 1,
|
||||
|
||||
1, 1,
|
||||
1, 0,
|
||||
0, 0,
|
||||
1, 1,
|
||||
0, 0,
|
||||
0, 1,
|
||||
|
||||
1, 1,
|
||||
1, 0,
|
||||
0, 0,
|
||||
1, 1,
|
||||
0, 0,
|
||||
0, 1,
|
||||
|
||||
1, 1,
|
||||
1, 0,
|
||||
0, 0,
|
||||
1, 1,
|
||||
0, 0,
|
||||
0, 1,
|
||||
|
||||
1, 1,
|
||||
1, 0,
|
||||
0, 0,
|
||||
1, 1,
|
||||
0, 0,
|
||||
0, 1,
|
||||
|
||||
1, 1,
|
||||
1, 0,
|
||||
0, 0,
|
||||
1, 1,
|
||||
0, 0,
|
||||
0, 1 };
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
// Code to draw a trefoil knot surface, with normals and texture
|
||||
// coordinates.
|
||||
// Adapted from the parametric equations example by Philip Rideout:
|
||||
// http://iphone-3d-programming.labs.oreilly.com/ch03.html
|
||||
|
||||
// Evaluates the surface point corresponding to normalized
|
||||
// parameters (x, y)
|
||||
PVector evalPoint(float u, float v) {
|
||||
float a = 0.5;
|
||||
float b = 0.3;
|
||||
float c = 0.5;
|
||||
float d = 0.1;
|
||||
float s = TWO_PI * u;
|
||||
float t = (TWO_PI * (1 - v)) * 2;
|
||||
|
||||
float r = a + b * cos(1.5 * t);
|
||||
float x = r * cos(t);
|
||||
float y = r * sin(t);
|
||||
float z = c * sin(1.5 * t);
|
||||
|
||||
PVector dv = new PVector();
|
||||
dv.x = -1.5f * b * sin(1.5f * t) * cos(t) -
|
||||
(a + b * cos(1.5f * t)) * sin(t);
|
||||
dv.y = -1.5f * b * sin(1.5f * t) * sin(t) +
|
||||
(a + b * cos(1.5f * t)) * cos(t);
|
||||
dv.z = 1.5f * c * cos(1.5f * t);
|
||||
|
||||
PVector q = dv;
|
||||
q.normalize();
|
||||
PVector qvn = new PVector(q.y, -q.x, 0);
|
||||
qvn.normalize();
|
||||
PVector ww = q.cross(qvn);
|
||||
|
||||
PVector pt = new PVector();
|
||||
pt.x = x + d * (qvn.x * cos(s) + ww.x * sin(s));
|
||||
pt.y = y + d * (qvn.y * cos(s) + ww.y * sin(s));
|
||||
pt.z = z + d * ww.z * sin(s);
|
||||
return pt;
|
||||
}
|
||||
|
||||
// Evaluates the surface normal corresponding to normalized
|
||||
// parameters (x, y)
|
||||
PVector evalNormal(float u, float v) {
|
||||
// Compute the tangents and their cross product.
|
||||
PVector p = evalPoint(u, v);
|
||||
PVector tangU = evalPoint(u + 0.01, v);
|
||||
PVector tangV = evalPoint(u, v + 0.01);
|
||||
tangU.sub(p);
|
||||
tangV.sub(p);
|
||||
|
||||
PVector normUV = tangV.cross(tangU);
|
||||
normUV.normalize();
|
||||
return normUV;
|
||||
}
|
||||
|
||||
// This function draws a trefoil knot surface as a triangle mesh derived
|
||||
// from its parametric equation.
|
||||
void drawSurface(float s, int ny, int nx, PImage tex) {
|
||||
PVector p0, p1, p2;
|
||||
PVector n0, n1, n2;
|
||||
float u0, u1, v0, v1;
|
||||
|
||||
beginShape(TRIANGLES);
|
||||
texture(tex);
|
||||
|
||||
for (int j = 0; j < nx; j++) {
|
||||
u0 = float(j) / nx;
|
||||
u1 = float(j + 1) / nx;
|
||||
for (int i = 0; i < ny; i++) {
|
||||
v0 = float(i) / ny;
|
||||
v1 = float(i + 1) / ny;
|
||||
|
||||
|
||||
p0 = evalPoint(u0, v0);
|
||||
n0 = evalNormal(u0, v0);
|
||||
|
||||
p1 = evalPoint(u0, v1);
|
||||
n1 = evalNormal(u0, v1);
|
||||
|
||||
p2 = evalPoint(u1, v1);
|
||||
n2 = evalNormal(u1, v1);
|
||||
|
||||
// Triangle p0-p1-p2
|
||||
normal(n0.x, n0.y, n0.z);
|
||||
vertex(s * p0.x, s * p0.y, s * p0.z, u0, v0);
|
||||
normal(n1.x, n1.y, n1.z);
|
||||
vertex(s * p1.x, s * p1.y, s * p1.z, u0, v1);
|
||||
normal(n2.x, n2.y, n2.z);
|
||||
vertex(s * p2.x, s * p2.y, s * p2.z, u1, v1);
|
||||
|
||||
p1 = evalPoint(u1, v0);
|
||||
n1 = evalNormal(u1, v0);
|
||||
|
||||
// Triangle p0-p2-p1
|
||||
normal(n0.x, n0.y, n0.z);
|
||||
vertex(s * p0.x, s * p0.y, s * p0.z, u0, v0);
|
||||
normal(n2.x, n2.y, n2.z);
|
||||
vertex(s * p2.x, s * p2.y, s * p2.z, u1, v1);
|
||||
normal(n1.x, n1.y, n1.z);
|
||||
vertex(s * p1.x, s * p1.y, s * p1.z, u1, v0);
|
||||
}
|
||||
}
|
||||
endShape();
|
||||
}
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
// Trefoil, by Andres Colubri
|
||||
// A parametric surface is textured procedurally
|
||||
// using a particle system rendered to an offscreen
|
||||
// surface.
|
||||
// Tap the screen to cycle between the textured surface,
|
||||
// the same surface but without the texture, and the
|
||||
// offscreen texture with the particle system.
|
||||
// Note that offscreen rendering is fully supported
|
||||
// only in Android 2.2 (froyo) and later. A3D provies
|
||||
// a fallback mechanism for 2.1, but it might be
|
||||
// substantially slower and not generate the same
|
||||
// visual results as in 2.2
|
||||
|
||||
PGraphics pg;
|
||||
PShape trefoil;
|
||||
PShape3D particles;
|
||||
int mode = 0;
|
||||
|
||||
void setup() {
|
||||
size(480, 800, P3D);
|
||||
orientation(PORTRAIT);
|
||||
|
||||
PFont font = createFont(PFont.list()[0], 24);
|
||||
textFont(font, 24);
|
||||
|
||||
textureMode(NORMAL);
|
||||
noStroke();
|
||||
|
||||
// Creating offscreen surface for 3D rendering.
|
||||
pg = createGraphics(32, 512, P3D);
|
||||
|
||||
// Initializing particle system
|
||||
particles = (PShape3D)createShape(1000, PShape3D.newParameters(POINT_SPRITES, DYNAMIC));
|
||||
particles.loadVertices();
|
||||
for (int i = 0; i < particles.getVertexCount(); i++) {
|
||||
particles.set(i, random(0, 10), random(0, 10), 0);
|
||||
}
|
||||
particles.updateVertices();
|
||||
particles.loadColors();
|
||||
for (int i = 0; i < particles.getVertexCount(); i++) {
|
||||
particles.set(i, random(0, 1), random(0, 1), random(0, 1));
|
||||
}
|
||||
particles.updateColors();
|
||||
PImage sprite = loadImage("particle.png");
|
||||
particles.setTexture(sprite);
|
||||
particles.setSpriteSize(8);
|
||||
|
||||
// Saving trefoil surface into a PShape3D object
|
||||
trefoil = beginRecord();
|
||||
drawSurface(250, 60, 15, pg);
|
||||
endRecord();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
|
||||
// Updating particle system
|
||||
particles.loadVertices();
|
||||
float[] v = particles.vertices;
|
||||
for (int i = 0; i < particles.getVertexCount(); i++) {
|
||||
// Just random wandering
|
||||
v[3 * i + 0] += random(-1, 1);
|
||||
v[3 * i + 1] += random(-1, 1);
|
||||
// Particles wrap around the edges
|
||||
if (v[3 * i + 0] < 0) v[3 * i + 0] += pg.width;
|
||||
if (v[3 * i + 1] < 0) v[3 * i + 1] += pg.height;
|
||||
if (pg.width < v[3 * i + 0]) v[3 * i + 0] -= pg.width;
|
||||
if (pg.height < v[3 * i + 1]) v[3 * i + 1] -= pg.height;
|
||||
}
|
||||
particles.updateVertices();
|
||||
|
||||
// Drawing particles into offscreen surface, used to
|
||||
// texture the trefoil shape.
|
||||
pg.beginDraw();
|
||||
pg.hint(DISABLE_DEPTH_MASK);
|
||||
pg.shape(particles);
|
||||
pg.hint(ENABLE_DEPTH_MASK);
|
||||
pg.endDraw();
|
||||
|
||||
if (mode < 2) {
|
||||
ambient(250, 250, 250);
|
||||
pointLight(255, 255, 255, 0, 0, 200);
|
||||
|
||||
pushMatrix();
|
||||
translate(width/2, height/2);
|
||||
rotateX(frameCount * PI / 500);
|
||||
rotateY(frameCount * PI / 500);
|
||||
|
||||
if (mode == 0) {
|
||||
trefoil.enableStyle();
|
||||
hint(DISABLE_DEPTH_MASK);
|
||||
screenBlend(ADD);
|
||||
} else {
|
||||
trefoil.disableStyle();
|
||||
screenBlend(BLEND);
|
||||
}
|
||||
|
||||
shape(trefoil);
|
||||
hint(ENABLE_DEPTH_MASK);
|
||||
popMatrix();
|
||||
} else {
|
||||
image(pg, 0, 0, width, height);
|
||||
}
|
||||
|
||||
fill(255);
|
||||
text("fps: " + frameRate, 10, height - 30);
|
||||
}
|
||||
|
||||
void mousePressed() {
|
||||
mode = (mode + 1) % 3;
|
||||
}
|
||||
|
||||
@@ -1,256 +0,0 @@
|
||||
class Gesture {
|
||||
|
||||
float damp = 5.0;
|
||||
float dampInv = 1.0 / damp;
|
||||
float damp1 = damp - 1;
|
||||
|
||||
int w;
|
||||
int h;
|
||||
int capacity;
|
||||
|
||||
Vec3f path[];
|
||||
int crosses[];
|
||||
Polygon polygons[];
|
||||
int nPoints;
|
||||
int nPolys;
|
||||
|
||||
float jumpDx, jumpDy;
|
||||
boolean exists;
|
||||
float INIT_TH = 14;
|
||||
float thickness = INIT_TH;
|
||||
|
||||
Gesture(int mw, int mh) {
|
||||
w = mw;
|
||||
h = mh;
|
||||
capacity = 600;
|
||||
path = new Vec3f[capacity];
|
||||
polygons = new Polygon[capacity];
|
||||
crosses = new int[capacity];
|
||||
for (int i=0;i<capacity;i++) {
|
||||
polygons[i] = new Polygon(4);
|
||||
polygons[i].npoints = 4;
|
||||
path[i] = new Vec3f();
|
||||
crosses[i] = 0;
|
||||
}
|
||||
nPoints = 0;
|
||||
nPolys = 0;
|
||||
|
||||
exists = false;
|
||||
jumpDx = 0;
|
||||
jumpDy = 0;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
nPoints = 0;
|
||||
exists = false;
|
||||
thickness = INIT_TH;
|
||||
}
|
||||
|
||||
void clearPolys() {
|
||||
nPolys = 0;
|
||||
}
|
||||
|
||||
void addPoint(float x, float y) {
|
||||
|
||||
if (nPoints >= capacity) {
|
||||
// there are all sorts of possible solutions here,
|
||||
// but for abject simplicity, I don't do anything.
|
||||
}
|
||||
else {
|
||||
float v = distToLast(x, y);
|
||||
float p = getPressureFromVelocity(v);
|
||||
path[nPoints++].set(x,y,p);
|
||||
|
||||
if (nPoints > 1) {
|
||||
exists = true;
|
||||
jumpDx = path[nPoints-1].x - path[0].x;
|
||||
jumpDy = path[nPoints-1].y - path[0].y;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float getPressureFromVelocity(float v) {
|
||||
final float scale = 18;
|
||||
final float minP = 0.02;
|
||||
final float oldP = (nPoints > 0) ? path[nPoints-1].p : 0;
|
||||
return ((minP + max(0, 1.0 - v/scale)) + (damp1*oldP))*dampInv;
|
||||
}
|
||||
|
||||
void setPressures() {
|
||||
// pressures vary from 0...1
|
||||
float pressure;
|
||||
Vec3f tmp;
|
||||
float t = 0;
|
||||
float u = 1.0 / (nPoints - 1)*TWO_PI;
|
||||
for (int i = 0; i < nPoints; i++) {
|
||||
pressure = sqrt((1.0 - cos(t))*0.5);
|
||||
path[i].p = pressure;
|
||||
t += u;
|
||||
}
|
||||
}
|
||||
|
||||
float distToLast(float ix, float iy) {
|
||||
if (nPoints > 0) {
|
||||
Vec3f v = path[nPoints-1];
|
||||
float dx = v.x - ix;
|
||||
float dy = v.y - iy;
|
||||
return mag(dx, dy);
|
||||
}
|
||||
else {
|
||||
return 30;
|
||||
}
|
||||
}
|
||||
|
||||
void compile() {
|
||||
// compute the polygons from the path of Vec3f's
|
||||
if (exists) {
|
||||
clearPolys();
|
||||
|
||||
Vec3f p0, p1, p2;
|
||||
float radius0, radius1;
|
||||
float ax, bx, cx, dx;
|
||||
float ay, by, cy, dy;
|
||||
int axi, bxi, cxi, dxi, axip, axid;
|
||||
int ayi, byi, cyi, dyi, ayip, ayid;
|
||||
float p1x, p1y;
|
||||
float dx01, dy01, hp01, si01, co01;
|
||||
float dx02, dy02, hp02, si02, co02;
|
||||
float dx13, dy13, hp13, si13, co13;
|
||||
float taper = 1.0;
|
||||
|
||||
int nPathPoints = nPoints - 1;
|
||||
int lastPolyIndex = nPathPoints - 1;
|
||||
float npm1finv = 1.0 / max(1, nPathPoints - 1);
|
||||
|
||||
// handle the first point
|
||||
p0 = path[0];
|
||||
p1 = path[1];
|
||||
radius0 = p0.p * thickness;
|
||||
dx01 = p1.x - p0.x;
|
||||
dy01 = p1.y - p0.y;
|
||||
hp01 = sqrt(dx01*dx01 + dy01*dy01);
|
||||
if (hp01 == 0) {
|
||||
hp02 = 0.0001;
|
||||
}
|
||||
co01 = radius0 * dx01 / hp01;
|
||||
si01 = radius0 * dy01 / hp01;
|
||||
ax = p0.x - si01;
|
||||
ay = p0.y + co01;
|
||||
bx = p0.x + si01;
|
||||
by = p0.y - co01;
|
||||
|
||||
int xpts[];
|
||||
int ypts[];
|
||||
|
||||
int LC = 20;
|
||||
int RC = w-LC;
|
||||
int TC = 20;
|
||||
int BC = h-TC;
|
||||
float mint = 0.618;
|
||||
float tapow = 0.4;
|
||||
|
||||
// handle the middle points
|
||||
int i = 1;
|
||||
Polygon apoly;
|
||||
for (i = 1; i < nPathPoints; i++) {
|
||||
taper = pow((lastPolyIndex-i)*npm1finv,tapow);
|
||||
|
||||
p0 = path[i-1];
|
||||
p1 = path[i ];
|
||||
p2 = path[i+1];
|
||||
p1x = p1.x;
|
||||
p1y = p1.y;
|
||||
radius1 = Math.max(mint,taper*p1.p*thickness);
|
||||
|
||||
// assumes all segments are roughly the same length...
|
||||
dx02 = p2.x - p0.x;
|
||||
dy02 = p2.y - p0.y;
|
||||
hp02 = (float) Math.sqrt(dx02*dx02 + dy02*dy02);
|
||||
if (hp02 != 0) {
|
||||
hp02 = radius1/hp02;
|
||||
}
|
||||
co02 = dx02 * hp02;
|
||||
si02 = dy02 * hp02;
|
||||
|
||||
// translate the integer coordinates to the viewing rectangle
|
||||
axi = axip = (int)ax;
|
||||
ayi = ayip = (int)ay;
|
||||
axi=(axi<0)?(w-((-axi)%w)):axi%w;
|
||||
axid = axi-axip;
|
||||
ayi=(ayi<0)?(h-((-ayi)%h)):ayi%h;
|
||||
ayid = ayi-ayip;
|
||||
|
||||
// set the vertices of the polygon
|
||||
apoly = polygons[nPolys++];
|
||||
xpts = apoly.xpoints;
|
||||
ypts = apoly.ypoints;
|
||||
xpts[0] = axi = axid + axip;
|
||||
xpts[1] = bxi = axid + (int) bx;
|
||||
xpts[2] = cxi = axid + (int)(cx = p1x + si02);
|
||||
xpts[3] = dxi = axid + (int)(dx = p1x - si02);
|
||||
ypts[0] = ayi = ayid + ayip;
|
||||
ypts[1] = byi = ayid + (int) by;
|
||||
ypts[2] = cyi = ayid + (int)(cy = p1y - co02);
|
||||
ypts[3] = dyi = ayid + (int)(dy = p1y + co02);
|
||||
|
||||
// keep a record of where we cross the edge of the screen
|
||||
crosses[i] = 0;
|
||||
if ((axi<=LC)||(bxi<=LC)||(cxi<=LC)||(dxi<=LC)) {
|
||||
crosses[i]|=1;
|
||||
}
|
||||
if ((axi>=RC)||(bxi>=RC)||(cxi>=RC)||(dxi>=RC)) {
|
||||
crosses[i]|=2;
|
||||
}
|
||||
if ((ayi<=TC)||(byi<=TC)||(cyi<=TC)||(dyi<=TC)) {
|
||||
crosses[i]|=4;
|
||||
}
|
||||
if ((ayi>=BC)||(byi>=BC)||(cyi>=BC)||(dyi>=BC)) {
|
||||
crosses[i]|=8;
|
||||
}
|
||||
|
||||
//swap data for next time
|
||||
ax = dx;
|
||||
ay = dy;
|
||||
bx = cx;
|
||||
by = cy;
|
||||
}
|
||||
|
||||
// handle the last point
|
||||
p2 = path[nPathPoints];
|
||||
apoly = polygons[nPolys++];
|
||||
xpts = apoly.xpoints;
|
||||
ypts = apoly.ypoints;
|
||||
|
||||
xpts[0] = (int)ax;
|
||||
xpts[1] = (int)bx;
|
||||
xpts[2] = (int)(p2.x);
|
||||
xpts[3] = (int)(p2.x);
|
||||
|
||||
ypts[0] = (int)ay;
|
||||
ypts[1] = (int)by;
|
||||
ypts[2] = (int)(p2.y);
|
||||
ypts[3] = (int)(p2.y);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void smooth() {
|
||||
// average neighboring points
|
||||
|
||||
final float weight = 18;
|
||||
final float scale = 1.0 / (weight + 2);
|
||||
int nPointsMinusTwo = nPoints - 2;
|
||||
Vec3f lower, upper, center;
|
||||
|
||||
for (int i = 1; i < nPointsMinusTwo; i++) {
|
||||
lower = path[i-1];
|
||||
center = path[i];
|
||||
upper = path[i+1];
|
||||
|
||||
center.x = (lower.x + weight*center.x + upper.x)*scale;
|
||||
center.y = (lower.y + weight*center.y + upper.y)*scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
public class Polygon {
|
||||
int npoints;
|
||||
int[] xpoints;
|
||||
int[] ypoints;
|
||||
|
||||
public Polygon(int n) {
|
||||
npoints = n;
|
||||
xpoints = new int[n];
|
||||
ypoints = new int[n];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
class Vec3f {
|
||||
float x;
|
||||
float y;
|
||||
float p; // Pressure
|
||||
|
||||
Vec3f() {
|
||||
set(0, 0, 0);
|
||||
}
|
||||
|
||||
Vec3f(float ix, float iy, float ip) {
|
||||
set(ix, iy, ip);
|
||||
}
|
||||
|
||||
void set(float ix, float iy, float ip) {
|
||||
x = ix;
|
||||
y = iy;
|
||||
p = ip;
|
||||
}
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
// Yellowtail
|
||||
// by Golan Levin (www.flong.com).
|
||||
|
||||
// Click, drag, and release to create a kinetic gesture.
|
||||
//
|
||||
// Yellowtail (1998-2000) is an interactive software system for the gestural
|
||||
// creation and performance of real-time abstract animation. Yellowtail repeats
|
||||
// a user's strokes end-over-end, enabling simultaneous specification of a
|
||||
// line's shape and quality of movement. Each line repeats according to its
|
||||
// own period, producing an ever-changing and responsive display of lively,
|
||||
// worm-like textures.
|
||||
|
||||
Gesture gestureArray[];
|
||||
final int nGestures = 36; // Number of gestures
|
||||
final int minMove = 3; // Minimum travel for a new point
|
||||
int currentGestureID;
|
||||
|
||||
Polygon tempP;
|
||||
int tmpXp[];
|
||||
int tmpYp[];
|
||||
|
||||
void setup() {
|
||||
size(screenWidth, screenHeight, P3D);
|
||||
orientation(PORTRAIT);
|
||||
|
||||
background(0, 0, 0);
|
||||
noStroke();
|
||||
|
||||
currentGestureID = -1;
|
||||
gestureArray = new Gesture[nGestures];
|
||||
for (int i = 0; i < nGestures; i++) {
|
||||
gestureArray[i] = new Gesture(width, height);
|
||||
}
|
||||
clearGestures();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
|
||||
updateGeometry();
|
||||
fill(255, 255, 245);
|
||||
for (int i = 0; i < nGestures; i++) {
|
||||
renderGesture(gestureArray[i], width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void mousePressed() {
|
||||
currentGestureID = (currentGestureID+1) % nGestures;
|
||||
Gesture G = gestureArray[currentGestureID];
|
||||
G.clear();
|
||||
G.clearPolys();
|
||||
G.addPoint(mouseX, mouseY);
|
||||
}
|
||||
|
||||
|
||||
void mouseDragged() {
|
||||
if (currentGestureID >= 0) {
|
||||
Gesture G = gestureArray[currentGestureID];
|
||||
if (G.distToLast(mouseX, mouseY) > minMove) {
|
||||
G.addPoint(mouseX, mouseY);
|
||||
G.smooth();
|
||||
G.compile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void keyPressed() {
|
||||
if (key == '+' || key == '=') {
|
||||
if (currentGestureID >= 0) {
|
||||
float th = gestureArray[currentGestureID].thickness;
|
||||
gestureArray[currentGestureID].thickness = min(96, th+1);
|
||||
gestureArray[currentGestureID].compile();
|
||||
}
|
||||
} else if (key == '-') {
|
||||
if (currentGestureID >= 0) {
|
||||
float th = gestureArray[currentGestureID].thickness;
|
||||
gestureArray[currentGestureID].thickness = max(2, th-1);
|
||||
gestureArray[currentGestureID].compile();
|
||||
}
|
||||
} else if (key == ' ') {
|
||||
clearGestures();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void renderGesture(Gesture gesture, int w, int h) {
|
||||
if (gesture.exists) {
|
||||
if (gesture.nPolys > 0) {
|
||||
Polygon polygons[] = gesture.polygons;
|
||||
int crosses[] = gesture.crosses;
|
||||
|
||||
int xpts[];
|
||||
int ypts[];
|
||||
Polygon p;
|
||||
int cr;
|
||||
|
||||
beginShape(QUADS);
|
||||
int gnp = gesture.nPolys;
|
||||
for (int i=0; i<gnp; i++) {
|
||||
|
||||
p = polygons[i];
|
||||
xpts = p.xpoints;
|
||||
ypts = p.ypoints;
|
||||
|
||||
vertex(xpts[0], ypts[0]);
|
||||
vertex(xpts[1], ypts[1]);
|
||||
vertex(xpts[2], ypts[2]);
|
||||
vertex(xpts[3], ypts[3]);
|
||||
|
||||
if ((cr = crosses[i]) > 0) {
|
||||
if ((cr & 3)>0) {
|
||||
vertex(xpts[0]+w, ypts[0]);
|
||||
vertex(xpts[1]+w, ypts[1]);
|
||||
vertex(xpts[2]+w, ypts[2]);
|
||||
vertex(xpts[3]+w, ypts[3]);
|
||||
|
||||
vertex(xpts[0]-w, ypts[0]);
|
||||
vertex(xpts[1]-w, ypts[1]);
|
||||
vertex(xpts[2]-w, ypts[2]);
|
||||
vertex(xpts[3]-w, ypts[3]);
|
||||
}
|
||||
if ((cr & 12)>0) {
|
||||
vertex(xpts[0], ypts[0]+h);
|
||||
vertex(xpts[1], ypts[1]+h);
|
||||
vertex(xpts[2], ypts[2]+h);
|
||||
vertex(xpts[3], ypts[3]+h);
|
||||
|
||||
vertex(xpts[0], ypts[0]-h);
|
||||
vertex(xpts[1], ypts[1]-h);
|
||||
vertex(xpts[2], ypts[2]-h);
|
||||
vertex(xpts[3], ypts[3]-h);
|
||||
}
|
||||
|
||||
// I have knowingly retained the small flaw of not
|
||||
// completely dealing with the corner conditions
|
||||
// (the case in which both of the above are true).
|
||||
}
|
||||
}
|
||||
endShape();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateGeometry() {
|
||||
Gesture J;
|
||||
for (int g=0; g<nGestures; g++) {
|
||||
if ((J=gestureArray[g]).exists) {
|
||||
if (g!=currentGestureID) {
|
||||
advanceGesture(J);
|
||||
} else if (!mousePressed) {
|
||||
advanceGesture(J);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void advanceGesture(Gesture gesture) {
|
||||
// Move a Gesture one step
|
||||
if (gesture.exists) { // check
|
||||
int nPts = gesture.nPoints;
|
||||
int nPts1 = nPts-1;
|
||||
Vec3f path[];
|
||||
float jx = gesture.jumpDx;
|
||||
float jy = gesture.jumpDy;
|
||||
|
||||
if (nPts > 0) {
|
||||
path = gesture.path;
|
||||
for (int i = nPts1; i > 0; i--) {
|
||||
path[i].x = path[i-1].x;
|
||||
path[i].y = path[i-1].y;
|
||||
}
|
||||
path[0].x = path[nPts1].x - jx;
|
||||
path[0].y = path[nPts1].y - jy;
|
||||
gesture.compile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clearGestures() {
|
||||
for (int i = 0; i < nGestures; i++) {
|
||||
gestureArray[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user