Jump to content
• Advertisement

# Lock camera on object

## Recommended Posts

Okay so I wanted the camera to automatically always look towards a specific position. But how do I calculate the yaw/pitch/roll of the camera with only the position of the camera and the position I want to look at in 3d space?

#### Share this post

##### Share on other sites
Advertisement
1 hour ago, A1pha 1 said:

how do I calculate the yaw/pitch/roll of the camera with only the position of the camera and the position I want to look at in 3d space?

That's not enough information to unambiguously derive the camera orientation. There are infinite possible camera up-axes that will satisfy your contraints. However, I'm assuming you desire the camera to remain roughly "upright", so...

Typically one takes the vector from the camera to the look point as the camera look direction. Then you pick an arbitrary up-axis (say, world up, which may be the positive the Y-axis), make sure it isn't parallel to the look direction (pick another abritrary axis in this case, say positive X-axis), take the cross-product of the up and look vectors to derive the right vector. Then cross the right and look vectors to get your actual up vector.

Now you have 3 perpendicular vectors (look, right, and up), and you can derive the 4x4 rotation matrix by substituiting in those values.

#### Share this post

##### Share on other sites

Thanks! I will give it a try!

#### Share this post

##### Share on other sites
void perform_rotation_to_vector(t3dpoint<float> vec, bool normalized)
{
t3dpoint<float> v;
if (normalized == false) v = Normalize( vec ); else v = vec;

t3dpoint<float> temp; temp = vector_multiple(v, 10000.0);

t3dpoint<float> temp2; temp2 = vector_multiple(rf, 10000.0);

float act_pitch;    act_pitch = GetLatitude( temp2 );
float act_yaw;      act_yaw	  = GetLongitude( temp2 );

act_pitch 	= VALIDUJ( act_pitch );
act_yaw 	= VALIDUJ( act_yaw );

//ShowMessage("act pitch: "+FloatToStr(act_pitch));
//ShowMessage("act yaw: "+FloatToStr(act_yaw));

float new_pitch;    new_pitch = GetLatitude( temp );
float new_yaw;      new_yaw	  = GetLongitude( temp );

new_pitch 	= VALIDUJ( new_pitch );
new_yaw 	= VALIDUJ( new_yaw );
//
//ShowMessage("new pitch: "+FloatToStr(new_pitch));
//ShowMessage("new yaw: "+FloatToStr(new_yaw));
float yawsign = 1.0; float pitchsign = 1.0;

float mpitch;
if (act_pitch > new_pitch)
mpitch = -(act_pitch - new_pitch);
else        {
mpitch =   new_pitch - act_pitch;
pitchsign = -1.0;
}

float myaw;
if (act_yaw > new_yaw)
myaw = -(act_yaw - new_yaw);
else    {
myaw =   new_yaw - act_yaw;

yawsign = -1.0;
}
float mpsine; float mpcosine;
mpsine 	= sin( mpitch * imopi );
mpcosine = cos( mpitch * imopi );

float mysine; float mycosine;
mysine 	= sin( myaw * imopi );
mycosine = cos( myaw * imopi );

if (mpitch 	< 0) 	pitchsign 	= -1.0;
if (myaw 	< 0) 	yawsign 	= -1.0;

yaw(mycosine,yawsign*mysine);
DoRotation();
pitch(mpcosine,pitchsign*mpsine);
DoRotation();

temp2 = vector_multiple(rf, 10000.0);

act_pitch = GetLatitude( temp2 );
act_yaw	  = GetLongitude( temp2 );

//ShowMessage("act pitch: "+FloatToStr(act_pitch));
//ShowMessage("act yaw: "+FloatToStr(act_yaw));

}

void perform_roll_to_vector(t3dpoint<float> vec, bool normalized)
{
t3dpoint<float> v;
if (normalized == false) v = Normalize( vec ); else v = vec;

t3dpoint<float> temp; temp = vector_multiple(v, 10000.0);

t3dpoint<float> temp2;
temp2.x = bx;
temp2.y = by;
temp2.z = bz;
temp2 = vector_multiple(temp2, 10000.0);
float angela = RAD_TO_DEG*( AngleBetweenVectors(temp, temp2) ) + 180.0;

float mpsine; float mpcosine;
mpsine 	= sin( angela * imopi );
mpcosine = cos( angela * imopi );

//      float yawsign = 1.0;

roll(mpcosine,mpsine);
DoRotation();

}

You need to define the initial vector direction i cant remember but this should be 0.0, 0.0, 1.0 or z was -1

Where


template <class type> type  aGetLongitude(t3dpoint<type> cpos)   //poludniki (Dlugosc)
{
type       angle;
angle = n2dGetPolarCoordAngleA(cpos.x,cpos.z) / type(2.0*pi);

angle = -360.0*angle;
angle = VALIDUJ(angle)+90.0;
angle = VALIDUJ(angle);
return angle;

}

template <class type> type  aGetLatitude(t3dpoint<type> cpos)
{

t3dpoint<type> cpn;
cpn = Normalize(cpn);

type t = cpn.x*cpn.x + cpn.z*cpn.z;
t = sqrt(t);
if (cpn.y == 0.0) return 0.0;
type tanges = t / cpn.y;
type angle;
angle = atan(tanges);
angle = RAD_TO_DEG * angle;
if (angle < 0) angle = -1.0*(90.0 + angle); else
angle = 90.0 - angle;
return angle;
}

template <class type>  double  GetLongitudeLD(t3dpoint<type> cpos, t3dpoint<type> pos)   //poludniki (Dlugosc)
{
double       angle;
angle = n2dGetPolarCoordAngleAD(( double)cpos.x-( double)pos.x,( double)cpos.z-( double)pos.z) / (pild*2.0);
//

angle = -360.0*angle;
angle = VALIDUJ(angle)+90.0;
angle = VALIDUJ(angle);
return angle;

}

template <class type>  double  AngleBetween2Points(t3dpoint<type> cpos, t3dpoint<type> pos)   //poludniki (Dlugosc)
{
double       angle;
angle = n2dGetPolarCoordAngleAD(( double)cpos.x-( double)pos.x,( double)cpos.z-( double)pos.z) / (pild*2.0);
//

angle = -360.0*angle;
angle = VALIDUJ(angle);
return angle;

}

template <class type>  double  GetLatitudeLD(t3dpoint<type> cpos, t3dpoint<type> pos)
{

t3dpoint<type> cpn;
cpn = vectorAB(pos,cpos);
cpn = Normalize(cpn);

if (cpn.y == 0.0) return 0.0;

double a = ( double)cpn.x;
double b = ( double)cpn.z;

double t = a*a+b*b;
t = sqrt(t);

double tanges = t / double(cpn.y);
double angle;
angle = atan(tanges);
angle =  angle * piimo;
if (angle < 0) angle = -1.0*(90.0 + angle); else
angle = 90.0 - angle;
return angle;
}
template <class type> type  n2dGetPolarCoordAngleA(type x,type y)
{
if ( (x > 0) && (y >= 0) ) { 	return atan(y/x);        }

if ( (x > 0) && (y < 0) )  { 	return atan(y/x)+2.0*3.1415926535897932384626433832795;  	  }

if  (x < 0)                {	return atan(y/x)+3.1415926535897932384626433832795;   	  }

if ( (x == 0) && (y > 0) )  { 	return 3.1415926535897932384626433832795/2.0;                   }

if ( (x == 0) && (y < 0) )  { 	return 3.0*3.1415926535897932384626433832795/2.0;                 }
//last versions were without .0 just simple 2 division
return - 1000.0;
}

inline double  n2dGetPolarCoordAngleAD(double x,double y)
{
if ( (x == 0) && (y > 0) )  { 	return 3.1415926535897932384626433832795/2.0;                   }

if ( (x == 0) && (y < 0) )  { 	return 3.0*3.1415926535897932384626433832795/2.0;                 }

if (x == 0) return - 1000.0;
double k; k = ( double)y / ( double)x;
if ( (x > 0) && (y >= 0) ) { 	return atan(k);        }

if ( (x > 0) && (y < 0) )  { 	return atan(k)+2.0*3.1415926535897932384626433832795;  	  }

if  (x < 0)                {	return atan(k)+3.1415926535897932384626433832795;   	  }

//last versions were without .0 just simple 2 division
return - 1000.0;
}

But the best pick is to use matrices for that see glulookat function or search forum for my posts inshowed thencode

Edited by WiredCat

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account

## Sign in

Already have an account? Sign in here.

Sign In Now

• Advertisement
• Advertisement

• ### Popular Contributors

1. 1
Rutin
42
2. 2
3. 3
4. 4
5. 5
• Advertisement

• 9
• 27
• 20
• 14
• 14
• ### Forum Statistics

• Total Topics
633384
• Total Posts
3011598
• ### Who's Online (See full list)

There are no registered users currently online

×

## Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!