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);