سؤال

What I need is to calculate where my lookat 3d vector would be based upon the camera position, the Y rotation and Z rotation, I would assume that any number greater than 0 would be sufficient for the distance from the camera to look at.

Here is the static class I'm using to control the camera and calculate the view and projection matrices, etc.

Class members that involve the position and rotation:

public static Vector3 Position { get; set; } //Publicly available for use outside the class
public static Vector3 Rotation { get; set; }
private static Vector3 camPos = new Vector3(0.0f, 200.0f, 300.0f); //However we work with these for manipulation of values
private static Vector3 camTarget = new Vector3(0, 0, -1200.0f);

private static float rotY = 0, rotZ = 0; //I believe that these are the correct axis following the right hand catasian coordinate system

My camera's update function:

public static void Update()        
{
    //Controls here

    //Update Position here
    Position = camPos;            

    //Update camTarget based on Position, rotY and rotZ <- Need help with this bit

    //After calculating camTarget update Rotation
    Rotation = camTarget;

    UpdateMatrices();
}

UpdateMatrices() handles everything else and works as it should but here it is just in case you would like to see it:

public static void UpdateMatrices()
{
    Matrix rotationMatrix = Matrix.CreateRotationX(MathHelper.ToRadians(90));
    Vector3 transformedReference = Vector3.Transform(Vector3.Forward, rotationMatrix);

    View = Matrix.CreateLookAt(Position, Rotation, Vector3.Forward);
    Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, nearClip, farClip);
    World = Matrix.Identity;

    CamBoundingFrustrum = new BoundingFrustum(View * Projection);
}

Would anyone be kind enough to share the secret to this please?

هل كانت مفيدة؟

المحلول

Rather than using Vector3.Forward, pull the .Forward and .Up vectors from your rotation matrix:

    public void UpdateMatrices()
    {
        /// assumes Rotation is a Vector3 containing rotation around each axis expressed in radians
        Matrix rotationMatrix = Matrix.CreateFromYawPitchRoll(Rotation.Y, Rotation.X, Rotation.Z);
        /// View = Matrix.CreateLookAt(Position, Rotation, Vector3.Forward);

        View = Matrix.CreateLookAt(Position, Position + rotationMatrix.Forward, rotationMatrix.Up);
        Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, nearClip, farClip);

        /// World matrix needs to match your translation and rotation used above
        /// XNA expects matrices to be concatenated in SRT (scale, rotation, then translate) order:
        World = rotationMatrix * Matrix.CreateTranslation(Position);

        CamBoundingFrustrum = new BoundingFrustum(View * Projection);
    }

Note that you have to add the camera's translation (via a vector you're storing, or from the camera's world matrix .Translation property) to the RotationMatrix.Forward to get a real target.

The matrix .Forward, .Backward,.Left,.Right,.Up and .Down properties are the same as the equivalent Vector3 properties transformed by the rotation matrix. so, RotationMatrix.Forward points in the direction you're looking, .Up is orthogonal to that, etc.

If you just use Vector3.Forward, you don't get a transformed vector, and weird things can happen.

Other notes:

  1. Don't make everything static. Create an instance of your camera class during Game.Initialize() and add it as a property. static should be used with caution - it can cause all sorts of fun threading issues that will drive you insane.
  2. I'd also recommend switching to a quaternion instead of yaw/roll/pitch (if you haven't already) since it avoids gimble lock, but that's a different topic.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top