Reputation: 2743
I really don't know whats is going wrong here. The game seams to be drawing funny. The first thing I notice is that when the player moves, the camera move before the avatar does so the camera comes out of the avatars head a bit. Then I noticed that when you look at the avatar from the side you can see though his shoulder and into his cheast cavity (it does not do this in the animation player I build and also in Maya). The next thing I notice is when the player moves forward, the ground starts to flicker. Am I calling the draw method wrong or something?
here is the camera class I am using
public class Camera : Microsoft.Xna.Framework.GameComponent
{
//Cam Matrices
//viw is composed of position, direction, and up vectors
public Matrix view { get; protected set; }
public Matrix projection { get; protected set; }
//to move the camera
//used to recreate view matrix each frame
public Vector3 cameraPosition { get; protected set; }
public Vector3 cameraDirection; //not the target/ point camera is looking at a relative direction camrea is faceing
//to find target add the cameraPosition and cameraDirection togeater
public Vector3 cameraUp;
public Vector3 target;
//camera controls
float speed = 3;
MouseState prevMouseState;
// Pi/180 = 1 degree
// Max yaw/pitch variables
//this is for moving the head only not the body
float totalYaw = MathHelper.PiOver2;
public float currentYaw = 0;
float totalPitch = MathHelper.PiOver2;
public float currentPitch = 0;
public float leftTrigYaw;
public float rightTrigYaw;
//constructor
public Camera(Game game, Vector3 pos, Vector3 target, Vector3 up)
: base(game)
{
//build camera view matrix
cameraPosition = pos;
cameraDirection = target - pos;
cameraDirection.Normalize(); //Convert to magintue 1
//make it easy to apply differt speeds to movement of camera
cameraUp = up;
CreateLookAt();
projection = Matrix.CreatePerspectiveFieldOfView
(
MathHelper.PiOver4,
(float)Game.Window.ClientBounds.Width / (float)Game.Window.ClientBounds.Height,
1, 3000);
}
private void CreateLookAt()
{
//middle variable is the target!
view = Matrix.CreateLookAt(cameraPosition, cameraPosition + cameraDirection, cameraUp);
}
public override void Initialize()
{
Mouse.SetPosition(Game.Window.ClientBounds.Width / 2,
Game.Window.ClientBounds.Height / 2);
prevMouseState = Mouse.GetState();
base.Initialize();
}
public override void Update(GameTime gameTime)
{
GamePadState currentState = GamePad.GetState(PlayerIndex.One);
//move forward
if (currentState.ThumbSticks.Left.Y > 0 || Keyboard.GetState().IsKeyDown(Keys.W))
{
//move just on x and x axis Y is controled other places.
cameraPosition += new Vector3(cameraDirection.X, 0, cameraDirection.Z) * speed;
}
//move backward
if (currentState.ThumbSticks.Left.Y < 0 || Keyboard.GetState().IsKeyDown(Keys.S))
{
//move just on x and x axis Y is controled other places.
cameraPosition -= new Vector3(cameraDirection.X, 0, cameraDirection.Z) * speed;
}
//move left
if (currentState.ThumbSticks.Left.X < 0 || Keyboard.GetState().IsKeyDown(Keys.A))
{
//cross product of the up and direction vectors can give the side direction
cameraPosition += Vector3.Cross(cameraUp, cameraDirection) * speed;
}
//move right
if (currentState.ThumbSticks.Left.X > 0 || Keyboard.GetState().IsKeyDown(Keys.D))
{
cameraPosition -= Vector3.Cross(cameraUp, cameraDirection) * speed;
}
//mouse movements
// Yaw rotation
float yawAngle = (-MathHelper.PiOver4 / 150) *
(Mouse.GetState().X - prevMouseState.X);
float padYaw = (-MathHelper.PiOver2 / 50) *
(currentState.ThumbSticks.Right.X);
if (Math.Abs(currentYaw + yawAngle) < totalYaw)
{
cameraDirection = Vector3.Transform(cameraDirection,
Matrix.CreateFromAxisAngle(cameraUp, yawAngle));
currentYaw += yawAngle;
}
//rotate left and right
if (currentState.ThumbSticks.Right.X < 0 || currentState.ThumbSticks.Right.X > 0)
{
if (Math.Abs(currentYaw + padYaw) < totalYaw)
{
cameraDirection = Vector3.Transform(cameraDirection,
Matrix.CreateFromAxisAngle(cameraUp, padYaw));
currentYaw += padYaw;
}
}
leftTrigYaw = (MathHelper.PiOver2 / 50) *
(currentState.Triggers.Left);
if (currentState.Triggers.Left > 0.0f)
{
cameraDirection = Vector3.Transform(cameraDirection,
Matrix.CreateFromAxisAngle(cameraUp, leftTrigYaw));
}
rightTrigYaw = (-MathHelper.PiOver2 / 50) *
(currentState.Triggers.Right);
if (currentState.Triggers.Right > 0.0f)
{
cameraDirection = Vector3.Transform(cameraDirection,
Matrix.CreateFromAxisAngle(cameraUp, rightTrigYaw));
}
// Pitch rotation
float pitchAngle = (MathHelper.PiOver4 / 150) *
(Mouse.GetState().Y - prevMouseState.Y);
float padPitch = (-MathHelper.PiOver2 / 50) *
(currentState.ThumbSticks.Right.Y);
if (Math.Abs(currentPitch + pitchAngle) < totalPitch)
{
cameraDirection = Vector3.Transform(cameraDirection,
Matrix.CreateFromAxisAngle(
Vector3.Cross(cameraUp, cameraDirection),
pitchAngle));
currentPitch += pitchAngle;
}
if (currentState.ThumbSticks.Right.Y < 0 || currentState.ThumbSticks.Right.Y > 0)
{
if (Math.Abs(currentPitch + padPitch) < totalPitch)
{
cameraDirection = Vector3.Transform(cameraDirection,
Matrix.CreateFromAxisAngle(
Vector3.Cross(cameraUp, cameraDirection),
padPitch));
currentPitch += padPitch;
}
}
//reset mouse state
target = cameraPosition + cameraDirection;
prevMouseState = Mouse.GetState();
//for testing only!! get rid of this when done
if (currentState.Buttons.A == ButtonState.Pressed)
{
//fly upwar
cameraPosition += new Vector3(0, 15, 0);
}
if (currentState.Buttons.B == ButtonState.Pressed)
{
//fly upwar
cameraPosition -= new Vector3(0, 15, 0);
}
//call camera creat look at method to build new view matrix
CreateLookAt();
if (Keyboard.GetState().IsKeyDown(Keys.Escape))
{
Game.Exit();
}
base.Update(gameTime);
}
}
}
I am also using a custom model handler to draw the ground and the avatar
public class CModel
{
public Vector3 Position { get; set; }
public Vector3 Rotation { get; set; }
public Vector3 Scale { get; set; }
public Model Model { get; private set; }
private Matrix[] modelTransforms;
private GraphicsDevice graphicsDevice;
public CModel(Model Model, Vector3 Position, Vector3 Rotation,
Vector3 Scale, GraphicsDevice graphicsDevice)
{
this.Model = Model;
modelTransforms = new Matrix[Model.Bones.Count];
Model.CopyAbsoluteBoneTransformsTo(modelTransforms);
this.Position = Position;
this.Rotation = Rotation;
this.Scale = Scale;
this.graphicsDevice = graphicsDevice;
}
public void Draw(Matrix View, Matrix Projection)
{
// Calculate the base transformation by combining
// translation, rotation, and scaling
Matrix baseWorld = Matrix.CreateScale(Scale)
* Matrix.CreateFromYawPitchRoll(
Rotation.Y, Rotation.X, Rotation.Z)
* Matrix.CreateTranslation(Position);
foreach (ModelMesh mesh in Model.Meshes)
{
Matrix localWorld = modelTransforms[mesh.ParentBone.Index]
* baseWorld;
foreach (ModelMeshPart meshPart in mesh.MeshParts)
{
BasicEffect effect = (BasicEffect)meshPart.Effect;
effect.World = localWorld;
effect.View = View;
effect.Projection = Projection;
effect.EnableDefaultLighting();
}
mesh.Draw();
}
}
}
}
I dont know where the problem is originating from but these are the only two things that I can think of that would give the problem. Thanks for any help with this.
Here is what is going on with the model. I am sure that the normal are right in maya because I used the simple model drawer that Microsoft has up on the tutorials but then you can somewhat see though the guys shoulder and arm. I could not get a picture of the ground flickering because it happens too fast to really screen capture it.But every time i move the camera, the ground jumps up and down a lot. and then stops when I stop moving the camera to look around. am I not calling the the camera.Update() method because its a game component and is linked up with the game1 class.
This is how I am drawing the models it is a draw method in the custom model class
public void Draw(Matrix View, Matrix Projection)
{
// Calculate the base transformation by combining
// translation, rotation, and scaling
Matrix baseWorld = Matrix.CreateScale(Scale)
* Matrix.CreateFromYawPitchRoll(
Rotation.Y, Rotation.X, Rotation.Z)
* Matrix.CreateTranslation(Position);
foreach (ModelMesh mesh in Model.Meshes)
{
Matrix localWorld = modelTransforms[mesh.ParentBone.Index]
* baseWorld;
foreach (ModelMeshPart meshPart in mesh.MeshParts)
{
BasicEffect effect = (BasicEffect)meshPart.Effect;
effect.World = localWorld;
effect.View = View;
effect.Projection = Projection;
effect.EnableDefaultLighting();
}
mesh.Draw();
}
}
Upvotes: 1
Views: 265
Reputation: 10896
For the artifacts on the model: The model doesn't look like it's being rendered properly. Your DrawPrimitives call probably isn't feeding the graphics card the right data (either your vertex/index buffers are filled in wrong or you have the primitive type/count wrong). Try rendering it in wireframe mode, you should be able to see the triangles that are getting distorted, producing these artifacts.
As for the ground - I will look some more through the code and see if I can think of anything.
Upvotes: 1