Free Camera problem

Started by
1 comment, last by MrDarkKnight 12 years, 2 months ago
Hello
I have a free camera in my game. My problem is the camera moves too fast when I move the mouse. Now if I slow down the camera the pitch and yaw in degrees also slow down.

I want to slow down my camera movement but in the same time I don't want the Pitch and Yaw to slow down.

If you look at the video the pitch and yaw are very slow, I can speed them up by increasing the mouse sensitivity variable but then the camera moves very fast.

I just want to make a free camera that locks at 90 and -90 degrees when I move up and down.

Sorry I’m not making a lot of sense but I don't know how to explain it.

I already made a free camera in OpenGL and it works but I don't know what I’m doing wrong in XNA.


XNA free camera problem
[media]
[/media]

OpenGL free camera locks at 90 and -90 degrees
[media]
[/media]

code FreeCamera class

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace XNA_4._0_Tutorial
{
class FreeCamera : Camera
{
public float Pitch { get; set; }
public float Yaw { get; set; }
public Vector3 Position { get; set; }
public Vector3 Target { get; set; }
private Vector3 Translation;

public FreeCamera(Vector3 Position, GraphicsDevice graphicsDevice)
: base(graphicsDevice)
{
this.Position = Position;
}
public void Lock()
{
if(Pitch > 90.0f)
Pitch = 90.0f;
if(Pitch < -90.0f)
Pitch = -90.0f;

if(Yaw > 360.0f)
Yaw -=360.0f;
if(Yaw < 0.0f)
Yaw +=360.0f;
}
public void Rotate(float YawOffset, float PitchOffset)
{
this.Yaw += MathHelper.ToDegrees(YawOffset);
this.Pitch += MathHelper.ToDegrees(PitchOffset);
}
public void Move(Vector3 Translation)
{
this.Translation += Translation;
}
public void Control(GraphicsDeviceManager graphics, GameTime gameTime, float Velocity, float MouseSensitivity)
{
MouseState mouseState = Mouse.GetState();
KeyboardState keyState = Keyboard.GetState();

int ScreenX = graphics.PreferredBackBufferWidth / 2;
int ScreenY = graphics.PreferredBackBufferHeight / 2;

Lock();

// Determine how much the camera should turn
float deltaX = MouseSensitivity * (ScreenX - (float)mouseState.X);
float deltaY = MouseSensitivity * (ScreenY - (float)mouseState.Y);

Mouse.SetPosition(ScreenX, ScreenY);

// Rotate the camera
Rotate(deltaX, deltaY);
Vector3 translation = Vector3.Zero;

// Determine in which direction to move the camera
if (keyState.IsKeyDown(Keys.W)) translation += Vector3.Forward;
if (keyState.IsKeyDown(Keys.S)) translation += Vector3.Backward;
if (keyState.IsKeyDown(Keys.A)) translation += Vector3.Left;
if (keyState.IsKeyDown(Keys.D)) translation += Vector3.Right;

// Move 10 units per millisecond, independent of frame rate
translation *= Velocity * (float)gameTime.ElapsedGameTime.TotalMilliseconds;

// Move the camera
Move(translation);

// Update the camera
Update();
}
public override void Update()
{
// Calculate the rotation matrix
Matrix Rrotation = Matrix.CreateFromYawPitchRoll(Yaw, Pitch, 0);

// Offset the position and reset the translation
Translation = Vector3.Transform(Translation, Rrotation);
Position += Translation;
Translation = Vector3.Zero;

// Calculate the new target
Vector3 forward = Vector3.Transform(Vector3.Forward, Rrotation);
Target = Position + forward;

// Calculate the up vector
Vector3 up = Vector3.Transform(Vector3.Up, Rrotation);

// Calculate the view matrix
View = Matrix.CreateLookAt(Position, Target, up);
}
}
}
Advertisement
MathHelper.ToDegrees() converts an angle from radians to degrees, if so why are you assuming that YawOffset and PitchOffset are angles in radians?
Also your calling Lock() before updating the yaw, and pitch values... And the Matrix.CreateFromYawPitchRoll() expects the angles in radians...

So if you move the mouse just one pixel the camera will be rotated 1 radian ~= 57 degrees, then you CreateFromYawPitchRoll() excepts the angles in radians so you rotate your camera ~3 265 degrees happy.png

So try this:


float deltaX, deltaY;

// If mouse moved rotate camera
if(ScreenX != (float)mouseState.X)
deltaX = MathHelper.ToRadians(5.0f); //Rotate camera 5 degrees

if(ScreenY != (float)mouseState.Y)
deltaY = MathHelper.ToRadians(5.0f); //Rotate camera 5 degrees

//You also have update your Lock function to use radians instead of degrees
Lock();

Mouse.SetPosition(ScreenX, ScreenY);

//You also have update your Rotate function to use radians instead of degrees
// Rotate the camera
Rotate(deltaX, deltaY);
Thank you. You were a lot of help.
I didn't know that Matrix.CreateFromYawPitchRoll() expects the angles in radians. I should read the hints in VS2010 more often. smile.png

Anyways I just did the following and it fixed my problem.


public void Lock()
{
float Angle = 90.0f;

Angle = MathHelper.ToRadians(Angle);

if (Pitch > Angle)
Pitch = Angle;
if (Pitch < -Angle)
Pitch = -Angle;

if (Yaw > (Angle * 4) )
Yaw -= (Angle * 4);
if(Yaw < (Angle - Angle) )
Yaw += (Angle * 4);
}


also I did what you said and changed the lock function place in my code. If i don't, crazy things happens biggrin.png


public void Control(GraphicsDeviceManager graphics, GameTime gameTime, float Velocity, float MouseSensitivity)
{
.......
// Determine how much the camera should turn
float deltaX = MouseSensitivity * (ScreenX - (float)mouseState.X);
float deltaY = MouseSensitivity * (ScreenY - (float)mouseState.Y);

Lock();

Mouse.SetPosition(ScreenX, ScreenY);
// Rotate the camera
Rotate(deltaX, deltaY);
......
}

This topic is closed to new replies.

Advertisement