⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arcball.h

📁 VC++ DEMO, used for the beginners and the amour
💻 H
字号:
#ifdef CGE_HEADER_H
#ifndef CGE_ARCBALL_H
#define CGE_ARCBALL_H

namespace CGE
{
	namespace MATRIX
	{
		enum
		{
			MOUSEKEY_NONE = 0x00,
				MOUSEKEY_LBUTTON = 0x01,
				MOUSEKEY_RBUTTON = 0x02,
				MOUSEKEY_SHIFT   = 0x04,
				MOUSEKEY_CONTROL = 0x08,
				MOUSEKEY_MBUTTON = 0x10,
		};
		typedef class ARCBALL  
		{
			public:
				ARCBALL();
				virtual ~ARCBALL();
				D3DXQUATERNION* QuaternionAxisToAxis( D3DXQUATERNION *pOut, const D3DXVECTOR3 *pvFrom, const D3DXVECTOR3 *pvTo);
				D3DXQUATERNION* QuaternionUnitAxisToUnitAxis2( D3DXQUATERNION *pOut, const D3DXVECTOR3 *pvFrom, const D3DXVECTOR3 *pvTo);
				VOID HandleMouseKeyDown(UINT nFlags,LPARAM lParam);
				D3DXVECTOR3 ScreenToVector( LONG sx,LONG sy);
				VOID SetArcBall(LONG w,LONG h,FLOAT fRadius = 1.0f);
				BOOL HandleMouseMove(UINT nFlags ,LPARAM lParam);
				D3DXMATRIX MatrixArcBall();
				LONG            m_Width;  
				LONG            m_Height;
				FLOAT           m_fRadius; 
				FLOAT           m_fRadiusTranslation; 	
				D3DXQUATERNION	m_qDown; 
				D3DXQUATERNION	m_qNow; 
				D3DXMATRIX		m_matRotation;
				D3DXMATRIX		m_matRotationDelta;
				D3DXMATRIX		m_matTranslation; 
				D3DXMATRIX		m_matTranslationDelta;
				BOOL			m_bDrag;
				D3DXVECTOR3     s_vDown; 
				LONG CurMouseX,CurMouseY;
		}*LPARCBALL;

		CGE_INLINE D3DXQUATERNION*  
			ARCBALL::QuaternionAxisToAxis( D3DXQUATERNION *pOut, const D3DXVECTOR3 *pvFrom, const D3DXVECTOR3 *pvTo)
		{
			D3DXVECTOR3 vA, vB;
			D3DXVec3Normalize(&vA, pvFrom);
			D3DXVec3Normalize(&vB, pvTo);
			D3DXVECTOR3 vHalf(vA + vB);
			D3DXVec3Normalize(&vHalf, &vHalf);
			return QuaternionUnitAxisToUnitAxis2(pOut, &vA, &vHalf);
		}
		
		CGE_INLINE D3DXQUATERNION*
			ARCBALL::QuaternionUnitAxisToUnitAxis2( D3DXQUATERNION *pOut, const D3DXVECTOR3 *pvFrom, const D3DXVECTOR3 *pvTo)
		{
			D3DXVECTOR3 vAxis;
			D3DXVec3Cross(&vAxis, pvFrom, pvTo);    // proportional to sin(theta)
			pOut->x = vAxis.x;
			pOut->y = vAxis.y;
			pOut->z = vAxis.z;
			pOut->w = D3DXVec3Dot( pvFrom, pvTo );
			return pOut;
		}
		
		CGE_INLINE VOID ARCBALL::HandleMouseKeyDown(UINT nFlags, LPARAM lParam)
		{
			INT MouseX = LOWORD(lParam);
			INT MouseY = HIWORD(lParam);
			if ((nFlags & MOUSEKEY_LBUTTON) == MOUSEKEY_LBUTTON)
			{
				s_vDown = ScreenToVector(MouseX,MouseY);
				m_qDown = m_qNow;
				CurMouseX = MouseX;
				CurMouseY = MouseY;
				m_bDrag = TRUE;
			}
		}
		
		CGE_INLINE ARCBALL::ARCBALL()
		{
			D3DXQuaternionIdentity( &m_qDown );
			D3DXQuaternionIdentity( &m_qNow );
			D3DXMatrixIdentity( &m_matRotation );
			D3DXMatrixIdentity( &m_matRotationDelta );
			D3DXMatrixIdentity( &m_matTranslation );
			D3DXMatrixIdentity( &m_matTranslationDelta );
			m_bDrag = FALSE;
			m_fRadiusTranslation = 5.0f;
		}
		
		CGE_INLINE ARCBALL::~ARCBALL()
		{
			
		}
		
		CGE_INLINE VOID ARCBALL::SetArcBall(LONG w, LONG h, FLOAT fRadius)
		{
			// Set ArcBall info
			m_Width  = w;
			m_Height = h;
			m_fRadius = fRadius;
		}
		
		CGE_INLINE D3DXVECTOR3 ARCBALL::ScreenToVector(LONG sx, LONG sy)
		{
			// Scale to screen
			float x   = -(sx - m_Width/2)  / (m_fRadius*m_Width/2);
			float y   =  (sy - m_Height/2) / (m_fRadius*m_Height/2);
			
			float z   = 0.0f;
			float mag = x*x + y*y;
			
			if( mag > 1.0f )
			{
				FLOAT scale = 1.0f/sqrtf(mag);
				x *= scale;
				y *= scale;
			}
			else
				z = sqrtf( 1.0f - mag );
			return D3DXVECTOR3( x, y, z );
		}
		
		CGE_INLINE BOOL ARCBALL::HandleMouseMove(UINT nFlags, LPARAM lParam)
		{	
			INT MouseX = LOWORD(lParam);
			INT MouseY = HIWORD(lParam);
			
			if ((nFlags & MOUSEKEY_LBUTTON) == MOUSEKEY_LBUTTON && (nFlags & MOUSEKEY_SHIFT) == MOUSEKEY_SHIFT)
			{
				FLOAT fDeltaX = ( CurMouseX-MouseX ) * m_fRadiusTranslation / m_Width;
				FLOAT fDeltaY = ( CurMouseY-MouseY ) * m_fRadiusTranslation / m_Height;
				D3DXMatrixTranslation( &m_matTranslationDelta, -2*fDeltaX, 2*fDeltaY, 0.0f );
				D3DXMatrixMultiply( &m_matTranslation, &m_matTranslation, &m_matTranslationDelta );
				CurMouseX = MouseX;
				CurMouseY = MouseY;
				return TRUE;
			}
			else if ((nFlags & MOUSEKEY_LBUTTON) == MOUSEKEY_LBUTTON && (nFlags & MOUSEKEY_SHIFT) != MOUSEKEY_SHIFT)
			{
				if( m_bDrag )
				{
					// recompute m_qNow
					D3DXVECTOR3 vCur = ScreenToVector( MouseX, MouseY );
					D3DXQUATERNION qAxisToAxis;
					QuaternionAxisToAxis(&qAxisToAxis, &s_vDown, &vCur);
					m_qNow = m_qDown;
					m_qNow *= qAxisToAxis;
					D3DXMatrixRotationQuaternion(&m_matRotationDelta, &qAxisToAxis);
				}
				else
				{
					D3DXMatrixIdentity(&m_matRotationDelta);
				}
				D3DXMatrixRotationQuaternion(&m_matRotation, &m_qNow);
				m_bDrag = TRUE;
				return TRUE;
			}	
			return FALSE;
		}
	}
}
#endif
#endif //

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -