Sign in to follow this  

first-person camera

This topic is 3355 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey, My doubt concerns this article: A Simple Quaternion-based camera. Specifically, this method:
void Camera::SetViewByMouse(void)
{
  // the coordinates of our mouse coordinates
  int MouseX, MouseY;

  // the middle of the screen in the x direction
  int MiddleX = SCREENWIDTH/2;

  // the middle of the screen in the y direction
  int MiddleY = SCREENHEIGHT/2;

  // vector that describes mouseposition - center
  Vector MouseDirection(0, 0, 0);

  // static variable to store the rotation about the x-axis, since
  // we want to limit how far up or down we can look.
  // We don't need to cap the rotation about the y-axis as we
  // want to be able to turn around 360 degrees
  static double CurrentRotationX = 0.0;

  // The maximum angle we can look up or down, in radians
  double maxAngle = 1;

  // This function gets the position of the mouse
  SDL_GetMouseState(&MouseX, &MouseY);

  // if the mouse hasn't moved, return without doing
  // anything to our view
  if((MouseX == MiddleX) && (MouseY == MiddleY))
    return;

  // otherwise move the mouse back to the middle of the screen
  SDL_WarpMouse(MiddleX, MiddleY);

  // get the distance and direction the mouse moved in x (in
  // pixels). We can't use the actual number of pixels in radians,
  // as only six pixels  would cause a full 360 degree rotation.
  // So we use a mousesensitivity variable that can be changed to
  // vary how many radians we want to turn in the x-direction for
  // a given mouse movement distance

  // We have to remember that positive rotation is counter-clockwise. 
  // Moving the mouse down is a negative rotation about the x axis
  // Moving the mouse right is a negative rotation about the y axis
  MouseDirection.x = (MiddleX - MouseX)/MouseSensitivity; 
  MouseDirection.y = (MiddleY - MouseY)/MouseSensitivity;

  CurrentRotationX += MouseDirection.y;
  
  // We don't want to rotate up more than one radian, so we cap it.
  if(CurrentRotationX > 1)
  {
    CurrentRotationX = 1;
    return;
  }
  // We don't want to rotate down more than one radian, so we cap it.
  if(CurrentRotationX < -1)
  {
    CurrentRotationX = -1;
    return;
  }
  else
  {
    // get the axis to rotate around the x-axis. 
    Vector Axis = CrossProduct(View - Position, Up);
    // To be able to use the quaternion conjugate, the axis to
    // rotate around must be normalized.
    Axis = Normalize(Axis);

    // Rotate around the y axis
    RotateCamera(MouseDirection.y, Axis.x, Axis.y, Axis.z);
    // Rotate around the x axis
    RotateCamera(MouseDirection.x, 0, 1, 0);
  }
}

My problem is that my CurrentRotationX is only < 1 or > -1 for the first mouse movements, and then it goes >1 and the camera never moves again... Does anyone have any idea of what the problem might be ? Thanks

Share this post


Link to post
Share on other sites
Got it to "work" with gametutorial.com's code:


void Camera::onMousePassiveMotion(int x, int y)
{
int middleX = (int)_winWidth >> 1; // This is a binary shift to get half the width
int middleY = (int)_winHeight >> 1; // This is a binary shift to get half the height
float angleY = 0.0f; // This is the direction for looking up or down
float angleZ = 0.0f; // This will be the value we need to rotate around the Y axis (Left and Right)
static float currentRotX = 0.0f;

// If our cursor is still in the middle, we never moved... so don't update the screen
if( (x == middleX) && (y == middleY) ) return;

// Set the mouse position to the middle of our window
glutWarpPointer(middleX, middleY);

// Get the direction the mouse moved in, but bring the number down to a reasonable amount
angleY = (float)( (middleX - x) ) / 500.0f;
angleZ = (float)( (middleY - y) ) / 500.0f;

// Here we keep track of the current rotation (for up and down) so that
// we can restrict the camera from doing a full 360 loop.
currentRotX -= angleZ;

// If the current rotation (in radians) is greater than 1.0, we want to cap it.
if(currentRotX > 1.0f)
currentRotX = 1.0f;
// Check if the rotation is below -1.0, if so we want to make sure it doesn't continue
else if(currentRotX < -1.0f)
currentRotX = -1.0f;
// Otherwise, we can rotate the view around our position
else
{
// To find the axis we need to rotate around for up and down
// movements, we need to get a perpendicular vector from the
// camera's view vector and up vector. This will be the axis.
btVector3 tmp = _lookAt - _position;
btVector3 vAxis = tmp.cross(_up);
vAxis = vAxis.normalize();

// Rotate around our perpendicular axis and along the y-axis
RotateView(angleZ, vAxis[0], vAxis[1], vAxis[2]);
}

// Rotate around the y axis no matter what the currentRotX is
RotateView(angleY, 0, 1, 0);
}



However... the movement is VERY jerky... and not smooth at all...
Any ideas?

Thanks again!

Share this post


Link to post
Share on other sites
Sign in to follow this