Sign in to follow this  
FreJa

first-person camera

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

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

Sign in to follow this