📄 arcball.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 + -