import InterpolatedVar.*;
import Raytracing.*;
import Tuple.*;
 
int frame =0;
 
Vector cast;
float az = 0, el =0;
 
float jx=0,jy=0;
PImage a,b,c;
 
int showHints = 0;
 
InterpolatedVar ilx,ilz,ily;
 
Tuple3f light = new Tuple3f(0,-200,200);
Plane ground = new Plane(0,50,0,0,1,0);
 
float cx = 0,cy = 100, cz = 45;
float lx = 0.0, ly = -1, ez = 45;
void setup()
{
 
size( 550, 300, P3D);
hint(g.ENABLE_ACCURATE_TEXTURES) ;
ilx = new SOLagInterpolatedVar(this,0,12,6);
ily = new SOLagInterpolatedVar(this,-100,12,6);
ilz = new SOLagInterpolatedVar(this,200,12,6);
 
 
 
a = loadImage("poenderous.png");
c = loadImage("poenderousShadow.png");
cast = new Vector();
 
for (int i=0; i < 40; i++){
cast.add(new Guy());
}
 
textureMode(NORMALIZED);
}
void draw(){
frame--;
 
background( 225,225,235);
 
hint(ENABLE_DEPTH_SORT);
if (frame < 0) {
frame = (int)random(60,240);
ilx.setVal(random(-300,300));
ily.setVal(random(-300,-100));
ilz.setVal(random(-300,300));
}
 
light.x = ilx.getVal();
light.z = ilz.getVal();
 
camera( cx, -ez , cy, cx + lx, -cz , cy + ly, 0, 1, 0);
fill(200);
 
noStroke();
 
 
 
Guy curr;
for (int i=0; i < cast.size(); i++){
curr = (Guy)cast.elementAt(i);
curr.draw();
}
 
pushMatrix();
translate(light.x,light.y,light.z);
fill(255);
sphere(5);
popMatrix();
 
if(keyPressed) {
float speed = 5;
if(key == 'w') {
cx += speed*lx;
cy += speed*ly;
 
}
if(key == 's') {
cx -= speed*lx;
cy -= speed*ly;
 
}
if(key == 'd') {
cx -= speed*ly;
cy += speed*lx;
 
}
if(key == 'a') {
cx += speed*ly;
cy -= speed*lx;
 
}
 
if(key == 'r') {
ez +=1;
cz +=1;
}
if(key == 'f') {
if (ez > -50){
ez -=1;
cz -=1;
}
}
 
if(key == 'q') {
float tr = -.1;
lx = lx*cos(tr) - ly*sin(tr);
ly = lx*sin(tr) + ly*cos(tr);
float norm = sqrt(lx*lx + ly*ly);
lx/=norm;
ly/=norm;
}
if(key == 'e') {
float tr = .1;
lx = lx*cos(tr) - ly*sin(tr);
ly = lx*sin(tr) + ly*cos(tr);
float norm = sqrt(lx*lx + ly*ly);
lx/=norm;
ly/=norm;
}
}
 
}
void keyPressed(){
if(key == 'h') {
showHints = 1 - showHints;
 
}
 
}
void mouseDragged(){
if (mouseButton == LEFT){
cz -= (mouseY-pmouseY)/75.0;
float tr = (mouseX-pmouseX)/100.0;
lx = lx*cos(tr) - ly*sin(tr);
ly = lx*sin(tr) + ly*cos(tr);
float norm = sqrt(lx*lx + ly*ly);
lx/=norm;
ly/=norm;
}
else{
float dy = mouseY-pmouseY;
if (ez > -50 || dy > 0){
cz += dy;
ez += dy;
}
}
}
class Guy{
 
PImage tex,texs;
float x,y;
public Guy(){
 
x = random(-400,400);
y = random(-400,400);
 
}
 
void draw(){
 
pushMatrix();
translate( x,0,y);
noStroke();
fill(0,255);
 
beginShape();
texture(a);
vertex(0, 0, 0, 0);
vertex(20, 0, 1, 0);
vertex(20, 50, 1, 1);
vertex(0, 50, 0, 1);
endShape();
 
popMatrix();
 
 
stroke(0);
Ray isect= new Ray();
isect.setPointer(light,new Tuple3f(x,0,y));
ground.intersect(isect);
Tuple3f gpt = isect.project(isect.distance);
if (showHints == 1){
beginShape();
vertex(light.x,light.y,light.z);
vertex(gpt.x,gpt.y,gpt.z);
endShape();
}
isect.setPointer(light,new Tuple3f(x+20,0,y));
ground.intersect(isect);
Tuple3f gpt2 = isect.project(isect.distance);
if (showHints == 1){
beginShape();
vertex(light.x,light.y,light.z);
vertex(gpt2.x,gpt2.y,gpt2.z);
endShape();
}
noStroke();
beginShape();
texture(c);
vertex(gpt.x,gpt.y,gpt.z,0,0);
vertex(gpt2.x,gpt2.y,gpt2.z,1,0);
vertex(x+20,49,y,1,1);
vertex(x,49,y,0,1);
endShape();
 
}
 
}