MNM
MNM

Reputation: 2743

Ground and model are flickering and somewhat invisable

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. See though model

See the inside of his arm though the top!

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

Answers (1)

Ani
Ani

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

Related Questions