Basic. Camera Controls Author Message
kaito
Member

 Post: #1 Basic. Camera Controls I've tested camera .cpp tutorials (Camera.cpp and Camera Modes.cpp), and I have written a sample code to better understand the functions related to the camera. Code in spanish: http://perso.orange.es/tomas_cg75/TallerCamara.html Code: ```/******************************************************************************/ // EDIT: Code Erased. New code in next post /******************************************************************************/``` Cam.setAngle: Using this function, i can move the camera position and Look 'at' position at the same time, but i can't modify Cam.dist value (distance variable). Cam.setSpherical: Using this function, i can't move the camera position directly. The camera focus the Look 'at' position at all times. The camera position changes when I modify the remaining variables (Cam.dist, Cam.yaw, Cam.pitch, Cam.roll). Cam.setPosDir: Using this function, i can only move the camera position. In the Camera Modes.cpp tutorial explain any more. The function is composed of 3 values (Vec pos, Vec dir, Vec up), but I do not know how to set up the 'Vec dir' and 'Vec up' in this example (without skeleton). To center camera on Ball position (PosEsfera) i have used Cam.setFromAt, but this function don't change Cam.yaw and Cam.pitch values, and when I move the camera lose the position of the Ball. Is there any mathematical function in esenthel to estimate the yaw and pitch between two 3D positions?
02-18-2009 05:03 PM
Esenthel
 Post: #3 Re: Basic. Camera Controls New code. I create new function to calculate Yaw, Pitch, Distance between two positions 3D. Calculate Yaw and Pitch is necessary for using Cam.setAngle(); For using Cam.setSpherical no is necessary because you can modify Cam.at variable to move the camera, and in this mode the camera has fixed focus. Cam.setFromAt function focus your camera on a point (similar to Cam.setSpherical, but you can change the position of the camera directly). I have applied Cam.setPosDir function to put the camera over object 3d (Ball), when you move the Ball, then the camera follow it. Code: ```/******************************************************************************/ #include "stdafx.h" /******************************************************************************/ Vec PosEsfera;          // 3D position (x,y,z) Int iVar1=0,iVar2(0);   // Integer variables Flt tiempo,fVar;         // Float variables /******************************************************************************/ Flt Yaw(Vec &pos1,Vec &pos2)   // Function to calculate yaw value {     Flt xc=pos1.x,zc=pos1.z,xp=pos2.x,zp=pos2.z;   // Local variables     if (xp==xc && zp>=zc) {return 0;}     if (xp==xc && zpxc) {return -1.5;}     if (zp==zc && xpzc) {return Atan((xc-xp)/(zp-zc));}     if (xp>xc) {return ((Atan((zc-zp)/(xc-xp)))-1.5);}                     else {return ((Atan((zc-zp)/(xc-xp)))+1.5);} } Flt Pitch(Vec &pos1,Vec &pos2)     // Function to calculate pitch value {     Flt xc=pos1.x,yc=pos1.y,zc=pos1.z,xp=pos2.x,yp=pos2.y,zp=pos2.z;  //Local variables     if (yp==yc) {return 0;}     return Atan((yp-yc)/(Sqrt(Sqr(xp-xc)+Sqr(zp-zc)))); } Flt Distance(Vec &pos1,Vec &pos2)   // Function to calculate distance {     Flt xc=pos1.x,yc=pos1.y,zc=pos1.z,xp=pos2.x,yp=pos2.y,zp=pos2.z;    //Local variables     return Sqrt(Sqr(xc-xp)+Sqr(yc-yp)+Sqr(zc-zp)); } /******************************************************************************/ void InitPre() {    // Initial configuration    App.name="TallerCamara";    App.flag=APP_FULL_TOGGLE;    IOPath="../data/";    PakAdd("engine.pak");    // Screen 800x600    D.mode(800,600); } /******************************************************************************/ Bool Init() {   /*       Default Camera:       Cam.matrix.pos=(0,0,1)           Cam.at=(0,0,0)                   Cam.dist=1                       Cam.pitch=0                       Cam.roll =0                      */    tiempo=Tm.time();  //Save current time       PosEsfera=Vec(0,0,5);  // Initial Ball Position    return true; } /******************************************************************************/ void Shut() { } /******************************************************************************/ Bool Main() {    if (Kb.bp(KB_ESC)){return false;}    if (Kb.bp(KB_TAB)) {iVar1++; return true;}    if (Kb.bp(KB_SPACE)) {iVar2++; return true;}    if (Kb.bp(KB_ENTER)) if (iVar2==0) {Cam.yaw=Yaw(Cam.matrix.pos,PosEsfera); Cam.pitch=Pitch(Cam.matrix.pos,PosEsfera);                                         Cam.setAngle(Cam.matrix.pos,Cam.yaw,Cam.pitch,Cam.roll).updateVelocities().​set(); return true;}    else if (iVar2==1) {Cam.at=PosEsfera; Cam.setSpherical(Cam.at,Cam.yaw,Cam.pitch,Cam.roll,Cam.dist).updateVelocities().​set(); return true;}    else if (iVar2==2) {Cam.at=PosEsfera; Cam.setFromAt(Cam.matrix.pos,Cam.at,Cam.roll).updateVelocities().set(); return true;}           if ((Kb.b(KB_LEFT)) || (Kb.b(KB_DOWN))) {fVar=-Tm.d*1.05;} else if ((Kb.b(KB_RIGHT)) || (Kb.b(KB_UP))) {fVar=Tm.d*1.05;} else {return true;}       switch (iVar1) {        case 0 : if ((Kb.b(KB_LEFT )) || (Kb.b(KB_RIGHT))) {Cam.matrix.pos+=Cam.matrix.x*fVar;} else if (Kb.b(KB_LCTRL)) {Cam.matrix.pos+=Cam.matrix.z*fVar;} else {Cam.matrix.pos+=Cam.matrix.y*fVar;} break;        case 1 : if ((Kb.b(KB_UP   )) || (Kb.b(KB_DOWN ))) {Cam.dist-=fVar;} break;        case 2 : if ((Kb.b(KB_LEFT )) || (Kb.b(KB_RIGHT))) {Cam.yaw-=fVar;} break;        case 3 : if ((Kb.b(KB_UP   )) || (Kb.b(KB_DOWN ))) {Cam.pitch+=fVar;} break;        case 4 : if ((Kb.b(KB_LEFT )) || (Kb.b(KB_RIGHT))) {Cam.roll+=fVar;}  break;        case 6 : if ((Kb.b(KB_LEFT )) || (Kb.b(KB_RIGHT))) {Cam.at.x+=fVar;} else if (Kb.b(KB_LCTRL)) {Cam.at.z+=fVar;} else {Cam.at.y+=fVar;} break;        default : if ((Kb.b(KB_LEFT )) || (Kb.b(KB_RIGHT))) {PosEsfera.x+=fVar;} else if (Kb.b(KB_LCTRL)) {PosEsfera.z+=fVar;} else {PosEsfera.y+=fVar;}    }    switch (iVar2) {        case 0 : Cam.setAngle(Cam.matrix.pos,Cam.yaw,Cam.pitch,Cam.roll); break;        case 1 : Cam.setSpherical(Cam.at,Cam.yaw,Cam.pitch,Cam.roll,Cam.dist); break;        case 2 : Cam.setFromAt(Cam.matrix.pos,Cam.at,Cam.roll); break;        default : Cam.setPosDir(Vec(PosEsfera.x,(PosEsfera.y)+1,(PosEsfera.z)-1));    }    Cam.updateVelocities().set();              // Update and set camera changes       return true; } /******************************************************************************/ void Draw() {       if (iVar1==7) iVar1=0;    if (iVar2==4) iVar2=0;    D.clear(WHITE); //Clear Screen in White.       Ball(1,PosEsfera).draw(ColorHue(Tm.time()/3)); // Draw Ball with time color          TextDS estilo;      // declare text format       estilo.color=GREY;    estilo.scale/=1.2;    estilo.align.set(-1,0);    estilo.shadow=1;    D.text(estilo,1.3,0.92,"Press SPACE BAR to change selection");    estilo.align.set(1,0);    D.text(estilo,-1.3,0.92,"Press TAB to change selection");    estilo.color=BLACK;          estilo.scale/=1.4;    estilo.shadow=0;    D.text(estilo,-1.2,0.85,S+"Camera Position (x,y,z): "+Cam.matrix.pos);    D.text(estilo,-1.2,0.8,S+"Distance: "+Cam.dist);    D.text(estilo,-1.2,0.75,S+"Orientation (Yaw): "+Cam.yaw);    D.text(estilo,-1.2,0.7,S+"Inclination (Pitch): "+Cam.pitch);    D.text(estilo,-1.2,0.65,S+"Rotation (Roll): "+Cam.roll);    D.text(estilo,-1.2,0.6,S+"Move Ball. Position: "+PosEsfera);    D.text(estilo,-1.2,0.55,S+"Focus to position: "+Cam.at);    D.text(estilo,-1.3,0.45,S+"Distance between camera and object 3D: "+Distance(Cam.matrix.pos,PosEsfera));    estilo.align.set(-1,0);      D.text(estilo,1.2,0.85,"Cam.setAngle");    D.text(estilo,1.2,0.8,"Cam.setSpherical");    D.text(estilo,1.2,0.75,"Cam.setFromAt");    D.text(estilo,1.2,0.7,"Cam.setPosDir");              estilo.color=RED;    if ((Tm.time()-tiempo)>0.4f) {                                    D.text(estilo,1.3,(0.85-(0.05*iVar2)),"<<<");                                    estilo.align.set(1,0);                                    D.text(estilo,-1.3,(0.85-(0.05*iVar1)),">>>");                                 }    estilo.scale*=1.2;    estilo.align.set(0,0);    switch (iVar1) {        case 0 : case 5 : case 6 : D.text(estilo,0,-0.8,"Use arrow keys left/right(x), up/down(y), hold left Ctrl button(z)"); break;        case 1 : case 3 : D.text(estilo,0,-0.8,"Use arrow keys up/down"); break;        default : D.text(estilo,0,-0.8,"Use arrow keys left/right");    }       estilo.scale*=1.4;    estilo.shadow=1;          if ((Tm.time()-tiempo)>1.8f) {tiempo=Tm.time();} else if ((Tm.time()-tiempo)>1.1f) {estilo.color=WHITE;}    D.text(estilo,0,-0.9,"Press ENTER to focus the Mesh");   } /******************************************************************************/``` I have obtained the formulas about this other formula: tan(A) = opp / adj