Lock camera on object

Started by
3 comments, last by _WeirdCat_ 6 years, 3 months ago

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?

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.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Thanks! I will give it a try!


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

This topic is closed to new replies.

Advertisement