Sign in to follow this  
WarrenPaul

3rd person Camera positioning

Recommended Posts

Hello I've been trying to make my code for the camera show the my model at the bottom center of the screen.

this is an example of what Im after:
[url="http://gamesareevil.com/wp-content/uploads/2011/05/starraiders.jpg"]http://gamesareevil....starraiders.jpg[/url]


I tried raising both the camera and where the camera is looking at on the up axis which when you first start the game the ship is positioned correctly on the screen but as soon as you move the camera does not follow it properly and the ship ends up somewhere else on the screen. Which was the advise I found at this post [url="http://forums.create.msdn.com/forums/p/31689/181122.aspx"]http://forums.create...689/181122.aspx[/url] which means either I did something wrong or it doesnt work right.



Here is my update camera code:


[code]

public void UpdateCamera(Ship target, GraphicsDevice device)
{
cameraRotation = Quaternion.Lerp(cameraRotation, target.ShipRotation, 0.1f);

Vector3 campos = new Vector3(0, 0.1f, 0.6f);

campos = Vector3.Transform(campos, Matrix.CreateFromQuaternion(cameraRotation));
campos += target.ShipPosition;

Vector3 camup = new Vector3(0, 1, 0);
camup = Vector3.Transform(camup, Matrix.CreateFromQuaternion(cameraRotation));

viewMatrix = Matrix.CreateLookAt(campos, target.ShipPosition, camup);
projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
device.Viewport.AspectRatio, 0.000001f, 100000000.0f);

cameraPosition = campos;
cameraUpDirection = camup;
}

[/code]



here is the input and draw methods which are slightly related I guess, incase something in there helps


[code] public void HandleInput(GamePadState gamePadState, GameTime gameTime)
{
float leftRightRot = 0;
float upDownRot = 0;
float rollRotation = 0;

float turningSpeed = (float)
gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f;

leftRightRot += gamePadState.ThumbSticks.Left.X * 0.03f;
upDownRot -= gamePadState.ThumbSticks.Left.Y * 0.03f;

if (gamePadState.IsButtonDown(Buttons.LeftShoulder))
rollRotation += turningSpeed;
if (gamePadState.IsButtonDown(Buttons.RightShoulder))
rollRotation -= turningSpeed;

Quaternion additionalRot = Quaternion.CreateFromAxisAngle(new
Vector3(0, -1, 0), leftRightRot) * Quaternion.CreateFromAxisAngle(new
Vector3(1, 0, 0), upDownRot) * Quaternion.CreateFromAxisAngle(new
Vector3(0, 0, -1), rollRotation);

shipRotation *= additionalRot;

shipThrust(ref shipPosition, shipRotation);
}



public void Draw(Effect effect, Camera camera)
{
Matrix worldMatrix = Matrix.CreateScale(0.0005f, 0.0005f, 0.0005f) *
Matrix.CreateRotationY(MathHelper.Pi) * Matrix.CreateFromQuaternion(shipRotation) *
Matrix.CreateTranslation(shipPosition);

Matrix[] shipTransforms = new Matrix[shipModel.Bones.Count];
shipModel.CopyAbsoluteBoneTransformsTo(shipTransforms);
foreach (ModelMesh mesh in shipModel.Meshes)
{
foreach (Effect currentEffect in mesh.Effects)
{
currentEffect.CurrentTechnique = currentEffect.Techniques["Colored"];
currentEffect.Parameters["xWorld"].SetValue(
shipTransforms[mesh.ParentBone.Index] * worldMatrix);
currentEffect.Parameters["xView"].SetValue(camera.ViewMatrix);
currentEffect.Parameters["xProjection"].SetValue(camera.ProjectionMatrix);
currentEffect.Parameters["xEnableLighting"].SetValue(true);
currentEffect.Parameters["xLightDirection"].SetValue(camera.LightDirection);
currentEffect.Parameters["xAmbient"].SetValue(0.5f);
}
mesh.Draw();
}
}

[/code]



I'm using code from Riemer's flightsim tutorials so far [url="http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series2/Quaternions.php"]http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series2/Quaternions.php[/url], but it positions the ship in the middle of the screen. How would I change the code to make the ship position at the bottom center instead? I'm rather new to XNA and 3D programming so if you can help please explain with some example for me to see :)


thanks.

Share this post


Link to post
Share on other sites
Add an offset to the camera's position after getting the position behind the item.
Camera.Position = PositionBehind + (Camera.UpAxis * 0.75 * Item.DepthFromCamera * Camera.HeightSlope)

Share this post


Link to post
Share on other sites
[quote name='Dawoodoz' timestamp='1310296288' post='4833297']
Add an offset to the camera's position after getting the position behind the item.
Camera.Position = PositionBehind + (Camera.UpAxis * 0.75 * Item.DepthFromCamera * Camera.HeightSlope)
[/quote]




Hey, thanks for the reply. I had a play around based on what you said above. I made it position the ship correctly until I make the model move forward, it just keeps raising the y axis of the camera indefinately which means its getting further and further away from the ship and looking down at it. Rotating on the spot works perfect though. I'll paste the new code, lets see if I could do it better then what I did as well.



[code]

public void UpdateCamera(Ship target, GraphicsDevice device)
{
cameraRotation = Quaternion.Lerp(cameraRotation, target.ShipRotation, 0.05f);

Vector3 camup = new Vector3(0, 1, 0);
camup = Vector3.Transform(camup, Matrix.CreateFromQuaternion(cameraRotation));

Vector3 PositionBehind = new Vector3(0, -0.12f,
0.3f);
PositionBehind = Vector3.Transform(PositionBehind, Matrix.CreateFromQuaternion(cameraRotation));
PositionBehind += target.ShipPosition;

Vector3 camOffset = new Vector3();
camOffset = PositionBehind + (camup * 0.10f * PositionBehind.Z * -0.5f);


Vector3 PositionAbove = new Vector3(0, 0.1f, -0.1f);
PositionAbove = Vector3.Transform(PositionAbove, Matrix.CreateFromQuaternion(cameraRotation));
PositionAbove += target.ShipPosition;

Vector3 targetOffset = new Vector3();
targetOffset = PositionAbove + (camup * 0.10f * PositionAbove.Z * 0.1f);

viewMatrix = Matrix.CreateLookAt(camOffset, targetOffset, camup);
projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
device.Viewport.AspectRatio, 0.000001f, 100000000.0f);

cameraPosition = camOffset;
cameraUpDirection = camup;
}



private void shipThrust(ref Vector3 position, Quaternion rotationQuat)
{
GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);

Vector3 addVector = Vector3.Transform(new Vector3(0, 0, -1), rotationQuat);
position += addVector * (gamePadState.Triggers.Right * 0.05f);
}

[/code]

Also included the method for moving the model forward using the gamepad trigger.


thanks for the help so far.




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