home *** CD-ROM | disk | FTP | other *** search
/ Introduction to 3D Game …ogramming with DirectX 12 / Introduction-to-3D-Game-Programming-with-DirectX-12.ISO / Code.Textures / Common / Camera.cpp next >
Encoding:
C/C++ Source or Header  |  2016-03-02  |  5.4 KB  |  276 lines

  1. //***************************************************************************************
  2. // Camera.h by Frank Luna (C) 2011 All Rights Reserved.
  3. //***************************************************************************************
  4.  
  5. #include "Camera.h"
  6.  
  7. using namespace DirectX;
  8.  
  9. Camera::Camera()
  10. {
  11.     SetLens(0.25f*MathHelper::Pi, 1.0f, 1.0f, 1000.0f);
  12. }
  13.  
  14. Camera::~Camera()
  15. {
  16. }
  17.  
  18. XMVECTOR Camera::GetPosition()const
  19. {
  20.     return XMLoadFloat3(&mPosition);
  21. }
  22.  
  23. XMFLOAT3 Camera::GetPosition3f()const
  24. {
  25.     return mPosition;
  26. }
  27.  
  28. void Camera::SetPosition(float x, float y, float z)
  29. {
  30.     mPosition = XMFLOAT3(x, y, z);
  31.     mViewDirty = true;
  32. }
  33.  
  34. void Camera::SetPosition(const XMFLOAT3& v)
  35. {
  36.     mPosition = v;
  37.     mViewDirty = true;
  38. }
  39.  
  40. XMVECTOR Camera::GetRight()const
  41. {
  42.     return XMLoadFloat3(&mRight);
  43. }
  44.  
  45. XMFLOAT3 Camera::GetRight3f()const
  46. {
  47.     return mRight;
  48. }
  49.  
  50. XMVECTOR Camera::GetUp()const
  51. {
  52.     return XMLoadFloat3(&mUp);
  53. }
  54.  
  55. XMFLOAT3 Camera::GetUp3f()const
  56. {
  57.     return mUp;
  58. }
  59.  
  60. XMVECTOR Camera::GetLook()const
  61. {
  62.     return XMLoadFloat3(&mLook);
  63. }
  64.  
  65. XMFLOAT3 Camera::GetLook3f()const
  66. {
  67.     return mLook;
  68. }
  69.  
  70. float Camera::GetNearZ()const
  71. {
  72.     return mNearZ;
  73. }
  74.  
  75. float Camera::GetFarZ()const
  76. {
  77.     return mFarZ;
  78. }
  79.  
  80. float Camera::GetAspect()const
  81. {
  82.     return mAspect;
  83. }
  84.  
  85. float Camera::GetFovY()const
  86. {
  87.     return mFovY;
  88. }
  89.  
  90. float Camera::GetFovX()const
  91. {
  92.     float halfWidth = 0.5f*GetNearWindowWidth();
  93.     return 2.0f*atan(halfWidth / mNearZ);
  94. }
  95.  
  96. float Camera::GetNearWindowWidth()const
  97. {
  98.     return mAspect * mNearWindowHeight;
  99. }
  100.  
  101. float Camera::GetNearWindowHeight()const
  102. {
  103.     return mNearWindowHeight;
  104. }
  105.  
  106. float Camera::GetFarWindowWidth()const
  107. {
  108.     return mAspect * mFarWindowHeight;
  109. }
  110.  
  111. float Camera::GetFarWindowHeight()const
  112. {
  113.     return mFarWindowHeight;
  114. }
  115.  
  116. void Camera::SetLens(float fovY, float aspect, float zn, float zf)
  117. {
  118.     // cache properties
  119.     mFovY = fovY;
  120.     mAspect = aspect;
  121.     mNearZ = zn;
  122.     mFarZ = zf;
  123.  
  124.     mNearWindowHeight = 2.0f * mNearZ * tanf( 0.5f*mFovY );
  125.     mFarWindowHeight  = 2.0f * mFarZ * tanf( 0.5f*mFovY );
  126.  
  127.     XMMATRIX P = XMMatrixPerspectiveFovLH(mFovY, mAspect, mNearZ, mFarZ);
  128.     XMStoreFloat4x4(&mProj, P);
  129. }
  130.  
  131. void Camera::LookAt(FXMVECTOR pos, FXMVECTOR target, FXMVECTOR worldUp)
  132. {
  133.     XMVECTOR L = XMVector3Normalize(XMVectorSubtract(target, pos));
  134.     XMVECTOR R = XMVector3Normalize(XMVector3Cross(worldUp, L));
  135.     XMVECTOR U = XMVector3Cross(L, R);
  136.  
  137.     XMStoreFloat3(&mPosition, pos);
  138.     XMStoreFloat3(&mLook, L);
  139.     XMStoreFloat3(&mRight, R);
  140.     XMStoreFloat3(&mUp, U);
  141.  
  142.     mViewDirty = true;
  143. }
  144.  
  145. void Camera::LookAt(const XMFLOAT3& pos, const XMFLOAT3& target, const XMFLOAT3& up)
  146. {
  147.     XMVECTOR P = XMLoadFloat3(&pos);
  148.     XMVECTOR T = XMLoadFloat3(&target);
  149.     XMVECTOR U = XMLoadFloat3(&up);
  150.  
  151.     LookAt(P, T, U);
  152.  
  153.     mViewDirty = true;
  154. }
  155.  
  156. XMMATRIX Camera::GetView()const
  157. {
  158.     assert(!mViewDirty);
  159.     return XMLoadFloat4x4(&mView);
  160. }
  161.  
  162. XMMATRIX Camera::GetProj()const
  163. {
  164.     return XMLoadFloat4x4(&mProj);
  165. }
  166.  
  167.  
  168. XMFLOAT4X4 Camera::GetView4x4f()const
  169. {
  170.     assert(!mViewDirty);
  171.     return mView;
  172. }
  173.  
  174. XMFLOAT4X4 Camera::GetProj4x4f()const
  175. {
  176.     return mProj;
  177. }
  178.  
  179. void Camera::Strafe(float d)
  180. {
  181.     // mPosition += d*mRight
  182.     XMVECTOR s = XMVectorReplicate(d);
  183.     XMVECTOR r = XMLoadFloat3(&mRight);
  184.     XMVECTOR p = XMLoadFloat3(&mPosition);
  185.     XMStoreFloat3(&mPosition, XMVectorMultiplyAdd(s, r, p));
  186.  
  187.     mViewDirty = true;
  188. }
  189.  
  190. void Camera::Walk(float d)
  191. {
  192.     // mPosition += d*mLook
  193.     XMVECTOR s = XMVectorReplicate(d);
  194.     XMVECTOR l = XMLoadFloat3(&mLook);
  195.     XMVECTOR p = XMLoadFloat3(&mPosition);
  196.     XMStoreFloat3(&mPosition, XMVectorMultiplyAdd(s, l, p));
  197.  
  198.     mViewDirty = true;
  199. }
  200.  
  201. void Camera::Pitch(float angle)
  202. {
  203.     // Rotate up and look vector about the right vector.
  204.  
  205.     XMMATRIX R = XMMatrixRotationAxis(XMLoadFloat3(&mRight), angle);
  206.  
  207.     XMStoreFloat3(&mUp,   XMVector3TransformNormal(XMLoadFloat3(&mUp), R));
  208.     XMStoreFloat3(&mLook, XMVector3TransformNormal(XMLoadFloat3(&mLook), R));
  209.  
  210.     mViewDirty = true;
  211. }
  212.  
  213. void Camera::RotateY(float angle)
  214. {
  215.     // Rotate the basis vectors about the world y-axis.
  216.  
  217.     XMMATRIX R = XMMatrixRotationY(angle);
  218.  
  219.     XMStoreFloat3(&mRight,   XMVector3TransformNormal(XMLoadFloat3(&mRight), R));
  220.     XMStoreFloat3(&mUp, XMVector3TransformNormal(XMLoadFloat3(&mUp), R));
  221.     XMStoreFloat3(&mLook, XMVector3TransformNormal(XMLoadFloat3(&mLook), R));
  222.  
  223.     mViewDirty = true;
  224. }
  225.  
  226. void Camera::UpdateViewMatrix()
  227. {
  228.     if(mViewDirty)
  229.     {
  230.         XMVECTOR R = XMLoadFloat3(&mRight);
  231.         XMVECTOR U = XMLoadFloat3(&mUp);
  232.         XMVECTOR L = XMLoadFloat3(&mLook);
  233.         XMVECTOR P = XMLoadFloat3(&mPosition);
  234.  
  235.         // Keep camera's axes orthogonal to each other and of unit length.
  236.         L = XMVector3Normalize(L);
  237.         U = XMVector3Normalize(XMVector3Cross(L, R));
  238.  
  239.         // U, L already ortho-normal, so no need to normalize cross product.
  240.         R = XMVector3Cross(U, L);
  241.  
  242.         // Fill in the view matrix entries.
  243.         float x = -XMVectorGetX(XMVector3Dot(P, R));
  244.         float y = -XMVectorGetX(XMVector3Dot(P, U));
  245.         float z = -XMVectorGetX(XMVector3Dot(P, L));
  246.  
  247.         XMStoreFloat3(&mRight, R);
  248.         XMStoreFloat3(&mUp, U);
  249.         XMStoreFloat3(&mLook, L);
  250.  
  251.         mView(0, 0) = mRight.x;
  252.         mView(1, 0) = mRight.y;
  253.         mView(2, 0) = mRight.z;
  254.         mView(3, 0) = x;
  255.  
  256.         mView(0, 1) = mUp.x;
  257.         mView(1, 1) = mUp.y;
  258.         mView(2, 1) = mUp.z;
  259.         mView(3, 1) = y;
  260.  
  261.         mView(0, 2) = mLook.x;
  262.         mView(1, 2) = mLook.y;
  263.         mView(2, 2) = mLook.z;
  264.         mView(3, 2) = z;
  265.  
  266.         mView(0, 3) = 0.0f;
  267.         mView(1, 3) = 0.0f;
  268.         mView(2, 3) = 0.0f;
  269.         mView(3, 3) = 1.0f;
  270.  
  271.         mViewDirty = false;
  272.     }
  273. }
  274.  
  275.  
  276.