zoukankan      html  css  js  c++  java
  • [3D]第一人称相机类Camera

    自己根据C++ D3D的源码改写一个相机类(第一人称)。

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using Microsoft.DirectX;
      6 using Microsoft.DirectX.PrivateImplementationDetails;
      7 using Microsoft.DirectX.Direct3D;
      8 
      9 namespace AppScene
     10 {
     11     public enum CameraType { LANDOBJECT, AIRCRAFT };
     12     public class Camera
     13     {
     14         CameraType mCameraType;
     15         Vector3 mPosition; //相机位置
     16         Vector3 mLook;//LookVector  
     17         Vector3 mUp;// UpVector  
     18         Vector3 mRight;// RightVector  
     19         Vector3 ViewFrustum;// 平面截投体  
     20 
     21         protected Viewport mViewPort;//视口大小
     22         protected Matrix m_ProjectionMatrix; //上一次渲染采用的投影变换矩阵 Projection matrix used in last render.
     23         protected Matrix m_ViewMatrix; //上一次渲染采用的观察矩阵 View matrix used in last render.
     24         protected Matrix m_WorldMatrix = Matrix.Identity;//世界变换矩阵
     25         public Camera()
     26         {
     27             mCameraType = CameraType.AIRCRAFT;
     28             mPosition = new Vector3(0.0f, 0.0f, -50.0f);//注意默认位置,现在对了。
     29             mRight = new Vector3(0.0f, 1.0f, 0.0f);
     30             mUp = new Vector3(0.0f, 1.0f, 0.0f);
     31             mLook = new Vector3(0.0f, 0.0f, 10.0f);
     32         }
     33         public Camera(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 upVector)
     34         {
     35             mCameraType = CameraType.AIRCRAFT;
     36             mPosition = new Vector3(0.0f, 0.0f, -100.0f);
     37             mRight = new Vector3(1.0f, 0.0f, 0.0f);
     38             mUp = new Vector3(0.0f, 1.0f, 0.0f);
     39             mLook = new Vector3(0.0f, 0.0f, 0.0f);
     40         }
     41         public void setCameraType(CameraType cameraType)
     42         {
     43             mCameraType = cameraType;
     44         }
     45         //前后移动
     46         public void walk(float units)
     47         {
     48             // move only on xz plane for land object
     49             if (mCameraType == CameraType.LANDOBJECT)
     50                 mPosition += new Vector3(mLook.X, 0.0f, mLook.Z) * units;
     51 
     52             if (mCameraType == CameraType.AIRCRAFT)
     53                 mPosition += mLook * units;
     54         }
     55         //左右移动,扫射
     56         public void strafe(float units)
     57         {
     58             // move only on xz plane for land object
     59             if (mCameraType == CameraType.LANDOBJECT)
     60                 mPosition += new Vector3(mRight.X, 0.0f, mRight.Z) * units;
     61 
     62             if (mCameraType == CameraType.AIRCRAFT)
     63                 mPosition += mRight * units;
     64         }
     65         //上下移动
     66         public void fly(float units)
     67         {
     68             // move only on y-axis for land object
     69             if (mCameraType == CameraType.LANDOBJECT)
     70                 mPosition.Y += units;
     71 
     72             if (mCameraType == CameraType.AIRCRAFT)
     73                 mPosition += mUp * units;
     74         }
     75 
     76         // 倾斜角 
     77         public void Pitch(float angle)
     78         {
     79             Matrix T = Matrix.Identity;
     80             //D3DXMatrixRotationAxis(&T, &_right, angle);
     81             T.RotateAxis(mRight, angle);
     82             // rotate _up and _look around _right vector
     83             mUp.TransformCoordinate(T);
     84             mLook.TransformCoordinate(T);
     85             //D3DXVec3TransformCoord(&_up, &_up, &T);
     86             //D3DXVec3TransformCoord(&_look, &_look, &T);
     87         }
     88         //俯仰角
     89         public void Roll(float angle)
     90         {
     91             // only roll for aircraft type
     92             if (mCameraType == CameraType.AIRCRAFT)
     93             {
     94                 Matrix T = Matrix.Identity;
     95                 T.RotateAxis(mLook, angle);
     96 
     97                 // rotate _up and _right around _look vector
     98                 mRight.TransformCoordinate(T);
     99                 mUp.TransformCoordinate(T);
    100             }
    101         }
    102         // 航偏角
    103         public void Yaw(float angle)
    104         {
    105             Matrix T = Matrix.Identity;
    106 
    107             // rotate around world y (0, 1, 0) always for land object
    108             if (mCameraType == CameraType.LANDOBJECT)
    109                 T.RotateY(angle);
    110             // rotate around own up vector for aircraft
    111             if (mCameraType == CameraType.AIRCRAFT)
    112                 T.RotateAxis(mUp, angle);
    113 
    114             // rotate _right and _look around _up or y-axis
    115             mRight.TransformCoordinate(T);
    116             mLook.TransformCoordinate(T);
    117         }
    118         public void SetPosition(Vector3 position)// 设置相机世界坐标  
    119         {
    120             mPosition = position;
    121         }
    122         //更新相机状态
    123         public Matrix UpdateCamera()
    124         {
    125             Matrix mViewMatrix = Matrix.Identity;
    126             // Keep camera's axes orthogonal to eachother
    127             //D3DXVec3Normalize(&_look, &_look);
    128             mLook.Normalize();
    129             //D3DXVec3Cross(&, &_look, &_right);
    130             // _up = Vector3.Cross(_look, _right);
    131             //D3DXVec3Normalize(&_up, &_up);
    132             mUp.Normalize();
    133             //D3DXVec3Cross(&_right, &_up, &_look);
    134             mRight = Vector3.Cross(mUp, mLook);
    135             //D3DXVec3Normalize(&_right, &_right);
    136             mRight.Normalize();
    137             // Build the view matrix:
    138             //float x = -D3DXVec3Dot(&_right, &_pos);
    139             //float y = -D3DXVec3Dot(&_up, &_pos);
    140             //float z = -D3DXVec3Dot(&_look, &_pos);
    141             float x = -Vector3.Dot(mRight, mPosition);
    142             float y = -Vector3.Dot(mUp, mPosition);
    143             float z = -Vector3.Dot(mLook, mPosition);
    144 
    145             mViewMatrix.M11 = mRight.X; mViewMatrix.M12 = mUp.X; mViewMatrix.M13 = mLook.X; mViewMatrix.M14 = 0.0f;
    146             mViewMatrix.M21 = mRight.Y; mViewMatrix.M22 = mUp.Y; mViewMatrix.M23 = mLook.Y; mViewMatrix.M24 = 0.0f;
    147             mViewMatrix.M31 = mRight.Z; mViewMatrix.M32 = mUp.Z; mViewMatrix.M33 = mLook.Z; mViewMatrix.M34 = 0.0f;
    148             mViewMatrix.M41 = x; mViewMatrix.M42 = y; mViewMatrix.M43 = z; mViewMatrix.M44 = 1.0f;
    149             return mViewMatrix;
    150         }
    151 
    152         public void Update(Microsoft.DirectX.Direct3D.Device m_Device3d)
    153         {
    154             Matrix V = UpdateCamera();
    155             m_Device3d.SetTransform(TransformType.View, V);
    156         }
    157         //视口大小
    158         public Viewport Viewport
    159         {
    160             get
    161             {
    162                 return mViewPort;
    163             }
    164         }
    165         //观察变换矩阵
    166         public Matrix ViewMatrix
    167         {
    168             get
    169             {
    170                 return m_ViewMatrix;
    171             }
    172         }
    173         //投影变换矩阵
    174         public Matrix ProjectionMatrix
    175         {
    176             get
    177             {
    178                 return m_ProjectionMatrix;
    179             }
    180         }
    181         //世界变换矩阵
    182         public Matrix WorldMatrix
    183         {
    184             get
    185             {
    186                 return m_WorldMatrix;
    187             }
    188         }
    189         /// <summary>
    190         /// UnProject和Project之前需要调用该方法
    191         /// </summary>
    192         /// <param name="m_Device3d"></param>
    193         public void ComputeMatrix(Device m_Device3d)
    194         {
    195             m_WorldMatrix = m_Device3d.GetTransform(TransformType.World);
    196             m_ProjectionMatrix = m_Device3d.GetTransform(TransformType.Projection);
    197             m_ViewMatrix = m_Device3d.GetTransform(TransformType.View);
    198             mViewPort = m_Device3d.Viewport;
    199         }
    200         /// <summary>
    201         /// Projects a point from world to screen coordinates.
    202         /// 计算指定世界坐标的屏幕坐标
    203         /// </summary>
    204         /// <param name="point">Point in world space</param>
    205         /// <returns>Point in screen space</returns>
    206         public Vector3 Project(Vector3 point)
    207         {
    208             point.Project(mViewPort, m_ProjectionMatrix, m_ViewMatrix, m_WorldMatrix);
    209             return point;
    210         }
    211 
    212         internal Vector3 UnProject(Vector3 v1)
    213         {
    214             v1.Unproject(mViewPort, m_ProjectionMatrix, m_ViewMatrix, m_WorldMatrix);
    215             return v1;
    216         }
    217     }
    218 }
    View Code

    增加一个围绕某条射线旋转的方法:

     1  //
     2         public void RotateRay(float angle, Vector3 vOrigin, Vector3 vAxis)
     3         {
     4             // 计算新的焦点
     5             Vector3 vView = mLook - vOrigin;
     6             Matrix temp = Matrix.RotationAxis(vAxis, angle);
     7             vView.TransformCoordinate(temp);
     8             //vView.RotateAxis(angle, vAxis);
     9             mLook = vOrigin + vView;
    10 
    11             // 计算新的视点
    12             vView = mPosition - vOrigin;
    13            // Matrix temp2 = Matrix.RotationAxis(vAxis, angle);
    14             vView.TransformCoordinate(temp);
    15             //vView.RotateAxis(angle, vAxis);
    16             mPosition = vOrigin + vView;
    17 
    18             mUp.TransformCoordinate(temp);
    19           //  m_strafe.RotateAxis(angle, vAxis);
    20         }
  • 相关阅读:
    Python 读写
    测试项目总结之手淘安全中心
    Python 单元测试
    Python __name__变量
    java数据类型取值范围
    java数据类型之间的转换
    Git 常用命令清单
    Linux Distribution
    UNIX&Linux发展图谱
    Linux 软件大全
  • 原文地址:https://www.cnblogs.com/yhlx125/p/3317377.html
Copyright © 2011-2022 走看看