1
\$\begingroup\$

I'm having following problem: Can't set my camera to follow object from behind and rotate when I use left/right arrow. I've tried different tutorial and examples but it still doesn't work for me. Don't know where I'm wrong

this is the code for handle input - so far I've removed the rotation option so the code can compile

 if (currentKeyboardState.IsKeyDown(Keys.Up))
        {
            zTranslationPosition -=5;
            //translatePosition.Z=-  1;
            animationCat.StartClip(animationCat.walk_R);
            animationCat.Update(gameTime.TotalGameTime, true, Matrix.Identity);
        }
        if (currentKeyboardState.IsKeyDown(Keys.Down))
        {
            zTranslationPosition += 5;
            //translatePosition.Z =+  1;
            animationCat.StartClip(animationCat.walk_R);
            animationCat.Update(gameTime.TotalGameTime, true, Matrix.Identity);
        }
        if (currentKeyboardState.IsKeyDown(Keys.Left))
        {
            xTranslationPosition -=5;
           // turn += 1;
            animationCat.StartClip(animationCat.walk_R);
            animationCat.Update(gameTime.TotalGameTime, true, Matrix.Identity);
        }
        if (currentKeyboardState.IsKeyDown(Keys.Right))
        {
           // turn -= 1;
            xTranslationPosition +=5;
            animationCat.StartClip(animationCat.walk_R);
            animationCat.Update(gameTime.TotalGameTime, true, Matrix.Identity);
        }
        turn = MathHelper.Clamp(turn, -1, 1);
        collision.checkCollision(catBounding, hud);


        Vector3 movement = Vector3.Zero;
        catPosition.X = xTranslationPosition;
        catPosition.Y = yTranslationPosition;
        catPosition.Z = zTranslationPosition;
        //catPosition.Y = heightmap.getHeight(catPosition) + 10;
        //translatePosition = newPosition;
        camera.updateCamera(catPosition);

Drawing the object:

Matrix[] bones = animationCat.GetCatTransforms();
        Matrix rotationMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(180)) *
                                Matrix.CreateRotationZ(MathHelper.ToRadians(90));
        Matrix[] transforms = new Matrix[currentModel.Bones.Count];
        currentModel.Root.Transform = Matrix.CreateRotationY(MathHelper.ToRadians(-90));
        currentModel.CopyAbsoluteBoneTransformsTo(transforms);

        foreach (ModelMesh mesh in currentModel.Meshes)
        {
            foreach (Effect effect in mesh.Effects)
            {
                if (effect is SkinnedEffect)
                {
                    SkinnedEffect thiseffect = effect as SkinnedEffect;
                    thiseffect.SetBoneTransforms(bones);
                    thiseffect.View = camera.getView;
                    thiseffect.Projection = camera.getProjection;
                    thiseffect.World = transforms[mesh.ParentBone.Index] *
                                       rotationMatrix * 
                                       Matrix.CreateTranslation(xTranslationPosition, yTranslationPosition, zTranslationPosition);  
                    catBounding = BoundingBox.CreateFromSphere(collision.CreateSphere(currentModel, thiseffect.World));


                }
            }               
            mesh.Draw();
        }

And my camera class which I've borrowed from msdn sample for 3rd person camera.

public class GameCamera 
{
    Matrix view;
    Matrix proj;        

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

    // Set the direction the camera points without rotation.
    Vector3 cameraReference = new Vector3(0, 0, 10);

    Vector3 thirdPersonReference = new Vector3(0, 200, -200);       

    // Set field of view of the camera in radians (pi/4 is 45 degrees).
    static float viewAngle = MathHelper.PiOver4;

    // Set distance from the camera of the near and far clipping planes.
    //static float nearClip = 5.0f;
    static float nearClip = 1.0f;
    static float farClip = 2000.0f;       

    public void updateCamera(Vector3 position)
    {
        Matrix rotationMatrix = Matrix.CreateRotationY(avatarYaw);

        // Create a vector pointing the direction the camera is facing.
        Vector3 transformedReference =
            Vector3.Transform(thirdPersonReference, rotationMatrix);

        // Calculate the position the camera is looking from.
        Vector3 cameraPosition = transformedReference + position;

        // Set up the view matrix and projection matrix.
        view = Matrix.CreateLookAt(cameraPosition, position,
            new Vector3(0.0f, 1.0f, 0.0f));

        Viewport viewport = Game1.graphics.GraphicsDevice.Viewport;
        float aspectRatio = (float)viewport.Width / (float)viewport.Height;

        proj = Matrix.CreatePerspectiveFieldOfView(viewAngle, aspectRatio,
            nearClip, farClip);
    }       
}

As you can see here cat is very small and thats not the view I want to have. view from camera

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Here is a very easy & basic way to accomplish this:

//class scope variable in game class
Matrix catWorldMatrix;

//when drawing cat while setting effect params
//you effectively store the cat's rotation/position
//in the matrix catWorldMatrix which you will eventually allow the camera to use
catWorldMatrix = transforms[mesh.ParentBone.Index] *
                   rotationMatrix * 
                   Matrix.CreateTranslation(xTranslationPosition, yTranslationPosition, zTranslationPosition);
thisEffect.World = catWorldMatrix;

//in camera update method
    public void updateCamera(Matrix objectToFollow)//send catWorldMatrix here
    {
        Vector3 target = objectToFollow.Translation; // camera always looks directly at cat
        Vector3 camPosition = target + objectToFollow.Backward * 10;//locates camera 10 units behind cat 
        view = Matrix.CreateLookAt(camPosition, target, Vector3.Up);

    }

This methodology eliminates the need to rotate the camera's reference vectors. It simply borrows the rotation matrix from the cat (which is the same rotation you effectively want for the camera anyway) and uses it to create a new orthonormal view matrix.

If you want the camera to be slightly higher than the cat & looking past the cat, you simply modify it like this:

Vector3 target = objectToFollow.Translation + (objectToFollow.Up* heightOffset);
Vector3 camPosition = objectToFollow.Translation  + (objectToFolow.Backward * 10) + (objectToFollow.Up * heightOffset);
\$\endgroup\$
3
  • \$\begingroup\$ Forgot to add projection to cameraUpdate method but still it looks kinda wired. Probably needs some calibration. I'll give you some feedback as soon as I'll try it :) \$\endgroup\$ Jan 14, 2013 at 18:15
  • \$\begingroup\$ Sorry, I should have mentioned my code is more like pseudo code intending to convey a concept, idea, or methodology, not necessarily code to be pasted in. It may need to be adjusted slightly depending on details of your implementation. \$\endgroup\$
    – Steve H
    Jan 14, 2013 at 18:17
  • \$\begingroup\$ I've taken it into accoount :) Camera follows the cat so its the most important. Sometimes I'm loosing projection totally don't know why yet but still troubleshooting. \$\endgroup\$ Jan 14, 2013 at 18:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .