//************************************** // 3D CAMERA // Written by Jarek Rossignac, June 2006 //************************************* class cam { float D=10000, sD=D; //Distance from Eye to Focus point pt E = new pt(0,0,D); pt sE = new pt(0,0,D); //Eye pt F = new pt(0,0,0); pt sF = new pt(0,0,0); //Focus (or center) vec U = new vec(0,1,0); //Upvector (ortoganal to FE vector vec I = new vec(1,0,0); vec J = new vec(0,1,0); vec K = new vec(0,0,1); //New x, y, z axis int px=0, py=0; //Mouse x and y coordinates cam (pt pE, pt pF) {E.setToPoint(pE); F.setToPoint(pF); D=E.disTo(F);}; //Constructor to initialize camera position void write() { //Writes the coordinates for the Eye point, Focus point, and Up vector print("camera:"); println("D="+D); print("E="); E.write(); print("F="); F.write(); print("U="); U.write(); println();}; void setcam (pt pE, pt pF) {E.setToPoint(pE); F.setToPoint(pF); D=E.disTo(F);}; //Set camera somewhat in the original position void apply() { camera(E.x,E.y,E.z,F.x,F.y,F.z,U.x,U.y,U.z); }; //Sets the position of the camera through setting the eye position, the center of the scene, and which axis is facing upward. void anchor() {px=mouseX; py=mouseY; sE.setToPoint(E); sF.setToPoint(F); sD=D;}; //Save coordinates for the mouse, Eye, and Focus points void pose() { //Determines new I, J, K axis and Upvector vec nK=F.vecTo(E); if (nK.norm()>0.0001) {K.setToVec(nK);} //If the length from Eye to Focus is large, Set K vector to this vector else {println("keep K");}; //Otherwise, Keep the K vector K.makeUnit(); //Make K vector into K axis vec nI=cross(U,K); //Use cross product of K and Upvector to determine the new I vector if (nI.norm()<0.0001) {nI.setToVec(I); println("I=UxJ");}; //If the length of the new I vector is small, Set new I vector to the old I vector nI.makeUnit(); //Make new I vector into unit vector I.setToVec(nI); //Set I axis to new I J.setToVec(cross(K,I)); //J vector is equal to the cross product of K and I J.makeUnit(); //Make J vector into J axis U.setToVec(J); //Upvector is now the J vector } void jump (int c) { //Jump directly to corner F.setToPoint(g(c)); //Set Focus to the location of corner vec N = triNormal(t(c)); N.makeUnit(); //Determine Normal for triangle containing corner E.setToPoint(triCenter(t(c))); //Set Eye to center of triangle containing corner vec T = E.vecTo(F); float nT=T.norm(); E.addScaledVec(nT,N); //Translate the Eye along the normal by the distance from Eye to Focus point U.setToVec(N); U.back(); sD=6*nT; this.pullE(); this.pose(); //Upvector is equal to set to normal println("sD="+sD); this.write(); }; void pullE() { //Move Eye towards Focus based on the distance from Focus to Eye float cD=F.disTo(E); if (abs(cD)<0.001) {E.setToPoint(F); E.addScaledVec(D,K);} else {E.moveTowards((cD-D)/cD,F);}; }; void pan() { //Move camera based on mouse coordinates float r=width/D/2; float x=-(mouseX-px)/r; float y=-(mouseY-py)/r; E.setToPoint(sE); E.addScaledVec(x,I); E.addScaledVec(y,J); if (cross(U,F.vecTo(E)).norm()<0.1) { F.addScaledVec(-x/10.0,I); F.addScaledVec(-y/10.0,J); }; }; void recomputeD() {D=E.disTo(F);}; //Recompute distance from Eye point to Focus point void track (cam K) { //Track the location of the camera by using the location of the new camera float s=0.0005*nt; if (s<0.005) {s=0.005;}; if (s>0.25) {s=0.25;}; //Scale value to move camera by E.moveTowards(s,K.E); F.moveTowards(s,K.F); //Move Eye and Focus of this camera towards new camera location this.recomputeD(); U.addScaled(s,K.U); U.makeUnit(); this.pose(); this.anchor(); }; void zoom() { float r=width/Rbox/2; float x=-(mouseX-px)/r; float y=-(mouseY-py)/r; E.setToPoint(sE); E.addScaledVec(x,I); D=sD+y*sD/height; }; /* Unused void setMark() { float x=float(mouseX-width/2)*2/width; float y=float(mouseY- height/2)*2/height; pMark.setToPoint(F); pMark.addScaledVec(x*D,I); pMark.addScaledVec (y*D,J); pEye.setToPoint(E); }; void snap() {E.setToPoint(sE); F.setToPoint(sF); D=sD;}; void snapD() {D=sD; println(">> snaped D="+D); }; void showPose() {vec II = I.make(); II.mul(100); stroke(250,20,20); II.show(F); vec JJ = U.make(); JJ.mul(100); stroke(0,200,50); JJ.show(F); } void pullF() {float cD=F.disTo(E); if (abs(cD)<0.001) {F.setToPoint(E); F.addScaledVec(D,K);} else {F.moveTowards((cD-D)/cD,E);};}; void fly(float s) { float r=width*2; float x=(mouseX-width/2)/r; float y=(mouseY-height/2)/r; F.addScaledVec(x,I); F.addScaledVec(y,J); F.addScaledVec(-s,K); }; void Turn() { float r=width/D/4; float x=-(mouseX-width/2)/r; float y=-(mouseY-height/2)/r; F.addScaledVec(x,I); F.addScaledVec(y,J); if (cross(U,F.vecTo(E)).norm()<0.1) { F.addScaledVec(-x/10.0,I); F.addScaledVec(-y/10.0,J); }; }; void turn() { float r=float(width)/D; r=100; float x=-(mouseX-px)/r; float y=-(mouseY-py)/r; F.setToPoint(sF); F.addScaledVec(x,I); F.addScaledVec(y,J); if (cross(U,F.vecTo(E)).norm()<0.1) { F.addScaledVec(-x/10.0,I); F.addScaledVec(-y/10.0,J); }; }; void Pan() { float r=16*width/D; float x=-(mouseX-width/2)/r; float y=-(mouseY-height/2)/r; E.addScaledVec(x,I); E.addScaledVec(y,J); if (cross(U,F.vecTo(E)).norm()<0.1) { F.addScaledVec(-x/10.0,I); F.addScaledVec(-y/10.0,J); }; }; void setToCam (cam K) {E.setToPoint(K.E); F.setToPoint(K.F); this.recomputeD(); U.setToVec(K.U); U.makeUnit(); this.pose(); this.anchor();} */ }