home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Utilities / MView / gxu / d3darcball.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-30  |  2.8 KB  |  135 lines

  1. /*//////////////////////////////////////////////////////////////////////////////
  2. //
  3. // File: d3darcball.cpp
  4. //
  5. // Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  6. //
  7. //
  8. //////////////////////////////////////////////////////////////////////////////*/
  9.  
  10. /*
  11.  * Simple arcball roration controll
  12.  * uses luciforms quaternion stuff
  13.  *
  14.  * Peter-Pike Sloan
  15.  */
  16.  
  17. #include "pchgxu.h"
  18. #include "d3dArcball.h"
  19.  
  20.  
  21. // constructors - default makes most
  22. // sense, SetWindow is what's important...
  23.  
  24. GXArcBall::GXArcBall()
  25. {
  26.     Reset();
  27. }
  28.  
  29. GXArcBall::GXArcBall(const int& x, const int& y)
  30. {
  31.     m_vCenter = D3DXVECTOR3((float)x,(float)y,0.0f);
  32.     Reset();
  33. }
  34.  
  35. GXArcBall::GXArcBall(D3DXVECTOR3 ¢er)
  36. {
  37.     m_vCenter = center;
  38.     Reset();
  39. }
  40.  
  41. void GXArcBall::Reset()
  42. {
  43.     D3DXQuaternionIdentity(&m_qDown);
  44.     D3DXQuaternionIdentity(&m_qNow);
  45.     m_bDrag = false;
  46. }
  47.  
  48. void GXArcBall::SetWindow(int iWidth, int iHeight, float fRadius)
  49. {
  50.     // set win info
  51.     m_iWidth = iWidth; 
  52.     m_iHeight = iHeight; 
  53.     m_fRadius = fRadius; 
  54.  
  55.     // set center after this
  56.     m_vCenter = D3DXVECTOR3(iWidth/2.0f,iHeight/2.0f,0.0f);
  57. }
  58.  
  59. void GXArcBall::BeginDrag(const int& x, const int& y)
  60. {
  61.     m_bDrag = true;
  62.     m_vDown = ScreenToVector(x,y);
  63. }
  64.  
  65. void GXArcBall::EndDrag()
  66. {
  67.     m_bDrag = false;
  68.     m_qDown = m_qNow;
  69. }
  70.  
  71. void GXArcBall::Mouse(const int& x, const int& y)
  72. {
  73.     if (m_bDrag) { // ignore it if you aren't dragging
  74.         m_vCur = ScreenToVector(x,y);
  75.         Update(); // always build qNow_...
  76.     }
  77. }
  78.  
  79. void GXArcBall::GetMat(D3DXMATRIX *pmat)
  80. {
  81.     D3DXQUATERNION qConj;
  82.     D3DXMatrixRotationQuaternion(pmat, D3DXQuaternionConjugate(&qConj, &m_qNow));
  83. }
  84.  
  85. D3DXVECTOR3 GXArcBall::ScreenToVector(const int& px, const int& py)
  86. {
  87.     float x,y,z;
  88.  
  89.     DWORD dwScreenDiameter = min(m_iWidth, m_iHeight);
  90.  
  91.     x = (px - m_vCenter.x) / (dwScreenDiameter * m_fRadius * 0.5f); // scales to screen...
  92. #if 1
  93.     y = (m_vCenter.y - py) / (dwScreenDiameter * m_fRadius * 0.5f); // invert Y coordinate...
  94. #else
  95.     y = (py - m_vCenter.y) / (dwScreenDiameter * m_fRadius * 0.5f); // invert Y coordinate...
  96. #endif
  97.  
  98.     x = -x;
  99.     y = -y;
  100.  
  101.     float mag = x*x + y*y;
  102.  
  103.     if (mag > 1.0) {
  104.         float scale = 1.0f/sqrtf(mag);
  105.         x *= scale;
  106.         y *= scale;
  107.         z = 0.0;
  108.     } else {
  109.         z = sqrtf((1.0f-mag));
  110.     }
  111.  
  112.     return D3DXVECTOR3(x,y,z);
  113. }
  114.  
  115. void GXArcBall::Update()
  116. {
  117.     if (m_bDrag) { // recompute m_qNow
  118. #if 0
  119.         m_qNow = QuatFromBallPoints(m_vDown, m_vCur) * m_qDown;
  120. #else
  121.         m_qNow = m_qDown * QuatFromBallPoints(m_vDown, m_vCur);
  122. #endif
  123.     }
  124. }
  125.  
  126. D3DXQUATERNION QuatFromBallPoints(const D3DXVECTOR3 &vFrom, const D3DXVECTOR3 &vTo)
  127. {
  128.     D3DXVECTOR3 vPart;
  129.     float     dotPart = D3DXVec3Dot(&vFrom, &vTo);
  130.  
  131.     D3DXVec3Cross(&vPart, &vFrom, &vTo);
  132.  
  133.     return D3DXQUATERNION(vPart.x, vPart.y, vPart.z, dotPart);
  134. }
  135.