自定义灵活摄像机

public enum CameraType
{
    LandObject,
    Aircraft
}
 
public class Camera
{
    private CameraType cameraType;
    private Vector3 right;
    private Vector3 up;
    private Vector3 look;
    private Vector3 pos;
 
    public Camera():this(CameraType.LandObject)
    {
 
    }
 
    public Camera(CameraType cameraType)
    {
        this.cameraType = cameraType;
 
        this.pos = new Vector3(0, 0, 0);
        this.right = new Vector3(1, 0, 0);
        this.up = new Vector3(0, 1, 0);
        this.look = new Vector3(0, 0, 1);
    }
 
    public Vector3 CamPosition
    {
        get
        {
            return this.pos;
        }
        set
        {
            this.pos = value;
        }
    }
 
    public Vector3 CamRight
    {
        get
        {
            return this.right;
        }
    }
 
    public Vector3 CamUp
    {
        get
        {
            return this.up;
        }
    }
 
    public Vector3 CamLook
    {
        get
        {
            return this.look;
        }
    }
 
    /// <summary>
    /// 前进后退
    /// </summary>
    /// <param name="units"></param>
    public void Walk(float units)
    {
        if (this.cameraType == CameraType.LandObject)
        {
            this.pos += Vector3.Multiply(
                new Vector3(this.look.X, 0, this.look.Z),
                units);
        }
        else if (this.cameraType == CameraType.Aircraft)
        {
            this.pos += Vector3.Multiply(
                this.look, units);
        }
    }
 
    /// <summary>
    /// 左右移动
    /// </summary>
    /// <param name="units"></param>
    public void LeftAndRight(float units)
    {
        if (this.cameraType == CameraType.LandObject)
        {
            this.pos += Vector3.Multiply(
                new Vector3(this.right.X, 0, this.right.Z),
                units);
        }
        else if (this.cameraType == CameraType.Aircraft)
        {
            this.pos += Vector3.Multiply(
                this.right,
                units);
        }
    }
 
    /// <summary>
    /// 升降操作
    /// </summary>
    /// <param name="units"></param>
    public void UpAndDown(float units)
    {
        if (this.cameraType == CameraType.LandObject)
        {
            this.pos.Y += units;
        }
        else if (this.cameraType == CameraType.Aircraft)
        {
            this.pos += Vector3.Multiply(
                this.up,
                units);
        }
    }
 
    /// <summary>
    /// 俯仰操作
    /// </summary>
    /// <param name="angle"></param>
    public void RotateByX(float angle)
    {
        Matrix rotateXMx = Matrix.RotationAxis(
            this.right,
            angle);
 
        this.look = Vector3.TransformCoordinate(
            this.look,
            rotateXMx);
 
        this.up = Vector3.TransformCoordinate(
            this.up,
            rotateXMx);
    }
 
    /// <summary>
    /// 旋转操作
    /// </summary>
    /// <param name="angle"></param>
    public void RotateByY(float angle)
    {
        Matrix rotateYMx = Matrix.Identity;
        if (this.cameraType == CameraType.LandObject)
        {
            rotateYMx = Matrix.RotationY(angle);
        }
        else if (this.cameraType == CameraType.Aircraft)
        {
            rotateYMx = Matrix.RotationAxis(
                this.up,
                angle);
        }
 
        this.look = Vector3.TransformCoordinate(
            this.look,
            rotateYMx);
        this.right = Vector3.TransformCoordinate(
            this.right,
            rotateYMx);
    }
 
    /// <summary>
    /// 放大缩小
    /// </summary>
    /// <param name="units"></param>
    public void ZoomAndIn(float units)
    {
        Vector3 direction = Vector3.Subtract(this.look, this.pos);
        float tempLen = direction.Length() + units;
        direction.Normalize();
        direction.Multiply(tempLen);
 
        this.pos = Vector3.Subtract(this.look, direction);
    }
 
    /// <summary>
    /// 滚动操作roll
    /// </summary>
    /// <param name="angle"></param>
    public void RotateByZ(float angle)
    {
        if (this.cameraType == CameraType.Aircraft)
        {
            Matrix rotateZMx = Matrix.RotationAxis(
                this.look,
                angle);
 
            this.right = Vector3.TransformCoordinate(
                this.right,
                rotateZMx);
 
            this.up = Vector3.TransformCoordinate(
                this.up,
                rotateZMx);
        }
    }
 
    /// <summary>
    /// 获取视图矩阵
    /// </summary>
    /// <returns></returns>
    public Matrix GetViewMatrix()
    {
        this.look.Normalize();
 
        this.up = Vector3.Cross(this.look, this.right);
        this.up.Normalize();
 
        this.right = Vector3.Cross(this.up, this.look);
        this.right.Normalize();
 
        float x = -Vector3.Dot(this.right, this.pos);
        float y = -Vector3.Dot(this.up, this.pos);
        float z = Vector3.Dot(this.look, this.pos);
 
        Matrix viewMatrix = Matrix.Identity;
        viewMatrix.M11 = right.X; viewMatrix.M12 = up.X; viewMatrix.M13 = look.X; viewMatrix.M14 = 0;
        viewMatrix.M21 = right.Y; viewMatrix.M22 = up.Y; viewMatrix.M23 = look.Y; viewMatrix.M24 = 0;
        viewMatrix.M31 = right.Z; viewMatrix.M32 = up.Z; viewMatrix.M33 = look.Z; viewMatrix.M34 = 0;
        viewMatrix.M41 = x; viewMatrix.M42 = y; viewMatrix.M43 = z; viewMatrix.M44 = 1;
 
        return viewMatrix;
    }
 
    /// <summary>
    /// 设置摄像机类型
    /// </summary>
    /// <param name="type"></param>
    public void SetCameraType(CameraType type)
    {
        this.cameraType = type;
    }
}

调用示例:

this.camera.ZoomAndIn(walkDistance);
Matrix view = this.camera.GetViewMatrix();
this.device.SetTransform(TransformType.View, view);
原文地址:https://www.cnblogs.com/sharpfeng/p/1999732.html