make an object rotate to face a vector (Opengl 3D)

Started by
13 comments, last by impulsee 9 years ago

Hi guys

I have been trying to work out how to make an object rotate to face another object in Opengl (with the glm library) but in still a little confused on a couple of things and was hoping you guys could help me out smile.png

At this moment I think what I have to do is have a normalized direction vector, and then a normalized vector of the object I want to face - current object and then computer the dot and cross product from this for the axis and angle of rotation. It is at this point where I am stuck on what to do next (if I even have the first part right). I should also mention that I am trying to use quaternions so any help that you can give me on applying it both for a rotation matrix and a quaternions would be very appreciated.

For the original set up, I use a set of Euler angles (in a vec 3 for pitch, yaw and roll) and do the following myquat = glm::quat(Eulerangles);. and then turn the quaternion into a matrix glm::mat4 RotationMatrix = glm::toMat4(myquat);

Here is the code I have so far



void Gamemodelimported::rotateobject(glm::vec3 otherposition)
{
  glm::vec3 currentlook;

  currentlook.x = glm::cos(glm::pitch(myquat)) * glm::cos(glm::yaw(myquat) + (0.0174532925 * 90));
  currentlook.z = -glm::cos(glm::pitch(myquat)) * glm::sin(glm::yaw(myquat) + (0.0174532925 * 90));
  currentlook.y = glm::sin(glm::pitch(myquat));

  currentlook = glm::normalize(currentlook);

  glm::vec3 diff = otherposition - _position;

  diff = glm::normalize(diff);
    
  float angle = glm::acos(glm::dot(diff,currentlook));

  glm::vec3 corrsspro = glm::cross(diff,currentlook); 


 
}

If you also have time can you suggest a good way to make the object slowly rotate to face the vector point.

Thanks for you time and help smile.png

Edit: I should mention that the + 90 on the yaw is to compensate for the original model rotation (I think that's the correct way not sure but it does move in the correct direction with that code)

Advertisement

I think atan2 is what you are looking for. It will let you pass in the legs of a triangle (X/Y) and give you the angle.. I've used it to figure yaw and pitch, each.

The quaternion version of the look at is more expensive than the conversion from a look at matrix.

Just make a look at matrix, transpose it and convert to a quaternion and you have the result.


Just make a look at matrix, transpose it and convert to a quaternion and you have the result.

can you go into more depth about this if you don't mind sorry, still trying to get to grips with it all.

Use GLM lookAt :


detail::tmat4x4<T> glm::gtc::matrix_transform::lookAt
(
  detail::tvec3< T > const & eye,
  detail::tvec3< T > const & center,
  detail::tvec3< T > const & up
)

On your case the rotation matrix will be :


glm::mat4 RotationMatrix = glm::transpose(glm::lookAt(_position, otherposition, glm::vec3(0.0f, 1.0f, 0.0f)));

Now convert to quaternion if you use quaternion and not matrix for the representation of the rotation :


Rotation = glm::toQuat(RotationMatrix);

Arr thanks for the help :)

Something extra to consider:

While it may happen to be convenient that your OpenGL math functions do the same operations as your world manipulation math functions, I strongly recommend you consider them as distinct actions. Moving a game object should not be considered the same thing as the OpenGL rendering motion.


The objects being shown to the player have very little to do with the representation of game objects within a simulation, which also typically has very little to do with the objects inside a physics simulation. Yes the player can see the end results of the action, but it is a common mistake for beginners to equate graphics, physics, and simulator motions since the all happen to use the same branch of mathematics.

Just because they happen to use the same type of math operations does not mean they are otherwise closely related.

The math operation you call "rotate to face a vector" is typically called "lerp" (a linear interpolation) or "slerp" (spherical linear interpolation), with the difference shown here. There are several similar and related interpolation functions with slight variations to compute cost and behavior. For example you can follow a less compute-expensive path through a quaternion where the vector out is the same but results in rotations, basically a partial barrel roll as the direction smoothly changes.

axis = cross(current, other)
angle = acos( dot(current, other) );

Form these you can create a rotation matrix/quat, if I understand the question correctly.

Just to ask another question, if the object i want to rotate to is directly above me (e.g. position = (0,0,0), otherposition = (0,5,0)) it comes back as error values (I'm guessing because of the matrix construction) is there any practical way around this? (this is with the look at function)

The direction and the up vector must not be parallel, check using a dot product and an epsilon then change the up to (1.0f, 0.0f, 0.0f) of the lookAt matrix.

Another option is to check if the cross product of the direction and the up is the vector (0.0f, 0.0f, 0.0f).

This topic is closed to new replies.

Advertisement