//
/*
Need to have each Polly follow a path.
*/
import render.*;
import java.util.*;
import java.awt.*;
public class Follow extends RenderApplet
{
int N = 9, S = 65;
Polly polly[] = new Polly[N];
PathFinder pf;
Geometry marker[][] = new Geometry[N][S];
double R[] = new double[N];
double X[][] = new double[N][S];
double Z[][] = new double[N][S];
double ends[][] = {
{-4,-2, 4, 3},
{-3,-3, 3, 2},
{-2,-2, 2, 3},
{-1,-3, 1, 2},
{ 0,-2, 0, 3},
{ 1,-3, -1, 2},
{ 2,-2, -2, 3},
{ 3,-3, -3, 2},
{ 4,-2, -4, 3},
};
public boolean keyUp(Event e, int k) { // SET ACTIONS VIA KEYBOARD
if (! super.keyUp(e, k))
key(k);
return true;
}
int n = 0;
public void key(int k) {
if (k >= '0' && k < '0' + N)
n = k - '0';
else if (k >= 'a' && k <= 'a' + Polly.nActions)
polly[n].setAction(k - 'a');
}
double w[][] = { {6,4, -6,4, -6,-4, 6,-4, 6,4}}; // WALL DATA
void createPaths(int state) {
for (int i = 0 ; i < N ; i++) {
for (int s = 1 ; s < S-1 ; s++)
X[i][s] = Z[i][s] = 0;
R[i] = .7;
X[i][ 0] = ends[i][state==0 ? 0 : 2];
Z[i][ 0] = ends[i][state==0 ? 1 : 3];
X[i][S-1] = ends[i][state==0 ? 2 : 0];
Z[i][S-1] = ends[i][state==0 ? 3 : 1];
}
pf = new PathFinder(R, X, Z);
pf.findPaths();
}
public void initialize() { // INITIALIZE EVERYTHING
// CREATE THE PATHS FOR THE POLLYS TO FOLLOW
createPaths(0);
// SET UP THE SCENE TO BE RENDERED
addLight(1,1,1, 1,1,1); // LIGHTS
addLight(0,-1,0, 1,1,1);
setBgColor(.2,.2,.8); // BACKGROUND COLOR
setFL(12); // CAMERA FOCAL LENGTH
push();
translate(-.5,0,0);
rotateX(Math.PI/2);
transform(world); // INITIAL VIEW ANGLE
pop();
world.add().setMaterial(
(new Material()).setColor(0,1,0).setTransparency(.5));
world.child[0].mesh(10, 10).setDoubleSided(true);
push(); // MAKE THE TRANSPARENT FLOOR
scale(6,1,4);
rotateX(-Math.PI/2);
transform(world.child[0]);
pop();
Geometry walls = world.add().setMaterial(
(new Material()).setColor(1,1,1).setTransparency(.5));
walls.setDoubleSided(true);
Polly.clearWalls();
for (int i = 0 ; i < w.length ; i++) {
Polly.addWall(w[i]);
makeWall(walls, w[i]);
}
Polly.clearPollys();
for (int i = 0; i < N ; i++) {
polly[i] = new Polly();
world.add(polly[i]);
polly[i].setPosition(X[i][0], Z[i][0]);
setDirection(i, X[i][1]-X[i][0], Z[i][1]-Z[i][0]);
polly[i].setAction("swagger");
polly[i].avoidActors(false);
polly[i].avoidWalls(false);
polly[i].setColor(s(i+1),s(i+2),s(i));
/*
Material m0 = (new Material()).setColor(1,0,0);
Material m1 = (new Material()).setColor(0,0,1);
for (int s = 0 ; s < S ; s++) {
world.add((marker[i][s] = new Geometry()).cube());
marker[i][s].setMaterial(s < S/2 ? m0 : m1);
placeMarker(i,s,0,0);
}
*/
}
}
double s(double x) { return .5 + .5 * Math.sin(x*x); }
double norm(double x, double z) {
return Math.sqrt(x*x + z*z);
}
void setDirection(int i, double dx, double dz) {
polly[i].setDirection(Math.atan2(dx,dz));
}
Random random = new Random();
double rand() { return 2 * random.nextDouble() - 1; }
void makeWall(Geometry g, double w[]) {
for (int j = 0 ; j < w.length/2 - 1 ; j++) {
double ax = w[2*j ], az = w[2*j+1],
bx = w[2*j+2], bz = w[2*j+3];
push();
double dx = (bx-ax)/2, dz = (bz-az)/2;
Geometry wall = g.add();
wall.mesh((int)Math.sqrt(dx*dx+dz*dz)+2, 2);
translate((ax+bx)/2, .25, (az+bz)/2);
rotateY(Math.atan2(-dz, dx));
scale(Math.sqrt(dx*dx + dz*dz), .25, 1);
transform(wall);
pop();
}
}
int step = 0;
int state = 0;
double pxz[] = new double[2];
public void animate(double time) { // ANIMATE ONE FRAME
pf.relax();
for (int i = 0 ; i < N ; i++)
polly[i].animate(time);
if (step == S)
return;
boolean advance = true;
for (int i = 0 ; i < N ; i++) {
/*
for (int s = 0 ; s < S ; s++)
placeMarker(i,s, X[i][s], Z[i][s]);
*/
if (norm(X[i][step] - polly[i].x, Z[i][step] - polly[i].z) >= .5)
advance = false;
}
if (advance) {
step++;
if (step < S)
for (int i = 0 ; i < N ; i++) {
setDirection(i, X[i][step]-polly[i].x, Z[i][step]-polly[i].z);
polly[i].setThrottle(norm(X[i][step] - polly[i].x, Z[i][step] - polly[i].z));
}
}
if (step == S) {
createPaths(state = 1 - state);
step = 0;
}
}
void placeMarker(int i, int s, double x, double z) {
push();
identity();
translate(x,.01,z);
scale(.03,.01,.03);
transform(marker[i][s]);
pop();
}
}