CY_glassDripping_final

11_26_14_53_34

import javax.media.opengl.*;
import javax.media.opengl.glu.*;
import com.sun.opengl.util.FPSAnimator;
import java.nio.*;

GLCanvas canvas;
GLCapabilities capabilities;

int myFrameCount = 0;
int lastMillis = 0;
int fps = 0;

int startedDrop = 0;

myTimer time;
boolean paused = false;
boolean leftPressed = false;
boolean rightPressed = false;
boolean altPressed = false;
boolean ctrlPressed = false;

int myMouseX;
int myMouseY;

float traceX = 0;
float traceY = 0;
float traceZ = 0;

boolean printScreen = false;
boolean screenPrinted = false;
int updateCount = 0;
int currentAgent = 0;

agentGroup[] myAgents;
gString myString;

tailPosition[] myTails;
spaceSphere[] mySpaces;

float gravity = 10;
float maintain = 10;
float adherence = 5;
float inertia = 0.5;
float speed = 3*3;
int meshDensity = 6;
float solidifacation = 0.002*2;

boolean stopped = false;

float meshMin = 40;
float minRadius = 2;
float maxHeight = 100;

boolean toggleShadeDisplay = true;
boolean toggleTransparency = false;
int toggleHistoryDisplay = 0;
boolean toggleSmoothShade = true;
boolean toggleSpaceDisplay = false;
boolean toggleGridDisplay = true;

float mouseXX;
float mouseYY;

float cameraRXX;
float cameraRZZ;
float cameraYY;

float cameraX;
float cameraY;
float cameraZ;

float cameraRX;
float cameraRY;
float cameraRZ;

float cameraTZ;
float cameraTX;
float cameraTZZ;
float cameraTXX;

float cameraClip = 0.1;
float cameraClipC;

int groupAgentNum = 4;

boolean automated = false;

gDrop[] dropArray;
String myTrace = “”;
PFont font;
FPSAnimator animator;

GLRenderer GLRender = new GLRenderer();

int[] listDelete;
boolean listDeleteB = false;

void setup(){
capabilities = new GLCapabilities();
capabilities.setSampleBuffers(true);
capabilities.setNumSamples(8);

canvas = new GLCanvas(capabilities);
canvas.setSize(720, 480);
canvas.addGLEventListener(GLRender);
canvas.addMouseMotionListener(new mouseMotion());
canvas.addMouseListener(new mouseClick());
canvas.addKeyListener(new keyPress());
animator = new FPSAnimator(canvas, 120);
animator.start();
add(canvas);

size(720, 500);

font = createFont(“Tahoma”, 12);
textFont(font);
cameraX = 0;
cameraY = 1800;
cameraZ = 400;
cameraRX = 0;
cameraRY = 0;
cameraRZ = 45;
cameraTZ = -150;
cameraTX = 0;

time = new myTimer();

//set up string
myString = new gString(meshMin);

//set up spaces
int spaceNumber = 24;
//mySpaces = new spaceSphere[spaceNumber*2];
for(int i=0;i
if(i
spaceSphere ss = new spaceSphere(300*sin(radians((360/(spaceNumber))*i-20)),300*cos(radians((360/(spaceNumber))*i-20)), 35*i+50, 150);
addSphere(ss);
}
/* if(i
spaceSphere ss2 = new spaceSphere(400*sin(radians((360/(spaceNumber))*i-40)),400*cos(radians((360/(spaceNumber))*i-40)), 25*i+ 400, 150);
addSphere(ss2);
}*/
spaceSphere ss2 = new spaceSphere(-500+200*sin(radians((360/(spaceNumber))*i)),-150+200*cos(radians((360/(spaceNumber))*i)), 100, 170);
addSphere(ss2);
spaceSphere ss3 = new spaceSphere(-300+200*sin(radians((360/(spaceNumber))*i)),250+200*cos(radians((360/(spaceNumber))*i)), 50, 170);
addSphere(ss3);
spaceSphere ss4 = new spaceSphere(-300+200*sin(radians((360/(spaceNumber))*i)),-200+200*cos(radians((360/(spaceNumber))*i)), 600, 170);
addSphere(ss4);
spaceSphere ss5 = new spaceSphere(-300+200*sin(radians((360/(spaceNumber))*i)),250+200*cos(radians((360/(spaceNumber))*i)), 650, 150);
addSphere(ss5);
spaceSphere ss6 = new spaceSphere(150+200*sin(radians((360/(spaceNumber))*i)),250+200*cos(radians((360/(spaceNumber))*i)), 700, 150);
addSphere(ss6);
}
for(int i=0;i<5;i++){
spaceSphere ss7 = new spaceSphere(0,-300, 40*i, 100);
addSphere(ss7);
}
spaceSphere ss9 = new spaceSphere(250,-200, 20, 100);
addSphere(ss9);

spaceSphere ss8 = new spaceSphere(-700,200, 40, 200);
ss8.closed = false;
addSphere(ss8);
/*for(int i=0;i<20;i++){
spaceSphere ss5 = new spaceSphere(-300,500, 40*i, 30);
addSphere(ss5);
}*/
//get the maxHeight
for(int i=0;i
float tempHei = mySpaces[i].pos[2] + mySpaces[i].radius + 30;
if(tempHei > maxHeight){
maxHeight = tempHei;
}
}
println(“maxHeight = “+maxHeight);

//set up the agents
float wid = 600;
float wid2 = 300;
int agentNumber = 18;
agent[] a = new agent[agentNumber*2];
/*for(int i=0;i
a[i] = new agent(createArray3(random(-wid,wid),random(-wid,wid),15.0), 30, createArray3(0.0,0.0,1.0));
}*/
for(int i=0;i
a[i] = new agent(createArray3(wid*sin(radians((360/(agentNumber))*i)),wid*cos(radians((360/(agentNumber))*i)),15.0), 30, createArray3(0.0,0.0,1.0));
}
for(int i=0;i
a[i+agentNumber] = new agent(createArray3(wid2*sin(radians((360/(agentNumber))*i)),wid2*cos(radians((360/(agentNumber))*i)),15.0), 30, createArray3(0.0,0.0,1.0));
}

myAgents = new agentGroup[agentNumber*2];
for(int i=0;i
myAgents[i] = new agentGroup(a[i], i);
}
}

void draw(){
time.update();
}

class GLRenderer implements GLEventListener {
GL gl;
GLU glu;
public void init(GLAutoDrawable drawable) {
this.gl = drawable.getGL();
this.glu = new GLU();
gl.glClearColor(1, 1, 1, 0);
canvas.setLocation(0, 0);
glInit(gl, glu);
}
//————-rendering loop here———————-
//——————————————————
public void display(GLAutoDrawable drawable) {
//FPS
if(myFrameCount <119){
myFrameCount++;
}
else if(myFrameCount == 119){
int timeUsed = millis() – lastMillis;
fps = round(1200000/timeUsed);
lastMillis = millis();
myFrameCount = 0;
}
//delete displayList
if(listDeleteB){
for(int i=0;i

gl.glDeleteLists(listDelete[i], 1);
}
listDeleteB = false;
}
//
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );
gl.glMatrixMode(GL.GL_PROJECTION); // Select The Projection Matrix
gl.glLoadIdentity();
glu.gluPerspective(45,1.5,cameraClip,10000.0);

gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
glu.gluLookAt(cameraX, cameraY, cameraZ,0,0,0,0,-1,0 );
//————————-
gl.glPushMatrix();

//gl.glRotatef(cameraRY,0,1,0);
gl.glRotatef(cameraRX,1,0,0);
gl.glRotatef(cameraRZ,0,0,1);

gl.glTranslatef(cameraTX, 0, cameraTZ);
if(toggleGridDisplay){
gl.glDisable(GL.GL_LIGHTING);
gl.glDisable(GL.GL_FOG);
gl.glColor3f(0.5,0.5,0.5);
int w = 1000;
gl.glBegin(GL.GL_QUADS);
gl.glNormal3f(0,0,1);
gl.glVertex3f(-w,-w,0);
gl.glVertex3f(w,-w,0);
gl.glVertex3f(w,w,0);
gl.glVertex3f(-w,w,0);
gl.glEnd();
//
gl.glEnable(GL.GL_LIGHTING);
gl.glEnable(GL.GL_FOG);
}

//draw trace
/*gl.glDisable(GL.GL_LIGHTING);
gl.glColor3f(1,0,0);
gl.glPointSize(10);
gl.glBegin(GL.GL_POINTS);
gl.glVertex3f(traceX, traceY, traceZ);
gl.glEnd();
gl.glEnable(GL.GL_LIGHTING);*/

//draw history
if(toggleHistoryDisplay == 1){
//myString.plot(gl);
if(myString.history != null){
myString.plot(gl, myString.history.length-1);
}
}
else if(toggleHistoryDisplay == 2){
for(int i=0;i
myAgents[i].plotHistory(gl);
}
}
if(dropArray != null){
for(int i=0; i
if(toggleShadeDisplay){
if(toggleTransparency){
gl.glColor4f(1,1,1,.5);
}
else{
gl.glColor3f(1,1,1);
}
if(dropArray[i].updating){
if(toggleTransparency){
gl.glColor4f(1,.3,.3,.5);
}
else{
gl.glColor3f(1,.3,.3);
}
dropArray[i].plot(gl);
}
else{
if(dropArray[i].plotList >0){
gl.glCallList(dropArray[i].plotList);
}
else{
dropArray[i].genPlotList(gl);
}
}
}
}
}
//draw space
if(toggleSpaceDisplay){
if(mySpaces != null){
for(int i=0;i
mySpaces[i].plot(gl);
}
}

}

gl.glPopMatrix();

if(printScreen){
FloatBuffer fb=ByteBuffer.allocateDirect(width*(height-20)*12).order(ByteOrder.nativeOrder()).asFloatBuffer();
loadPixels();
gl.glReadPixels( 0,0,width,height-20,GL.GL_RGB,GL.GL_FLOAT,fb);
for(int i=0;i
for(int j=0;j
int k = (i*width+j)*3;
pixels[(height-i-21)*width+j] = color(fb.get(k)*255, fb.get(k+1)*255, fb.get(k+2)*255);
}
}
updatePixels();
printScreen = false;
screenPrinted = true;
}
gl.glFlush();
}

public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
}
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
}
}

//—————————————————
//export
void mayaExportDrop(){
PrintWriter mayaOutput = createWriter(month()+”_”+day()+”_”+hour()+”_”+minute()+”_”+second()+”_drop.mel”);
mayaOutput.println(“select -all;”);
mayaOutput.println(“hide -all;”);
for(int i=0;i
mayaOutput.print(“curve”);
for(int j=0;j
mayaOutput.print(” -p “+dropArray[i].rings[j].pos[0]+” ” +dropArray[i].rings[j].pos[1]+” “+dropArray[i].rings[j].pos[2]);
}
mayaOutput.print(“-d 1”);
mayaOutput.println(“;”);
}
mayaOutput.flush(); // Writes the remaining data to the file
mayaOutput.close(); // Finishes the file
println(“MEL saved (drops)”);
}

void mayaExportRobot(int ID){
PrintWriter mayaOutput = createWriter(month()+”_”+day()+”_”+hour()+”_”+minute()+”_”+second()+”_history_robot.mel”);
//for(int i=0;i
mayaOutput.println(“select -all;”);
mayaOutput.println(“hide -all;”);
for(int j=0;j
//polySphere -ax 0 0 1 -r 10;move 297.38525 234.0122 15.0;
mayaOutput.println(“polySphere -ax 0 0 1 -r 3 -sx 5 -sy 5;”);
mayaOutput.println(“move ” + myAgents[ID].history[j][0]+” “+ myAgents[ID].history[j][1]+” 0;”);
}
mayaOutput.println(“select -all -vis;”);
mayaOutput.println(“polyUnite;”);
//}
mayaOutput.flush(); // Writes the remaining data to the file
mayaOutput.close(); // Finishes the file
println(“MEL saved (robot type:dots, agent: “+ ID+”)”);
}

void mayaExportRobot3(int ID){
PrintWriter mayaOutput = createWriter(month()+”_”+day()+”_”+hour()+”_”+minute()+”_”+second()+”_history_robot3.mel”);
int count = ceil(float(myString.history.length)/myAgents.length);
mayaOutput.println(“select -all;”);
mayaOutput.println(“hide -all;”);
mayaOutput.print(“curve”);
for(int i=0;i
for(int j=0;j
mayaOutput.print(” -p “+myString.history[i*myAgents.length+ID].pPos[j][0]+” ” +myString.history[i*myAgents.length+ID].pPos[j][1]+” 0″);
}
}
mayaOutput.print(“-d 2”);
mayaOutput.println(“;”);

mayaOutput.flush(); // Writes the remaining data to the file
mayaOutput.close(); // Finishes the file
println(“MEL saved (robot type:trajectory, agent: “+ ID+”)”);
}

void mayaExportRobot2(int ID){
PrintWriter mayaOutput = createWriter(month()+”_”+day()+”_”+hour()+”_”+minute()+”_”+second()+”_history_robot2.mel”);
//for(int i=0;i
mayaOutput.println(“select -all;”);
mayaOutput.println(“hide -all;”);
mayaOutput.print(“curve”);
for(int j=0;j
mayaOutput.println(“-p ” + myAgents[ID].history[j][0]+” “+ myAgents[ID].history[j][1]+” 0″);
}

mayaOutput.print(“-d 2”);
mayaOutput.println(“;”);
//}
mayaOutput.flush(); // Writes the remaining data to the file
mayaOutput.close(); // Finishes the file
println(“MEL saved (robot type:trajectory1, agent: “+ ID+”)”);
}

void rhinoExportString(){
PrintWriter rhinoOutput = createWriter(month()+”_”+day()+”_”+hour()+”_”+minute()+”_”+second()+”_String.txt”);
for(int i=0;i
for(int j=0;j
rhinoOutput.print(myString.history[i].pPos[j][0]+”,” +myString.history[i].pPos[j][1]+”,”+myString.history[i].pPos[j][2]+”;”);
}
rhinoOutput.println();
}

rhinoOutput.flush(); // Writes the remaining data to the file
rhinoOutput.close(); // Finishes the file
println(“Rhino Text saved (Strings)”);
}

void mayaExportString(){
PrintWriter mayaOutput = createWriter(month()+”_”+day()+”_”+hour()+”_”+minute()+”_”+second()+”_string.mel”);
int count = 0;
int amount = 500;
int amount2 = ceil(float(myString.history.length)/amount);
for(int k=0;k
mayaOutput.println(“select -all;”);
mayaOutput.println(“hide -all;”);
int amount3 = amount;
if(k == amount2-1){
amount3 = myString.history.length % amount;
}
for(int i=0;i
mayaOutput.print(“curve”);
for(int j=0;j
mayaOutput.print(” -p “+myString.history[i+k*amount].pPos[j][0]+” ” +myString.history[i+k*amount].pPos[j][1]+” “+myString.history[i+k*amount].pPos[j][2]);
}
mayaOutput.print(“-d 1”);
mayaOutput.println(“;”);
}
mayaOutput.println(“select -all -vis;”);
mayaOutput.println(“group -n stringH_”+k+”;”);
}

mayaOutput.flush(); // Writes the remaining data to the file
mayaOutput.close(); // Finishes the file
println(“MEL saved (strings)”);
}

void mayaExportHistory(){
PrintWriter mayaOutput = createWriter(month()+”_”+day()+”_”+hour()+”_”+minute()+”_”+second()+”_history.mel”);
mayaOutput.println(“select -all;”);
mayaOutput.println(“hide -all;”);
for(int i=0;i
mayaOutput.print(“curve”);
for(int j=0;j
mayaOutput.print(” -p “+myAgents[i].history[j][0]+” ” +myAgents[i].history[j][1]+” “+myAgents[i].history[j][2]);
}
mayaOutput.print(“-d 2”);
mayaOutput.println(“;”);
}

mayaOutput.flush(); // Writes the remaining data to the file
mayaOutput.close(); // Finishes the file
println(“MEL saved (history type: trajectory)”);
}

void rhinoExportHistory(){
PrintWriter rhinoOutput = createWriter(month()+”_”+day()+”_”+hour()+”_”+minute()+”_”+second()+”_history.txt”);
for(int i=0;i
for(int j=0;j
rhinoOutput.print(myAgents[i].history[j][0]+”,” +myAgents[i].history[j][1]+”,”+myAgents[i].history[j][2]+”/”+myAgents[i].historyR[j]+”;”);
}
rhinoOutput.println();
}

rhinoOutput.flush(); // Writes the remaining data to the file
rhinoOutput.close(); // Finishes the file
println(“Rhino Text saved (history type: trajectory)”);
}

void mayaExportHistory2(){
PrintWriter mayaOutput = createWriter(month()+”_”+day()+”_”+hour()+”_”+minute()+”_”+second()+”_history_agent.mel”);
for(int i=0;i
mayaOutput.println(“select -all;”);
mayaOutput.println(“hide -all;”);
for(int j=0;j
//polySphere -ax 0 0 1 -r 10;move 297.38525 234.0122 15.0;
mayaOutput.println(“polySphere -ax 0 0 1 -r 3 -sx 5 -sy 5;”);
mayaOutput.println(“move ” + myAgents[i].history[j][0]+” “+ myAgents[i].history[j][1]+” “+ myAgents[i].history[j][2]+”;”);
}
mayaOutput.println(“select -all -vis;”);
mayaOutput.println(“polyUnite;”);
}
mayaOutput.flush(); // Writes the remaining data to the file
mayaOutput.close(); // Finishes the file
println(“MEL saved (history type:dots, agent)”);
}

void mayaExportHistory3(){
PrintWriter mayaOutput = createWriter(month()+”_”+day()+”_”+hour()+”_”+minute()+”_”+second()+”_history_amount.mel”);
int amount = 10;
int total = ceil(float(myAgents[0].history.length)/amount);
for(int k=0;k
mayaOutput.println(“select -all;”);
mayaOutput.println(“hide -all;”);
int amount2 = amount;
if(k == total-1){
amount2 = (myAgents[0].history.length)%amount;
}
for(int i=0;i
for(int j=0;j
//polySphere -ax 0 0 1 -r 10;move 297.38525 234.0122 15.0;
mayaOutput.println(“polySphere -ax 0 0 1 -r 3 -sx 5 -sy 5;”);
mayaOutput.println(“move ” + myAgents[i].history[j+ k*amount][0]+” “+ myAgents[i].history[j+ k*amount][1]+” “+ myAgents[i].history[j+ k*amount][2]+”;”);
}
}
mayaOutput.println(“select -all -vis;”);
mayaOutput.println(“polyUnite;”);
}
mayaOutput.flush(); // Writes the remaining data to the file
mayaOutput.close(); // Finishes the file
println(“MEL saved (history type:dots, amount)”);
}

void mayaExport(){
int total = ceil(float(dropArray.length)/100);
println(“exporting “+total+” MEL…”);
for(int i=0;i
mayaExport2((i+1), total);
}
}

String printPoint(float[] v){
String out = v[0]+”,”+v[1]+”,”+v[2]+”;”;
return out;
}

String printFaceIndex(int a, int b, int c, int d){
String out = a+”,”+b+”,”+c+”,”+d+”;”;
return out;
}

void rhinoExport(){
PrintWriter rhinoOutput = createWriter(month()+”_”+day()+”_”+hour()+”_”+minute()+”_”+second()+”_mesh.txt”);
if(dropArray != null){
for(int i=0;i
int ringLength = dropArray[i].rings.length-1;
//0 is for start vertex
rhinoOutput.print(printPoint(dropArray[i].capStart.pos));
//1 is for end vertex
rhinoOutput.print(printPoint(dropArray[i].rings[ringLength].pos));
//2 ~ 2 + meshDensity-1 (meshDensity +1) is capStart
for(int j=0;j
rhinoOutput.print(printPoint(dropArray[i].capStart.particles[j].pos));
}
//the rest
for(int j=0;j
for(int k=0;k
rhinoOutput.print(printPoint(dropArray[i].rings[j].particles[k].pos));
}
}
rhinoOutput.print(“/”);
//for faces
//cap start
for(int j=0;j
int l = j+1;
if(j == meshDensity – 1)l=0;
rhinoOutput.print(printFaceIndex(l+2,j+2,0,0));
}
//start to first
for(int j=0;j
int l = j+1;
if(j == meshDensity – 1)l=0;
rhinoOutput.print(printFaceIndex(j+2,l+2,l+meshDensity +2, j+meshDensity +2));
}
//the rest
for(int k=1;k
for(int j=0;j
int l = j+1;
if(j == meshDensity – 1)l=0;
rhinoOutput.print(printFaceIndex(j+(meshDensity)*k+2,l+(meshDensity)*k+2,l+(meshDensity)*(k+1)+2,j+(meshDensity)*(k+1)+2));
}
}
//capend
for(int j=0;j
int l = j+1;
if(j == meshDensity – 1)l=0;
rhinoOutput.print(printFaceIndex(j+(meshDensity)*(ringLength+1)+2,l+(meshDensity)*(ringLength+1)+2,1,1));
}

rhinoOutput.println();
}
}

rhinoOutput.flush(); // Writes the remaining data to the file
rhinoOutput.close(); // Finishes the file
println(“Rhino saved”);
}

void mayaExport2(int id, int total){
PrintWriter mayaOutput = createWriter(month()+”_”+day()+”_”+hour()+”_”+minute()+”_”+second()+”_”+id+”of”+total+”.mel”);
mayaOutput.println(“select -all;”);
mayaOutput.println(“hide -all;”);
int l;
int start;
if(id == total){
l = dropArray.length;
}
else{
l=id*100;
}
start = (id-1)*100;
if(dropArray != null){
for(int i=start;i
for(int j=0;j
//export the main geometry
if(j
for(int k=0;k< meshDensity;k++){
int t = k+1;
if(t>meshDensity-1){
t=0;
}
mayaOutput.println(exportQuad(dropArray[i].rings[j].particles[k].pos, dropArray[i].rings[j+1].particles[k].pos, dropArray[i].rings[j+1].particles[t].pos, dropArray[i].rings[j].particles[t].pos));
}
}
}
//export the added starting ring
//export the starting and ending cap
int ringLength = dropArray[i].rings.length-1;
for(int k=0;k< meshDensity;k++){
int t = k+1;
if(t>meshDensity-1){
t=0;
}
mayaOutput.println(exportQuad(dropArray[i].capStart.particles[k].pos, dropArray[i].rings[0].particles[k].pos, dropArray[i].rings[0].particles[t].pos, dropArray[i].capStart.particles[t].pos));
mayaOutput.println(exportTri(dropArray[i].capStart.particles[k].pos, dropArray[i].capStart.particles[t].pos, dropArray[i].capStart.pos));
mayaOutput.println(exportTri(dropArray[i].rings[ringLength].particles[k].pos, dropArray[i].rings[ringLength].particles[t].pos, dropArray[i].rings[ringLength].pos));
}
mayaOutput.println(“select -all -vis;”);
mayaOutput.println(“polyUnite;”);
mayaOutput.println(“delete -ch;”);
}
}
mayaOutput.println(“select -all -vis;”);
mayaOutput.println(“polyMergeVertex -d 0.1;”);
mayaOutput.println(“select -all -vis;”);
mayaOutput.println(“polySoftEdge -a 180;”);
mayaOutput.println(“select -all -vis;”);
mayaOutput.println(“polyCleanupArgList 3 { \”1\”,\”1\”,\”0\”,\”0\”,\”0\”,\”0\”,\”0\”,\”0\”,\”0\”,\”1e-005\”,\”0\”,\”1e-005\”,\”0\”,\”1e-005\”,\”0\”,\”1\”,\”1\” };”);
mayaOutput.println(“delete -ch;”);
mayaOutput.flush(); // Writes the remaining data to the file
mayaOutput.close(); // Finishes the file
println(“MEL saved (“+id+” of “+total+”)”);
}

String exportQuad(float[] pos1, float[] pos2, float[] pos3, float[] pos4){
String out;
out = “polyCreateFacet”;
out += ” -p “+pos1[0]+” “+pos1[1]+” “+pos1[2];
out += ” -p “+pos2[0]+” “+pos2[1]+” “+pos2[2];
out += ” -p “+pos3[0]+” “+pos3[1]+” “+pos3[2];
out += ” -p “+pos4[0]+” “+pos4[1]+” “+pos4[2];
out += “;”;
return out;
}

String exportTri(float[] pos1, float[] pos2, float[] pos3){
String out;
out = “polyCreateFacet”;
out += ” -p “+pos1[0]+” “+pos1[1]+” “+pos1[2];
out += ” -p “+pos2[0]+” “+pos2[1]+” “+pos2[2];
out += ” -p “+pos3[0]+” “+pos3[1]+” “+pos3[2];
out += “;”;
return out;
}

//—————————————————
//UI
class keyPress implements KeyListener{
public void keyPressed(KeyEvent e){
if(e.getKeyCode() == 90){//z
// cameraTZ = 0;
cameraClip = 0.1;
}
else if(e.getKeyCode() ==79){//o
toggleTransparency = !toggleTransparency;
}
else if(e.getKeyCode() ==74){//j
toggleSmoothShade = !toggleSmoothShade;
}
else if(e.getKeyCode() ==76){//l
toggleShadeDisplay = !toggleShadeDisplay;
}
else if(e.getKeyCode() ==85){//u
toggleGridDisplay = !toggleGridDisplay;
}else if(e.getKeyCode() ==73){//i
toggleSpaceDisplay = !toggleSpaceDisplay;
}
else if(e.getKeyCode()==75){//k
toggleHistoryDisplay++;
if(toggleHistoryDisplay>2){
toggleHistoryDisplay = 0;
}
}
else if(e.getKeyCode()==80){//p
paused = !paused;
}
else if(e.getKeyCode() == 77){//m
mayaExport();
mayaExportDrop();
mayaExportString();
mayaExportHistory();
mayaExportHistory2();
mayaExportHistory3();
mayaExportRobot(0);
mayaExportRobot2(0);
mayaExportRobot3(0);
//
println(“MEL export finished!!”);
}
else if(e.getKeyCode() == 69){//e
rhinoExportHistory();
rhinoExportString();
rhinoExport();
println(“Rhino export finished!!”);
}
else if(e.getKeyCode() == 78){//n
printScreen = true;
}
else if(e.getKeyCode() == 18){//alt
if(!altPressed){
altPressed = true;
}
}
else if(e.getKeyCode() == 17){//ctrl
if(!ctrlPressed){
ctrlPressed = true;
}
}else{
println(“keyCode = ” + e.getKeyCode());
}
}
public void keyReleased(KeyEvent e){
//println(e.getKeyCode());
if(e.getKeyCode() == 18){//alt
altPressed = false;
}
else if(e.getKeyCode() == 17){//ctrl
ctrlPressed = false;
}
}
public void keyTyped(KeyEvent e){
if(e.getKeyCode() == 90){//y
print(“y”);
}
}
}

class mouseClick implements MouseListener{
public void mouseClicked(MouseEvent e){
}
public void mouseEntered(MouseEvent e){
}
public void mouseExited(MouseEvent e){
}
public void mousePressed(MouseEvent e){
//println(e.getButton());
mouseXX = myMouseX;
mouseYY = myMouseY;
cameraRXX = cameraRX;
cameraRZZ = cameraRZ;
cameraTXX = cameraTX;
cameraTZZ = cameraTZ;
cameraYY = cameraY;
cameraClipC = cameraClip;
if(e.getButton()==1){
if(!leftPressed){
leftPressed = true;
}
}
if(e.getButton()==3){
if(!rightPressed){
rightPressed = true;
}
}
}
public void mouseReleased(MouseEvent e){
if(e.getButton()==1){
leftPressed = false;
}
if(e.getButton()==3){
rightPressed = false;
}
}
}

class mouseMotion implements MouseMotionListener{
public void mouseMoved(MouseEvent e){
myMouseX = e.getX();
myMouseY = e.getY();
}
public void mouseDragged(MouseEvent e){
myMouseX = e.getX();
myMouseY = e.getY();
if(leftPressed){
if(altPressed){
cameraClip = cameraClipC + (myMouseY – mouseYY);
//println(cameraClip);
if(cameraClip < 0.1){
cameraClip = 0.1;
}
}
else if(ctrlPressed){
cameraTZ = cameraTZZ – (myMouseY – mouseYY)/2;
}else{
cameraRZ = cameraRZZ + (myMouseX – mouseXX)/2;
cameraRX = cameraRXX – (myMouseY – mouseYY)/2;
}
}
else if(rightPressed){
cameraY = cameraYY – (myMouseY – mouseYY)*5;
}
}
}

class agent{
float[] pos = new float[3];
float radius;
float[] direction = new float[3];
float[][] history;

agent(float[] p, float r, float[] d){
pos = p;
radius = r;
direction = d;
}

void checkHeight(){
float dropHeight = radius/2;
if(dropArray != null){
for(int i=0;i
if(!dropArray[i].updating){
for(int j=0;j
if(dropArray[i].rings[j].radius>minRadius){
float tD = getDistance(createArray2(pos[0], pos[1]), createArray2(dropArray[i].rings[j].pos[0], dropArray[i].rings[j].pos[1]));
if(tD < (radius + dropArray[i].rings[j].radius)*0.8){
float tH = sqrt(sq(radius + dropArray[i].rings[j].radius)+ sq(tD))*0.6 + dropArray[i].rings[j].pos[2];
if(tH > dropHeight){
dropHeight = tH;
}
}
}
}
}
}
}
pos[2] = dropHeight;
}

boolean checkInSpace(){
boolean out = false;
//check if its in a sphere space
if(mySpaces != null){
for(int i=0;i
float sD = getDistance(pos, mySpaces[i].pos);
if(sD
float[] sVector = getVector(mySpaces[i].pos, pos);
float rad = sqrt(sq(mySpaces[i].radius)-sq(sVector[2]));
float rad2 = sqrt(sq(sVector[0]) + sq(sVector[1]));
sVector[0] *= rad/rad2;
sVector[1] *= rad/rad2;
pos = addVector(mySpaces[i].pos, sVector);
checkHeight();
float dis = abs(pos[2] – mySpaces[i].pos[2]);
float dis2 = sqrt(sq(mySpaces[i].radius) – sq(dis));
if(dis> mySpaces[i].radius){
dis2 = 0;
}
float dis3 = getDistance(createArray2(pos[0],pos[1]), createArray2(mySpaces[i].pos[0],mySpaces[i].pos[1]));
sVector = getVector(pos, mySpaces[i].pos);
if(dis2 != 0){
sVector[0] *= 1-(dis2/dis3);
sVector[1] *= 1-(dis2/dis3);
}
else{
sVector[2] = 0;
sVector = unifyVector(sVector);
sVector = multiplyVector(sVector, radius*0.1);
}
sVector = rotateZZ(sVector[0], sVector[1], sVector[2], radians(random(10)-5));
pos = addVector(pos, sVector);
checkHeight();

out = true;
}
}
}
return out;
}

void update(int id, int spaceID){

//set the radius according to the relationship with the space
float zDist = abs(pos[2] – mySpaces[spaceID].pos[2]);
//int radiusType = 0;
float rad = 15;
if(zDist > mySpaces[spaceID].radius){
if(zDist – mySpaces[spaceID].radius > 30){
rad = random(15,20);
}
else{
rad = random(5,10);
}
}
else{
rad = 5 + abs(mySpaces[spaceID].radius-zDist)*15/mySpaces[spaceID].radius;
}
float movement = 1.5;
if(pos[2] – mySpaces[spaceID].pos[2] > mySpaces[spaceID].radius-50){
if(pos[2] – mySpaces[spaceID].pos[2] < mySpaces[spaceID].radius+100){
movement = .7;
}
else{
movement = 4;
}
}

float lastRadius = radius+1;
lastRadius–;
radius = rad;

float[] tempV = new float[3];
tempV = unifyVector(direction);
for(int i = 0; i<3; i++){
pos[i] += tempV[i]*(radius+lastRadius)*movement;
}
//check if there is any existing geometry under it
checkHeight();

/* int dCount = 0;
while(checkInSpace() && dCount < 3){
checkHeight();
dCount ++;
}*/
checkInSpace();
//checkHeight();

//check on collision
boolean collision = true;
int detectTime = 0;
while(collision && detectTime <10){
collision = checkCollision();
detectTime ++;
if(detectTime>9){
println(“can’t avoid collision”);
}
}
}

boolean checkCollision(){
boolean out = false;
if(dropArray != null){
for(int i=0;i
for(int j=0;j
float d = getDistance(dropArray[i].rings[j].pos, pos);
if(d< (dropArray[i].rings[j].radius+radius)*0.6){
//println(“collision!”);
d = (dropArray[i].rings[j].radius+radius)*0.8-d;
out = true;
float[] tV = new float[3];
for(int k = 0;k<3;k++){
tV[k] = pos[k] – dropArray[i].rings[j].pos[k];
}
if(tV[2] ==0){
tV[2] = 1;
}
else if(tV[2]<0){
tV[2] = -tV[2];
}
tV = unifyVector(tV);
for(int k = 0;k<3;k++){
pos[k] += tV[k]*d;
}
}
}
}
}
return out;
}
}

class agentGroup{
int ID;
int phase = 0;
int[] chase;
int[] avoid;
int tailon;
agent[] agents = new agent[2];
float[] oDirection = new float[3];
float[][] history;
float[] historyR;
int lastEmergedID;

agentGroup(agent a1, int id){
agents[0] = a1;
float[] t1 = {
0,0,0 };
float[] t2 = {
0,0,0 };
agents[1] = new agent(t1, 20, t2);
ID = id;
lastEmergedID = id;
//parent = p;
for(int i=0;i<3;i++){
oDirection[i] = agents[0].direction[i];
}
}

void update(){
for(int i=0;i<3;i++){
agents[0].direction[i] = 0;
}
//float[] oriPos = cloneVector(agents[0].pos);

//check if its already too high
if(agents[0].pos[2] > maxHeight){
int lowestID = -1;
float lowest = maxHeight;
//find the lowest agent
for(int i=0;i
if(i != ID){
if(myAgents[i].agents[0].pos[2] < lowest){
lowestID = i;
lowest = myAgents[i].agents[0].pos[2];
}
}
}
//move its position to the lowest
if(lowestID != -1){
agents[0].pos = createArray3(myAgents[lowestID].agents[0].pos[0]+random(-25,25),myAgents[lowestID].agents[0].pos[1]+random(-25,25),myAgents[lowestID].agents[0].pos[2]);
//println(“move to lowest agent”);
}
else{
println(“everyone is above maxHeight!!”);
paused = true;
}

}

//move farer the closest
float[] tClose = createArray3(0,0,0);
float range = 2000;
for(int i=0;i
if(i != ID){
float dis = getDistance(createArray2(agents[0].pos[0], agents[0].pos[1]), createArray2(myAgents[i].agents[0].pos[0], myAgents[i].agents[0].pos[1]));
if(dis
range = dis;
if(range < 200){
//println(“robots too close”);
tClose = getVector(myAgents[i].agents[0].pos, agents[0].pos);
tClose[2] = 0;
tClose = unifyVector(tClose);
}
}
}
}

//move toward the closest space
float[] tSpace = new float[3];
float spaceDist = 200000;
int spaceID = -1;
int spaceType = -1;//0:sphere 1: square
if(mySpaces != null){
for(int i=0;i
if(mySpaces[i].closed){
float sD = getDistance(agents[0].pos, mySpaces[i].pos)-mySpaces[i].radius;
if(spaceDist>sD){
spaceDist = sD;
spaceID = i;
spaceType = 0;
}
}
}
}

if(spaceType ==0){
if(spaceID>-1){
tSpace = getVector(agents[0].pos, mySpaces[spaceID].pos);
}
}

tSpace[2] = 0;
tSpace = unifyVector(tSpace);

agents[0].direction = addVector(agents[0].direction, tClose);
agents[0].direction = addVector(agents[0].direction, tSpace);

agents[0].direction = unifyVector(agents[0].direction);
//
/*float rnd = random(1);
if(rnd>0.5&&spaceID>-1){
float dis = agents[0].pos[2] – mySpaces[spaceID].pos[2];
if(dis > 0){
float dis2 = mySpaces[spaceID].radius – dis;
if(dis2 < 0){
dis2 = 0;
}
agents[0].direction = multiplyVector(agents[0].direction, (0.1 + 0.2*dis2));
}
}*/

agents[0].update(ID,spaceID);

//put the tail backward to the space(spaceID)
float[] tailVector = createArray3(0,0,0);
float rnd3;
rnd3 =mySpaces[spaceID].radius+150;
float rndHeight;
if(abs(mySpaces[spaceID].pos[2] – agents[0].pos[2]) > mySpaces[spaceID].radius – 100){
rndHeight = random(50,70);
rnd3 += 100;
}
else{
rndHeight = random(100,600);

}
tailVector= getVector(mySpaces[spaceID].pos,agents[0].pos);

//modify tailVector to avoid all nearby spaces
float[] tVector = createArray3(0,0,0);
for(int i=0;i
if(getDistance(mySpaces[i].pos, agents[0].pos) < 500){
float[] tempV = getVector(mySpaces[i].pos,agents[0].pos);
tempV = unifyVector(tempV);
tVector = addVector(tVector, tempV);
}
}
tVector = unifyVector(tVector);
//rnd3 =mySpaces[spaceID].radius – tVector[2]+100;

tailVector = unifyVector(tailVector);
for(int i=0;i<2;i++){
agents[1].direction[i] = rnd3*tailVector[i];
}
agents[1].direction[2] = rndHeight;
//agents[1].direction = rotateZZ(agents[1].direction[0], agents[1].direction[1],agents[1].direction[2],radians(random(30)-15));
for(int i=0;i<3;i++){
agents[1].pos[i] = agents[0].pos[i]+ agents[1].direction[i];
}

//assign String
myString.update(agents[0].pos[0],agents[0].pos[1],agents[0].pos[2],
agents[1].pos[0],agents[1].pos[1],agents[1].pos[2],agents[0].radius,random(2.5,4));
myString.createDrop();
addHistory(createArray3(agents[0].pos[0],agents[0].pos[1],agents[0].pos[2]), agents[0].radius);

}

void addHistory(float[] h, float r){
if(history != null){
float[][] tempH = new float[history.length+1][3];
arraycopy(history, tempH);
tempH[history.length] = h;
history = tempH;

float[] tempHR = new float[history.length+1];
arraycopy(historyR, tempHR);
tempHR[history.length] = r;
historyR = tempHR;
}
else{
history = new float[1][3];
history[0] = h;
historyR = new float[1];
historyR[0] = r;
}
}
void plotHistory(GL _gl){
if(history != null){
_gl.glDisable(GL.GL_LIGHTING);
_gl.glColor3f(0,0,0);
_gl.glPointSize(3);
_gl.glBegin(GL.GL_POINTS);
for(int i=0;i
_gl.glVertex3f(history[i][0],history[i][1],history[i][2]);
}

_gl.glEnd();
_gl.glEnable(GL.GL_LIGHTING);
}
}
}

//—————————————————
//GLASSDROP CLASS DROP/RING/PARTICLE
class gDrop{
int ID;
gRing[] rings;
gRing capStart;
gParticle[] cap = new gParticle[2];
float[] direction = new float[3];
boolean updating = true;
boolean ended = false;
float range;
float[] volume = new float[6];
int plotList;

gDrop(int id, float x1, float y1, float z1, float x2, float y2, float z2, float r){
ID = id;
direction[0] = x2-x1;
direction[1] = y2-y1;
direction[2] = z2-z1;
int[] tempid = {
id, 0 };
int[] tempid2 = {
id, -1 };
rings = new gRing[1];
//unify direction
float[] dir = {
x2,y2,z2 };
dir = unifyVector(dir);
rings[0] = new gRing(tempid, x1, y1, z1, dir[0], dir[1], dir[2], r);
capStart = new gRing(tempid2, x1 – dir[0]*(r/2), y1- dir[1]*(r/2), z1- dir[2]*(r/2), x2, y2, z2, r/2);
cap[0] = new gParticle(tempid, 0,0,0);
cap[1] = new gParticle(tempid, 0,0,0);
range = r;
}

void updateVolume(){
volume[0] = rings[0].pos[0]+rings[0].radius;
volume[1] = rings[0].pos[1]+rings[0].radius;
volume[2] = rings[0].pos[2]+rings[0].radius;
volume[3] = rings[0].pos[0]-rings[0].radius;
volume[4] = rings[0].pos[1]-rings[0].radius;
volume[5] = rings[0].pos[2]-rings[0].radius;
for( int i=1;i
if(rings[i].pos[0] + rings[i].radius > volume[0]){
volume[0] = rings[i].pos[0] + rings[i].radius;
}
if(rings[i].pos[1] + rings[i].radius > volume[1]){
volume[1] = rings[i].pos[1] + rings[i].radius;
}
if(rings[i].pos[2] + rings[i].radius > volume[2]){
volume[2] = rings[i].pos[2] + rings[i].radius;
}
if(rings[i].pos[0] – rings[i].radius < volume[3]){
volume[3] = rings[i].pos[0] – rings[i].radius;
}
if(rings[i].pos[1] – rings[i].radius < volume[4]){
volume[4] = rings[i].pos[1] – rings[i].radius;
}
if(rings[i].pos[2] – rings[i].radius < volume[5]){
volume[5] = rings[i].pos[2] – rings[i].radius;
}
}
}

void addRing(float x1, float y1, float z1, float x2, float y2, float z2, float r){
int[] tempid = {
ID, rings.length };
gRing tempRing = new gRing(tempid, x1, y1, z1, x2, y2, z2, r);
gRing[] tempArray = new gRing[rings.length+1];
arraycopy(rings, tempArray);
tempArray[rings.length] = tempRing;
rings = tempArray;
range = getDistance(rings[rings.length-1].pos, rings[0].pos);
}

void cutDrop(int pos){
gRing[] tempArray = new gRing[pos];
arraycopy(rings,0, tempArray,0,pos);
rings = tempArray;
updateVolume();
//put the plotlist to delete
if(!listDeleteB){
listDelete = new int[1];
listDelete[0] = plotList;
listDeleteB = true;
}
else{
int[] temp2 = new int[listDelete.length+1];
arraycopy(listDelete, temp2);
temp2[listDelete.length] = plotList;
listDelete = temp2;
}
plotList = 0;
}

void deleteRing(){
gRing[] tempArray = new gRing[rings.length-1];
arraycopy(rings,0, tempArray,0,rings.length-1);
rings = tempArray;
}
void update(){
int solid = 0;
for(int i = 0; i
if(i>0){
if(rings[i].liquefaction !=0){
rings[i].update(true);
}
else{
rings[i].update(false);
solid++;
}
}
else{
rings[i].update(false);
solid++;
}
}
if(ended){
if(solid == rings.length){
updating = false;
updateVolume();
// genPlotList(GLRender.gl);
}
}
if(capStart !=null){
capStart.update(false);
cap[0].pos = capStart.pos;
cap[1].pos = rings[rings.length-1].pos;
}
updateFaceNormal();
for(int i=0;i
for(int j=0;j
rings[i].particles[j].updateNormal();
}
}
for(int j=0;j
capStart.particles[j].updateNormal();
}
cap[0].updateNormal();
cap[1].updateNormal();
}
void getQuadNormal(int r1, int r2, int p1, int p2){
float[] v1 = new float[3];
float[] v2 = new float[3];
for(int i=0;i<3;i++){
v1[i] = rings[r1].particles[p1].pos[i]-rings[r1].particles[p2].pos[i];
v2[i] = rings[r2].particles[p1].pos[i]-rings[r1].particles[p1].pos[i];
}
float[] nor = crossProduct(v1, v2);
nor = unifyVector(nor);
rings[r1].particles[p1].addFaceNormal(nor);
rings[r1].particles[p2].addFaceNormal(nor);
rings[r2].particles[p1].addFaceNormal(nor);
rings[r2].particles[p2].addFaceNormal(nor);
}
void getQuadNormal(int r1, int p1, int p2){
float[] v1 = new float[3];
float[] v2 = new float[3];
for(int i=0;i<3;i++){
v1[i] = capStart.particles[p1].pos[i]-capStart.particles[p2].pos[i];
v2[i] = rings[r1].particles[p1].pos[i]-capStart.particles[p1].pos[i];
}
float[] nor = crossProduct(v1, v2);
nor = unifyVector(nor);
rings[r1].particles[p1].addFaceNormal(nor);
rings[r1].particles[p2].addFaceNormal(nor);
capStart.particles[p1].addFaceNormal(nor);
capStart.particles[p2].addFaceNormal(nor);
}
void getTriNormal(int r1, int p1,int p2){
float[] v1 = new float[3];
float[] v2 = new float[3];
for(int i=0;i<3;i++){
v1[i] = rings[r1].particles[p1].pos[i]-rings[r1].particles[p2].pos[i];
v2[i] = cap[1].pos[i]-rings[r1].particles[p1].pos[i];
}
float[] nor = crossProduct(v1, v2);
nor = unifyVector(nor);
rings[r1].particles[p1].addFaceNormal(nor);
rings[r1].particles[p2].addFaceNormal(nor);
cap[1].addFaceNormal(nor);
}
void getTriNormal(int p1,int p2){
float[] v1 = new float[3];
float[] v2 = new float[3];
for(int i=0;i<3;i++){
v2[i] = capStart.particles[p1].pos[i]-cap[0].pos[i];
v1[i] = cap[0].pos[i]-capStart.particles[p2].pos[i];
}
float[] nor = crossProduct(v1, v2);
nor = unifyVector(nor);
capStart.particles[p1].addFaceNormal(nor);
capStart.particles[p2].addFaceNormal(nor);
cap[0].addFaceNormal(nor);
}

void updateFaceNormal(){
for(int i = 0; i
if(i
for(int j = 0; j
int t = j+1;
if(t>meshDensity-1){
t=0;
}
getQuadNormal(i, i+1, t, j);
}
}
}
for(int j = 0; j
int t = j+1;
if(t>meshDensity-1){
t=0;
}
getQuadNormal(0, t, j);
getTriNormal(rings.length-1, t,j);
getTriNormal(t,j);
}
}

void plotRings(GL _gl){
if(rings != null){
for(int i = 0; i
_gl.glBegin(GL.GL_LINES);
_gl.glColor3f(0,0,1);
_gl.glVertex3f(rings[i].pos[0], rings[i].pos[1],rings[i].pos[2]);
_gl.glVertex3f(rings[i].pos[0]+rings[i].myAxis[2][0]*rings[i].radius, rings[i].pos[1]+rings[i].myAxis[2][1]*rings[i].radius,rings[i].pos[2]+rings[i].myAxis[2][2]*rings[i].radius);
_gl.glEnd();
_gl.glBegin(GL.GL_LINES);
_gl.glColor3f(1,0,0);
_gl.glVertex3f(rings[i].pos[0], rings[i].pos[1],rings[i].pos[2]);
_gl.glVertex3f(rings[i].pos[0]+rings[i].myAxis[0][0]*rings[i].radius, rings[i].pos[1]+rings[i].myAxis[0][1]*rings[i].radius,rings[i].pos[2]+rings[i].myAxis[0][2]*rings[i].radius);
_gl.glEnd();
_gl.glBegin(GL.GL_LINES);
_gl.glColor3f(0,1,0);
_gl.glVertex3f(rings[i].pos[0], rings[i].pos[1],rings[i].pos[2]);
_gl.glVertex3f(rings[i].pos[0]+rings[i].myAxis[1][0]*rings[i].radius, rings[i].pos[1]+rings[i].myAxis[1][1]*rings[i].radius,rings[i].pos[2]+rings[i].myAxis[1][2]*rings[i].radius);
_gl.glEnd();
}
}
}

void genPlotList(GL _gl){
plotList = _gl.glGenLists(1);
int w = 2000;
_gl.glNewList(plotList,GL.GL_COMPILE);
plot(_gl);
_gl.glEndList();
}

void plot(GL _gl){
if(rings != null){
for(int i = 0; i
if(i
for(int j = 0; j
int t = j+1;
if(t>meshDensity-1){
t=0;
}
if(!toggleSmoothShade){
drawQuad2(_gl, rings[i].particles[t].pos,rings[i+1].particles[t].pos, rings[i+1].particles[j].pos,rings[i].particles[j].pos );
}
else{
drawQuad(_gl, rings[i].particles[t].pos,rings[i+1].particles[t].pos, rings[i+1].particles[j].pos,rings[i].particles[j].pos,
rings[i].particles[t].myNormal, rings[i+1].particles[t].myNormal, rings[i+1].particles[j].myNormal, rings[i].particles[j].myNormal );
}
}
}
}
//draw the starting and ending cap
for(int j = 0; j
int t = j+1;
if(t>meshDensity-1){
t=0;
}
if(!toggleSmoothShade){
drawQuad2(_gl, capStart.particles[t].pos, rings[0].particles[t].pos,rings[0].particles[j].pos,capStart.particles[j].pos );
drawTri2(_gl,capStart.pos, capStart.particles[t].pos,capStart.particles[j].pos );
drawTri2(_gl, rings[rings.length-1].particles[j].pos, rings[rings.length-1].particles[t].pos, rings[rings.length-1].pos);
}
else{
drawQuad(_gl, capStart.particles[t].pos, rings[0].particles[t].pos,rings[0].particles[j].pos,capStart.particles[j].pos,
capStart.particles[t].myNormal, rings[0].particles[t].myNormal , rings[0].particles[j].myNormal,capStart.particles[j].myNormal );
drawTri(_gl,capStart.pos, capStart.particles[t].pos,capStart.particles[j].pos,
cap[0].myNormal, capStart.particles[t].myNormal, capStart.particles[j].myNormal);
drawTri(_gl,rings[rings.length-1].particles[j].pos, rings[rings.length-1].particles[t].pos, rings[rings.length-1].pos,
rings[rings.length-1].particles[j].myNormal, rings[rings.length-1].particles[t].myNormal, cap[1].myNormal);
}
}
}
}
}

class gRing{
int[] ID;
float[] pos = new float[3];
float[] direction = new float[3];
float[] motion = new float[3];
float radius;
float liquefaction = 1;
float[][] myAxis = new float[3][3];
gParticle[] particles = new gParticle[meshDensity];

gRing(int[] id, float x1, float y1, float z1, float x2, float y2, float z2, float r){
ID = id;
pos[0] = x1;
pos[1] = y1;
pos[2] = z1;
direction[0] = x2;
direction[1] = y2;
direction[2] = z2;
motion[0] =0;
motion[1] =0;
motion[2] =0;
radius = r;

for(int i =0; i
int[] tempID = new int[3];
tempID[0] = id[0];
tempID[1] = id[1];
tempID[2] = i;
particles[i] = new gParticle(tempID, 0, 0, 0);
}
//updateParticles();
}

void updateParticles(){
//uniify the direction
myAxis[2] = unifyVector(direction);
float[] t = {
0,0,1 };
float angle = getVectorAngle(myAxis[2],t);
if(angle<1&&angle>-1){
//use the drop direction as axis
float[] tempDirection = unifyVector(dropArray[ID[0]].direction);
myAxis[0] = unifyVector(crossProduct(myAxis[2], tempDirection));
myAxis[1] = unifyVector(crossProduct(myAxis[2], myAxis[0]));
}
else{
myAxis[0] = unifyVector(crossProduct(myAxis[2], t));
myAxis[1] = unifyVector(crossProduct(myAxis[2], myAxis[0]));
}
for(int i =0; i
float[] temp2 = new float[3];
for(int j=0; j<3;j++){
temp2[j] = radius*(myAxis[1][j]*sin(i*TWO_PI/meshDensity) + (myAxis[0][j]*cos(i*TWO_PI/meshDensity)));
temp2[j] += pos[j];
}
particles[i].pos = temp2;
}
}

void update(boolean move){
if(liquefaction>0){
if(move){
//adhere to solid surface
boolean adhered = false;
//check the distance between all existing rings
int i2=0;
while(i2
if(i2 != ID[0]){//check if its self
//check the distance with the first ring
if(pos[0] < dropArray[i2].volume[0] && pos[0] > dropArray[i2].volume[3]
&& pos[1] < dropArray[i2].volume[1] && pos[1] > dropArray[i2].volume[4]
&& pos[2] < dropArray[i2].volume[2] && pos[2] > dropArray[i2].volume[5]){
for(int j=0;j
float d = getDistance(pos, dropArray[i2].rings[j].pos);
if(dropArray[i2].rings[j].radius>minRadius || radius == minRadius){
if(d < (radius + dropArray[i2].rings[j].radius)*0.8){
liquefaction = 0;
adhered = true;
}
}
else if(radius> minRadius){//check if have to destroy the drop
if(d < (radius + meshMin/2)){
dropArray[i2].cutDrop(j);
// println(“cut”);
}
}
}
}
}
i2++;
}
if(!adhered){
//movement
float[] tempD = new float[3];
//add the garvity
//
tempD[2] -= gravity;
//move toward the center of next and last rings
if(ID[1] >0 && ID[1]
float[] goal = new float[3];
float d1 = dropArray[ID[0]].rings[ID[1]-1].radius+radius;
float d2 = dropArray[ID[0]].rings[ID[1]+1].radius+radius;
if(d1
d1 = meshMin;
}
if(d2
d2 = meshMin;
}
float d3 = getDistance(pos, dropArray[ID[0]].rings[ID[1]-1].pos);
float d4 = getDistance(pos, dropArray[ID[0]].rings[ID[1]+1].pos);
float d5 = d3 + d4 – d1 – d2;
for(int i=0;i<3;i++){
goal[i] = dropArray[ID[0]].rings[ID[1]+1].pos[i]-dropArray[ID[0]].rings[ID[1]-1].pos[i];
goal[i] *= (d1)/(d1+d2);
goal[i] += dropArray[ID[0]].rings[ID[1]-1].pos[i];
}
float[] tempDDD = getMaintainForce(0, pos, goal, maintain/10);//originally maintain/3
for(int i =0;i<3;i++){
tempD[i] += tempDDD[i];
}
}
//the force with lastRing
if(ID[1] >0){
float distanceT = dropArray[ID[0]].rings[ID[1]-1].radius+radius;
if(distanceT
distanceT = meshMin;
}
float[] tempDD = getMaintainForce(distanceT, pos, dropArray[ID[0]].rings[ID[1]-1].pos, maintain);
for(int i=0; i<3;i++){
tempD[i] += tempDD[i];
}
}
//unify the vector
tempD = unifyVector(tempD);
//move the vector
for(int i=0;i<3;i++){
pos[i] += tempD[i]*liquefaction*speed;
}
if(pos[2]
pos[2] = radius;
liquefaction = 0;
}
}
liquefaction -= solidifacation;
}
}
else{
liquefaction = 0;
}
int ringNum = 0;
float[] tempD = {
0,0,0 };
//get the direction with the last ring
float[] dArray2 = new float[3];
float[] dArray = new float[3];
if(ID[1] > 0){//if its not the first ring
for(int i=0;i<3;i++){
dArray[i] = pos[i] – dropArray[ID[0]].rings[ID[1]-1].pos[i];
}
dArray = unifyVector(dArray);
//direction = dArray;
for(int i=0;i<3;i++){
tempD[i] += dArray[i];
}
ringNum++;
}
if(ID[1] < dropArray[ID[0]].rings.length-1&& ID[1]>-1){//get the direction to next ring
for(int i=0;i<3;i++){
dArray2[i] = dropArray[ID[0]].rings[ID[1]+1].pos[i] – pos[i];
}
dArray2 = unifyVector(dArray2);
for(int i=0;i<3;i++){
tempD[i] += dArray2[i];
}
ringNum++;
}
if(ID[1] == -1){//if its the capstart ring
//get the new position, direction, r
dArray = unifyVector(dropArray[ID[0]].rings[0].direction);
float r = dropArray[ID[0]].rings[0].radius/2;
for(int i=0;i<3;i++){
pos[i] = dropArray[ID[0]].rings[0].pos[i] – dArray[i]*r;
}
radius = r;
dArray = unifyVector(dArray);
//direction = dArray;
for(int i=0;i<3;i++){
tempD[i] += dArray[i];
}
ringNum++;
}
if(ringNum>0){
direction = unifyVector(tempD);
}
//update the particles position
updateParticles();
}

float[] getMaintainForce(float originDist, float[] sp, float[] p, float m){
float distance = getDistance(sp, p);
//distance -= originDist;
float[] out = new float[3];
for(int i =0;i<3;i++){
out[i] = p[i] – sp[i];
}
out = unifyVector(out);
for(int i =0;i<3;i++){
out[i] = out[i]*(distance-originDist)*m;
}
return out;
}
}

class gParticle{
int[] ID;
float[] pos = new float[3];
//vertexNormal
float[] myNormal = new float[3];
float[][] faceNormal;
boolean updated = false;
int count = 0;

gParticle(int[] id, float x, float y, float z){
ID = id;
pos[0] = x;
pos[1] = y;
pos[2] = z;
}
void addFaceNormal(float[] fn){
if(!updated){//refresh the whole array
faceNormal = new float[1][3];
faceNormal[0] = fn;
updated = true;
}
else{//add the face normal to the array
float[][] tempN = new float[faceNormal.length+1][3];
arraycopy(faceNormal, tempN);
tempN[faceNormal.length] = fn;
faceNormal = tempN;
}
}
void updateNormal(){
if(updated){//average all face Normal
for(int i=0;i<3;i++){
myNormal[i] = 0;
for(int j=0;j
myNormal[i] += faceNormal[j][i];
}
myNormal[i] = myNormal[i]/faceNormal.length;
}
updated = false;
}
}
}

float[] createArray3(float x, float y, float z){
float[] out = {
x,y,z };
return out;
}

float[] createArray2(float x, float y){
float[] out = {
x,y };
return out;
}

class gString{
float[][] pPos;
stringHistory[] history;
float[] radius;
//float[] lastPos = new float[3];
//float[] endPos = new float[3];
//float lastR;
//boolean started = false;
float maxDist;
float pDist;
gString(float md){
maxDist = md;
pDist = 5;
}

void plot(GL _gl){
if(history != null){
plotHistory(_gl);
}
}

void plot(GL _gl, int index){
if(history != null){
plotHistory(_gl, index);
}
}

float[][] getString(float sX, float sY, float sZ, float eX, float eY, float eZ){
float[][] out = new float[1][3];
out[0][0] = sX;
out[0][1] = sY;
out[0][2] = sZ;
float xDist = eX – sX;
float yDist = eY – sY;
float zDist = eZ – sZ;
float xyDist = sqrt(sq(xDist)+sq(yDist));
float a = (eZ – sZ)/sq(xyDist);
float b = 5;
int i=1;
while(i<(eZ – sZ)){
float d = dist(out[out.length-1][0]-sX, out[out.length-1][1]-sY, out[out.length-1][2]-sZ,(sqrt(i/a)+(zDist -i)/5)*xDist/xyDist,(sqrt(i/a)+(zDist -i)/5)*yDist/xyDist, i);
if(d>pDist){
float x = sX+(sqrt(i/a)+(zDist -i)/5)*xDist/xyDist;
float y = sY+(sqrt(i/a)+(zDist -i)/5)*yDist/xyDist;
float z = sZ +i;
float[][] temp = new float[out.length+1][3];
arraycopy(out, temp);
temp[out.length] = createArray3(x,y,z);
out = temp;
}
i++;
}
return out;
}

float[][] checkString(float[][] pos){
int lastStatic = 0;
float[][] out = new float[1][3];
float[][] temp2;
out[0] = cloneVector(pos[0]);
int i=1;
boolean modified = false;
while(i

if(dropArray != null && !modified){
float hei = pos[i][2];
for(int j=0;j
if(pos[i][0] < dropArray[j].volume[0] && pos[i][0] > dropArray[j].volume[3]
&& pos[i][1] < dropArray[j].volume[1] && pos[i][1] > dropArray[j].volume[4]
&& pos[i][2] < dropArray[j].volume[2] && pos[i][2] > dropArray[j].volume[5]){
for(int k=0;k
float z = dropArray[j].rings[k].pos[2] + dropArray[j].rings[k].radius – pos[i][2];
if(z >0 && z< 1000){
float d = getDistance(createArray2(dropArray[j].rings[k].pos[0], dropArray[j].rings[k].pos[1]), createArray2(pos[i][0], pos[i][1]));
if(d < dropArray[j].rings[k].radius){
float z2 = dropArray[j].rings[k].pos[2] + sqrt(sq(dropArray[j].rings[k].radius) – sq(d));
if(z2>hei){
hei = z2;
}
}
}
}
}
}
if(hei > pos[i][2]){
float difference = hei – pos[i][2];
pos[i][2] = hei;
for(int j=i+1;j

pos[j][2] += difference;
}
//modify vertex ahead
float[][] tempP = getString(pos[lastStatic][0], pos[lastStatic][1], pos[lastStatic][2], pos[i][0], pos[i][1], pos[i][2]);
temp2 = new float[1][3];
temp2[0] = cloneVector(pos[0]);
for(int j=1; j
float[][] tmp = new float[temp2.length+1][3];
arraycopy(temp2, tmp);
tmp[temp2.length] = cloneVector(out[j]);
temp2 = tmp;
}
lastStatic = i;
for(int l=0;l
float[][] tmp = new float[temp2.length+1][3];
arraycopy(temp2, tmp);
tmp[temp2.length] = cloneVector(tempP[l]);
temp2 = tmp;
}
out = temp2;
modified = true;
}
}
float[][] temp = new float[out.length+1][3];
arraycopy(out, temp);
temp[out.length] = cloneVector(pos[i]);
out = temp;
i++;
}
return out;
}

void geometryString(float[][] pos, float rr, float rDecrease){
pPos = new float[1][3];
radius = new float[1];
pPos[0] = cloneVector(pos[0]);
radius[0] = rr;
for(int i=1;i
float r = rr-sqrt(i*pDist)*rDecrease;
if(r
r=minRadius;
}
float d = getDistance(pPos[pPos.length-1], pos[i]);
float range = maxDist;
if(r+radius[radius.length-1] > maxDist){
range = r + radius[radius.length-1];
}
if(d>range){
float[][] temp = new float[pPos.length+1][3];
arraycopy(pPos, temp);
temp[pPos.length] = pos[i];
pPos = temp;

float[] tempR = new float[radius.length+1];
arraycopy(radius, tempR);
tempR[radius.length] = r;
radius = tempR;
}
}
}

void update(float sX, float sY, float sZ, float eX, float eY, float eZ, float rr, float rDecrease){
float[][] pos = getString(sX, sY, sZ, eX, eY, eZ);
pos = checkString(pos);
geometryString(pos, rr, rDecrease);
addHistory(pPos);
}

void addHistory(float[][] h){
if(history == null){
history = new stringHistory[1];
history[0] = new stringHistory(h);
}
else{
stringHistory[] tempH = new stringHistory[history.length+1];
arraycopy(history, tempH);
tempH[history.length] = new stringHistory(h);
history = tempH;
}
}
void plotHistory(GL _gl){
if(history != null){
for(int i=0;i
history[i].plot(_gl);
}
}
}
void plotHistory(GL _gl, int index){
if(history != null){
//for(int i=0;i
history[index].plot(_gl);
//}
}
}

void createDrop(){
int tempID;
if(dropArray == null){
tempID = 0;
dropArray = new gDrop[1];
}
else{
tempID = dropArray.length;
gDrop[] tempArray = new gDrop[dropArray.length+1];
arraycopy(dropArray, tempArray);
dropArray = tempArray;
}
dropArray[tempID] = new gDrop(tempID, pPos[0][0],pPos[0][1],pPos[0][2],pPos[pPos.length-1][0],pPos[pPos.length-1][1],pPos[pPos.length-1][2],radius[0]);

for(int i=1;i

dropArray[tempID].addRing(pPos[i][0],pPos[i][1],pPos[i][2],0,0,1,radius[i]);
}
startedDrop++;
dropArray[tempID].ended = true;
}
}

class stringHistory{
float[][] pPos;
stringHistory(float[][] p){
pPos = p;
}
void plot(GL _gl){
_gl.glDisable(GL.GL_LIGHTING);
_gl.glColor3f(0,0,0);
_gl.glBegin(GL.GL_LINE_STRIP);
for(int i=0;i
_gl.glVertex3f(pPos[i][0],pPos[i][1],pPos[i][2]);
}
_gl.glEnd();
_gl.glEnable(GL.GL_LIGHTING);

}
}

//—————————————————
//opengl draw
void drawQuad(GL _gl, float[] p1, float[] p2, float[] p3, float[] p4,float[] v1, float[] v2, float[] v3, float[] v4){
_gl.glBegin(GL.GL_QUADS);//GL.GL_QUADS, GL.GL_LINE_LOOP
_gl.glNormal3f(v1[0], v1[1], v1[2]);
_gl.glVertex3f(p1[0], p1[1], p1[2]);
_gl.glNormal3f(v2[0], v2[1], v2[2]);
_gl.glVertex3f(p2[0], p2[1], p2[2]);
_gl.glNormal3f(v3[0], v3[1], v3[2]);
_gl.glVertex3f(p3[0], p3[1], p3[2]);
_gl.glNormal3f(v4[0], v4[1], v4[2]);
_gl.glVertex3f(p4[0], p4[1], p4[2]);
_gl.glEnd();
}
void drawQuad2(GL _gl, float[] p1, float[] p2, float[] p3, float[] p4){
//get the normal first
float[] v1 = new float[3];
float[] v2 = new float[3];
for(int i=0;i<3;i++){
v1[i] = p2[i] – p1[i];
v2[i] = p3[i] – p2[i];
}
float[] v3 = crossProduct(v1, v2);
v3 = unifyVector(v3);
_gl.glBegin(GL.GL_QUADS);//GL.GL_QUADS, GL.GL_LINE_LOOP
_gl.glNormal3f(v3[0], v3[1], v3[2]);
_gl.glVertex3f(p1[0], p1[1], p1[2]);
_gl.glVertex3f(p2[0], p2[1], p2[2]);
_gl.glVertex3f(p3[0], p3[1], p3[2]);
_gl.glVertex3f(p4[0], p4[1], p4[2]);
_gl.glEnd();
}
void drawTri(GL _gl, float[] p1, float[] p2, float[] p3,float[] v1, float[] v2, float[] v3){
_gl.glBegin(GL.GL_TRIANGLES);//GL.GL_QUADS, GL.GL_LINE_LOOP
_gl.glNormal3f(v1[0], v1[1], v1[2]);
_gl.glVertex3f(p1[0], p1[1], p1[2]);
_gl.glNormal3f(v2[0], v2[1], v2[2]);
_gl.glVertex3f(p2[0], p2[1], p2[2]);
_gl.glNormal3f(v3[0], v3[1], v3[2]);
_gl.glVertex3f(p3[0], p3[1], p3[2]);
_gl.glEnd();
}

void drawTri2(GL _gl, float[] p1, float[] p2, float[] p3){
//get the normal first
float[] v1 = new float[3];
float[] v2 = new float[3];
for(int i=0;i<3;i++){
v1[i] = p2[i] – p1[i];
v2[i] = p3[i] – p2[i];
}
float[] v3 = crossProduct(v1, v2);
v3 = unifyVector(v3);
_gl.glBegin(GL.GL_TRIANGLES);
_gl.glNormal3f(v3[0], v3[1], v3[2]);
_gl.glVertex3f(p1[0], p1[1], p1[2]);
_gl.glVertex3f(p2[0], p2[1], p2[2]);
_gl.glVertex3f(p3[0], p3[1], p3[2]);
_gl.glEnd();
}

void drawSphere(GL _gl, float r, int lats, int longs) {
//int i, j;
for(int i = 1; i <= lats; i++) {
float lat0 = PI * (-0.5 + (float) (i – 1) / lats);
float z0 = sin(lat0);
float zr0 = cos(lat0);

float lat1 = PI * (-0.5 + (float) i / lats);
float z1 = sin(lat1);
float zr1 = cos(lat1);

// _gl.glPointSize(5);
_gl.glBegin(GL.GL_QUAD_STRIP);
//_gl.glBegin(GL.GL_POINTS);
for(int j = 0; j <= longs; j++) {
float lng = 2 * PI * (float) (j – 1) / longs;
float x = cos(lng);
float y = sin(lng);
_gl.glNormal3f(x * zr1, y * zr1, z1);
_gl.glVertex3f(r*x * zr1, r*y * zr1, r*z1);
_gl.glNormal3f(x * zr0, y * zr0, z0);
_gl.glVertex3f(r*x * zr0, r*y * zr0, r*z0);

}
_gl.glEnd();

}
// _gl.glPopMatrix();
}

void glInit(GL gl, GLU glu){
gl.glEnable(GL.GL_CULL_FACE);
gl.glEnable(GL.GL_BLEND);
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
//gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ZERO);
gl.glShadeModel(GL.GL_SMOOTH);
gl.glEnable(GL.GL_COLOR_MATERIAL);

float[] light_ambient ={
0.0, 0.0, 0.0, 1.0 };
float[] light_diffuse = {
1.0, 1.0, 1.0, 1 };
float[] light_specular = {
1.0, 1.0, 1.0, 1.0 };
float[] light_position = {
10.0, 10.0, 10.0, 0 };

gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, light_ambient, 0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, light_diffuse, 0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, light_specular, 0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, light_position, 0);

gl.glEnable(GL.GL_LIGHT0);

float[] light_ambient1 ={
0.0, 0.0, 0.0, 1.0 };
float[] light_diffuse1 = {
0.3, 0.3, 0.3, 1.0 };
float[] light_specular1 = {
1.0, 1.0, 1.0, 1.0 };
float[] light_position1 = {
-10.0, -10.0, -10.0, 0 };

gl.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, light_ambient1, 0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, light_diffuse1, 0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_SPECULAR, light_specular1, 0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, light_position1, 0);

gl.glEnable(GL.GL_LIGHT1);

gl.glEnable(GL.GL_LIGHTING);
gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);

float[] fogColor= {
0f, 0.0f, 0.0f, .0f }; // Fog Color

gl.glFogi(GL.GL_FOG_MODE, GL.GL_LINEAR); // Fog Mode
gl.glFogfv(GL.GL_FOG_COLOR, fogColor,0); // Set Fog Color
gl.glFogf(GL.GL_FOG_DENSITY, 0.3f); // How Dense Will The Fog Be
gl.glHint(GL.GL_FOG_HINT, GL.GL_NICEST); // Fog Hint Value
gl.glFogf(GL.GL_FOG_START, 1000.0f); // Fog Start Depth
gl.glFogf(GL.GL_FOG_END, 3000.0f); // Fog End Depth
gl.glEnable(GL.GL_FOG);
}

//—————————————————
//MATH

float[] unifyVector(float[] v){
float[] out = {
0,0,0 };
if(v[0] ==0 && v[1]==0 && v[2]==0){
//println(“unifyVector error!! length == 0”);
}
else{
float[] zero = {
0,0,0 };
float d = getDistance(zero, v);
for(int i =0; i<3; i++){
out[i] = v[i]/d;
}
}
return out;
}

float[] multiplyVector(float[] v, float m){
float[] out = new float[v.length];

for(int i =0; i
out[i] = v[i]*m;
}

return out;
}

float[] reverseVector(float[] v){
float[] out = new float[v.length];
for(int i=0;i
out[i] = -1*v[i];
}
return out;
}

float[] cloneVector(float[] v){
float[] out = new float[v.length];
for(int i=0;i
out[i] = v[i];
}
return out;
}

float getDistance(float[] x1, float[] x2){
float temp = 0;
for(int i = 0; i
float temp2 = x1[i] – x2[i];
temp2 = temp2*temp2;
temp += temp2;
}
if(temp != 0){
temp = sqrt(temp);
}
return temp;
}

float getLength(float[] x1){
float temp = 0;
for(int i = 0; i
temp += sq(x1[i]);
}
if(temp != 0){
temp = sqrt(temp);
}
return temp;
}
float[] crossProduct(float[] v1, float[] v2){
//A x B =
float[] out = new float[3];
out[0] = v1[1]*v2[2] – v1[2]*v2[1];
out[1] = v1[2]*v2[0] – v1[0]*v2[2];
out[2] = v1[0]*v2[1] – v1[1]*v2[0];
/*if(out[0] ==0 && out[1]==0 && out[2]==0){
println(“crossproduct error!!”);
}*/
return out;
}

float dotProduct(float[] v1, float[] v2){
v1 = unifyVector(v1);
v2 = unifyVector(v2);
float out = 0;
for(int i=0;i<3;i++){
out += v1[i]*v2[i];
}
return out;
}

float getVectorAngle(float[] v1, float[] v2){
float out=0;
//float l1 = getLength(v1);
//float l2 = getLength(v2);
float dot = dotProduct(v1,v2);
out = degrees(acos(dot));
return out;
}

float[] getVector(float[] v1, float[] v2){
float[] out=new float[v1.length];
for(int i=0;i
out[i] = v2[i] – v1[i];
}
return out;
}

float[] addVector(float[] v1, float[] v2){
float[] out=new float[v1.length];
for(int i=0;i
out[i] = v2[i] + v1[i];
}
return out;
}

float[] rotateXX(float x, float y, float z, float x2){
float[] temp = new float[3];
temp[1] = y*cos(x2) – z*sin(x2);
temp[2] = z*cos(x2) + y*sin(x2);

temp[0] = x;
return temp;
}

float[] rotateYY(float x, float y, float z, float y2){
float[] temp = new float[3];
temp[0] = x*cos(y2) + z*sin(y2);
temp[2] = z*cos(y2) – x*sin(y2);

temp[1] = y;
return temp;
}

float[] rotateZZ(float x, float y, float z, float z2){
float[] temp = new float[3];
temp[0] = x*cos(z2) – y*sin(z2);
temp[1] = x*sin(z2) + y*cos(z2);

temp[2] = z;
return temp;
}

class tailPosition{
float[] pos = new float[3];

tailPosition(float x, float y, float z){
pos[0] = x;
pos[1] = y;
pos[2] = z;
}

}

class spaceSquare{
float[] pos = new float[3];
float[] volume = new float[3];

spaceSquare(float x, float y, float z, float w1, float w2, float h){
pos[0] = x;
pos[1] = y;
pos[2] = z;
volume[2] = h;
volume[0] = w1;
volume[1] = w2;
}

float distance(float x, float y, float z){
float[] tV = getVector(createArray3(pos[0],pos[1],pos[2]+(volume[2]/2)), createArray3(x,y,z));
for(int i=0;i<3;i++){
tV[i] = tV[i]/volume[i];
}
tV = unifyVector(tV);
float longest = 0;
int lID = 0;
for(int i=0;i<3;i++){
if(abs(tV[i])> longest){
longest = abs(tV[i]);
lID = i;
}
}
for(int i=0;i<3;i++){
tV[i] = (tV[i]/longest) * volume[i]/2;
}
tV = addVector(tV, createArray3(pos[0],pos[1],pos[2]+(volume[2]/2)));
float out = getDistance(createArray3(x,y,z), tV);
/* traceX = tV[0];
traceY = tV[1];
traceZ = tV[2];
println(out);*/
return out;
}

void plot(GL _gl){
_gl.glPushMatrix();
_gl.glTranslatef(pos[0],pos[1],pos[2]);
_gl.glColor4f(0,0,1,.5);
//top
drawQuad2(_gl, createArray3(-volume[0]/2, volume[1]/2,volume[2]), createArray3(-volume[0]/2, -volume[1]/2,volume[2]), createArray3(volume[0]/2, -volume[1]/2,volume[2]), createArray3(volume[0]/2, volume[1]/2,volume[2]));
drawQuad2(_gl, createArray3(-volume[0]/2, volume[1]/2,volume[2]), createArray3(-volume[0]/2, volume[1]/2,0), createArray3(-volume[0]/2, -volume[1]/2,0), createArray3(-volume[0]/2, -volume[1]/2,volume[2]));
drawQuad2(_gl, createArray3(-volume[0]/2, -volume[1]/2,volume[2]), createArray3(-volume[0]/2, -volume[1]/2,0), createArray3(volume[0]/2, -volume[1]/2,0), createArray3(volume[0]/2, -volume[1]/2,volume[2]));
drawQuad2(_gl, createArray3(volume[0]/2, -volume[1]/2,volume[2]), createArray3(volume[0]/2, -volume[1]/2,0), createArray3(volume[0]/2, volume[1]/2,0), createArray3(volume[0]/2, volume[1]/2,volume[2]));
drawQuad2(_gl, createArray3(volume[0]/2, volume[1]/2,volume[2]), createArray3(volume[0]/2, volume[1]/2,0), createArray3(-volume[0]/2, volume[1]/2,0), createArray3(-volume[0]/2, volume[1]/2,volume[2]));
_gl.glPopMatrix();
}
}

class gCol{
float[] pos = new float[3];
float hei;

gCol(float x, float y, float z, float h){
pos[0] = x;
pos[1] = y;
pos[2] = z;
hei = h;
}

void plot(GL _gl){
_gl.glDisable(GL.GL_LIGHTING);
_gl.glColor3f(0,0,0);
_gl.glBegin(GL.GL_LINES);
_gl.glVertex3f(pos[0], pos[1], pos[2]);
_gl.glVertex3f(pos[0], pos[1], pos[2]+hei);
_gl.glEnd();
_gl.glEnable(GL.GL_LIGHTING);
}

}

void addSphere(spaceSphere SS){
if(mySpaces == null){
mySpaces = new spaceSphere[1];
mySpaces[0] = SS;
}
else{
spaceSphere[] temp = new spaceSphere[mySpaces.length+1];
arraycopy(mySpaces, temp);
temp[mySpaces.length] = SS;
mySpaces = temp;
}
}

class spaceSphere{
float[] pos = new float[3];
float radius;
boolean closed;

spaceSphere(float x, float y, float z, float r){
pos[0] = x;
pos[1] = y;
pos[2] = z;
radius = r;
closed = true;
}

void plot(GL _gl){
_gl.glPushMatrix();
_gl.glTranslatef(pos[0],pos[1],pos[2]);
if(closed){
_gl.glColor4f(0,1,1,.5);
}
else{
_gl.glColor4f(1,.3,.3,.5);
}
drawSphere(_gl,radius, 10,10);
_gl.glPopMatrix();
}
}

class myTimer{
int counter;
myTimer(){
counter = 0;
}
void update(){
if(!paused){
if(counter>300){
counter-=300;
loopEvent();
}
counter++;
}
//update——————————
updateCount = 0;
if(dropArray != null){
for(int i=0; i
if(dropArray[i].updating){
dropArray[i].update();
updateCount ++;
}
}
}

fill(255);
noStroke();
rect(0,height-20,width,20);
stroke(0);
line(5,height-18,width-5,height-18);
if(dropArray !=null){
myTrace = “FPS: “+float(fps)/10+ ” FPS: “+round(frameRate)+” / “+dropArray.length+” drops, “+updateCount+” updating”+” “+month()+”/”+day()+” “+hour()+”:”+minute()+”:”+second();
}
else{
myTrace = “FPS: “+float(fps)/10+ ” FPS: “+round(frameRate)+” / “+updateCount+” updating”+” “+month()+”/”+day()+” “+hour()+”:”+minute()+”:”+second();
}
if(paused){
myTrace +=” PAUSED!”;
}
fill(0);
text(myTrace, 5, height-5);
if(screenPrinted){
screenPrinted = false;
saveFrame(month()+”_”+day()+”_”+hour()+”_”+minute()+”_”+second()+”.png”);
println(“Screenshot saved”);
}
}
void loopEvent(){
if(myAgents != null){
for(int i=0;i
myAgents[i].update();
}
}
}
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s