//#pragma once #ifndef GTARCBALL_H_ #define GTARCBALL_H_ /*////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2000 Microsoft Corporation. All Rights Reserved. // // Description: // This include file contains a simple version of Shoemake's arcball code // from GGems IV. //////////////////////////////////////////////////////////////////////////////*/ //#include #include class GTArcBall { public: GTArcBall(); GTArcBall(int x, int y); GTArcBall(D3DXVECTOR3 center); void Reset(); // m_qNow set to identity void SetWindow(int w, int h, float r=0.9); // ball info - sets center void BeginDrag(int x, int y); // start dragging void Mouse(int x, int y); // right from windows... void EndDrag(); // button up void GetMatrix(D3DXMATRIX *pmat); // gets current rotation matrix void GetQuaternion(D3DXQUATERNION *pq) { *pq = m_qNow; } void SetQuaternion(D3DXQUATERNION *pq) { m_qNow = *pq; if (m_bDrag) m_qDown = m_qNow; } void Update(); protected: D3DXVECTOR3 ScreenToVector(int x, int y); // screen point to normalized point on the sphere D3DXVECTOR3 m_pCenter; // center of arcball - on screen D3DXVECTOR3 m_vDown; // button down quaternion D3DXVECTOR3 m_vCur; // current quaternion D3DXQUATERNION m_qDown; // quaternion before button down D3DXQUATERNION m_qNow; // composite quaternion for current drag int m_iWidth,m_iHeight; // window dimensions float m_fRadius; // ball radius - in screen space bool m_bDrag; // true if during drag }; // add helper function - probably should be in quaternion class // Axis to axis quaternion double angle (no normalization) // Takes two points on unit sphere an angle THETA apart, returns // quaternion that represents a rotation around cross product by 2*THETA. inline D3DXQUATERNION* WINAPI D3DXQuaternionUnitAxisToUnitAxis2 ( 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; } // Axis to axis quaternion // Takes two points on unit sphere an angle THETA apart, returns // quaternion that represents a rotation around cross product by theta. inline D3DXQUATERNION* WINAPI D3DXQuaternionAxisToAxis ( 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 D3DXQuaternionUnitAxisToUnitAxis2(pOut, &vA, &vHalf); } #endif