RICH525234

Hey all im trying to get my camera to work properly i want it positioned behind the model at a certain distance which i have done, but when i turn my avatar i want my camera to turn with it at a proportional distance

. right now i can get the camera to turn and follow my avatar from a fixed position easy just put the model position in cameratarget, I can also get the camera to stay behind the avatar at a fixed position but when it follows the model it doesn't turn with it. can i get some help here i can't figure out how to get the code to work so it follows the model and also turns with it so its always behind below is my code minus some of the unneeded code..

public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
ContentManager content;
Model Happyface;
Model floor;
Vector3 cameraPosition = new Vector3(0.0f, 50.0f, 500.0f);
Vector3 cameraTarget = new Vector3(0.0f, 0.0f, 0.0f);
Vector3 cameraUp = Vector3.Up;
float Fov = MathHelper.ToRadians(45f);
float aspectRatio = 640.0f / 480.0f;
float nearClip = 1.0f;
float farClip = 500000.0f;
Vector3 cameraReference = new Vector3(0, 0, 10);
Vector3 avatarVelocity = Vector3.Zero;
float avatarRotation = 0.0f;
Vector3 avatarPosition = new Vector3(0.0f, 0.0f, 0.0f);
protected override void Update(GameTime gameTime)
{
// Allows the default game to exit on Xbox 360 and Windows
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
UserInput(); ;
//didnt use this methods cause they dont turn the camera with the avatar
// camera change follows model but doesnt turn with it
//cameraChange();
avatarPosition += avatarVelocity;
avatarPosition *= .99f;
base.Update(gameTime);
}

protected void UserInput()
{
GamePadState currentState = GamePad.GetState(PlayerIndex.One);
if (currentState.IsConnected)
{
//rotate avatar
avatarRotation -= currentState.ThumbSticks.Left.X * 0.10f;
Vector3 avatarVelocityAdd = Vector3.Zero;
avatarVelocityAdd.X = -(float)Math.Sin(avatarRotation);
avatarVelocityAdd.Z = -(float)Math.Cos(avatarRotation);
avatarVelocityAdd *= currentState.Triggers.Right;
avatarVelocity += avatarVelocityAdd;
if (currentState.Buttons.A == ButtonState.Pressed)
{
avatarPosition = Vector3.Zero;
avatarVelocity = Vector3.Zero;
avatarRotation = 0.0f;
}
}
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
DrawModel(Happyface, avatarPosition, avatarRotation);
DrawModel(floor, Vector3.Zero, 90.0f);
base.Draw(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
//dont use this but this will work if i figure out how to turn the camera still havent figured it //out yet so wont use it but it
//keeps camera right behind objectif only can turn my camera its third person mode.
protected void cameraChange()
{
Matrix rotationMatrix = Matrix.CreateRotationY(avatarRotation);
Vector3 transformedReference = Vector3.Transform(cameraReference, rotationMatrix);
cameraPosition = avatarPosition + transformedReference;
cameraPosition.X = avatarPosition.X - 500f;
cameraPosition.Z = avatarPosition.Z - 500f;
}
//didnt use this tried to but wont work
protected void CameraMOVING()
{
cameraPosition.X = (float)( Math.Cos(avatarRotation) * Math.Cos(avatarRotation));
cameraPosition.Y = (float)( Math.Sin(avatarRotation));
cameraPosition.Z = (float)(Math.Cos(avatarRotation) * Math.Sin(avatarRotation));
}
//draw a model anymodel just pass the model and attach there reference in solution //explorer
public void DrawModel(Model model, Vector3 Position, float Rotation)
{
Matrix[] transforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(transforms);
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms[mesh.ParentBone.Index] * Matrix.CreateRotationY(Rotation) * Matrix.CreateTranslation(Position);
UpdateCamera(effect);
}
mesh.Draw();
}
}
//chaanges the camera positions
protected void UpdateCamera(BasicEffect effect)
{
effect.View = Matrix.CreateLookAt(cameraPosition,avatarPosition, cameraUp);
effect.Projection = Matrix.CreatePerspectiveFieldOfView(Fov, aspectRatio, nearClip, farClip);
}
}
}
.thanks for the help guys



Re: XNA Game Studio Express Camera Help

thedo

Probably not the most effeciant way to do it, but what I tend to do for simple follow-cams is to multiply the matrix fo the object i'm chasing by the distance behind it i want to place the camera and then invert the result.

so something like

Matrix view = hero.world*Matrix.CreateTranslation(0,0,10);

view = Matrix.Invert(view);

I may have the direction wrong in the example (I d ont have any XNA code on this PC to double check), but this will follow the hero's character, and its pretty simple to follow the code too. Now I'm sure someone will rip me on efficiency, and yada yada, but it works OK for me so far.

N






Re: XNA Game Studio Express Camera Help

RICH525234

That wasnt very clear to me excuse me as i didn't understand what i should do. take my model position in the draw method and multiply it by that new Translation you posted then take the effect.view and and invert it all in the draw method i posted. sorry im confused by the reply





Re: XNA Game Studio Express Camera Help

thedo

Sorry if I wasnt clear. Basically what we are doing is this.

1stly you take your model that you are following, calculate its matrix however you are doing that. Once you have done that that matrix contains its rotation and position in the world. Multiplying a second fixed matrix with the matrix of what you want to follow will move the result a fixed difference from the model you are following. We then invert it to make it work properly as a view matrix.

So........

//Move around and rotate the player as you see fit

//Move the camera 10 units directly behind the player

Matrix CameraDistanceFromModel = Matrix.CreateTranslation(0,0,10);

//move the view matrix to the a point relative to the player matrix

Matrix ViewMatrix = modelToFollowMatrix*CameraDistanceFromModel;

//The ViewMatrix position is now correct, however needs inverting to make it work (someone better at maths will be able to explain why)

ViewMatrix = Matrix.Invert(ViewMatrix);

//How to use the data in a basic Effect to render

BasicEffect be = new BasicEffect();

bs.World = modelToFollowMatrix;

bs.View = ViewMatrix ;

//Render stuff here

Note the code is pretty pseudo codey. I'm not very good at explaining things like this, and i hope I havent confused you more!

N






Re: XNA Game Studio Express Camera Help

conard

I think you should check out riemer's flight sim tutorial and see how he handles "Dynamic Camera".

I think basically you create a vector to store where the camera will be in relation to the avatar.

campos = new Vector3(0, 0, 10);

Create a rotation matrix with your rotation value.

Matrix camrot = Matrix.CreateRotationY(rot);

Transform the campos vector by the camrot vector, then transform campos vector by a translation of the targetPosition, then create your look at. Since campos always starts with the same value you only need to translate it by the target position, not the last value of the camera.
campos = Vector3.Transform(campos, camrot);
campos = Vector3.Transform(campos, Matrix.CreateTranslation(targetPosition));
viewMatrix = Matrix.CreateLookAt(campos, targetPosition, Vector3.Up);

How this helps.





Re: XNA Game Studio Express Camera Help

Danny Gregory

There is a much simpler way to calculate the camera's position without requiring additional matrix operations.

The rows of your typical orientation matrix can be interpreted geometrically as the new directions of the cardinal X/Y/Z axis after transformation. That is, the first row vector of the matrix points in the direction of the "new" X axis, the second row vector in the direction of the Y axis and the third in the direction of the Z axis.

As we can consider that the cardinal X/Y/Z axis in your avatar's local coordinate space corresponds directly to your avatar's side, up and forward orientation vectors, we can simply extract a direction vector from the third row of the avatar's World matrix that will point in the direction that the avatar is facing.

After obtaining this direction vector, we simply multiply it by the distance behind the avatar that the camera should follow and then subtract this vector from the avatar's position to get the camera position.

Using the rows of a transformation matrix in this way is common practice. So much so that the Matrix class includes properties that will extract appropriate rows from the matrix for you!

Don't worry if you couldn't follow that explanation. Just look at this (psuedo) code, it's simple!


// Calculate the avatar's World matrix
world = rotation * translation;

// Extract the forward vector from the world matrix. You should normalise this
// vector if your world matrix includes scaling. There is also a Matrix.Backwards property
// if you prefer to use that instead.
forward = world.Forward;

// Calculate the camera position.
camera_position = avatar_position - (forward * follow_distance);