About Store Forum Documentation Contact



Post Reply 
Basic. Camera Controls
Author Message
kaito Offline
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: <!-- m --><a class="postlink" href="http://perso.orange.es/tomas_cg75/TallerCamara.html">http://perso.orange.es/tomas_cg75/TallerCamara.html</a><!-- m -->

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
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #2
Re: Basic. Camera Controls
Quote:Is there any mathematical function in esenthel to estimate the yaw and pitch between two 3D positions?
no

Quote: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).
'dir' is just the camera direction
'up' it is the up vector of the camera
02-18-2009 05:16 PM
Find all posts by this user Quote this message in a reply
kaito Offline
Member

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 && zp<zc) {return 3;}
    if (zp==zc && xp>xc) {return -1.5;}
    if (zp==zc && xp<xc) {return 1.5;}
    if (zp>zc) {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
02-19-2009 09:33 PM
Find all posts by this user Quote this message in a reply
Post Reply