d3dutil.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:43k
- //-----------------------------------------------------------------------------
- // File: D3DUtil.cpp
- //
- // Desc: Shortcut macros and functions for using DX objects
- //
- // Copyright (c) Microsoft Corporation. All rights reserved
- //-----------------------------------------------------------------------------
- #include "dxstdafx.h"
- #ifndef WM_MOUSEWHEEL
- #define WM_MOUSEWHEEL 0x020A
- #endif
- //-----------------------------------------------------------------------------
- // Name: D3DUtil_GetCubeMapViewMatrix()
- // Desc: Returns a view matrix for rendering to a face of a cubemap.
- //-----------------------------------------------------------------------------
- D3DXMATRIX D3DUtil_GetCubeMapViewMatrix( DWORD dwFace )
- {
- D3DXVECTOR3 vEyePt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
- D3DXVECTOR3 vLookDir;
- D3DXVECTOR3 vUpDir;
- switch( dwFace )
- {
- case D3DCUBEMAP_FACE_POSITIVE_X:
- vLookDir = D3DXVECTOR3( 1.0f, 0.0f, 0.0f );
- vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
- break;
- case D3DCUBEMAP_FACE_NEGATIVE_X:
- vLookDir = D3DXVECTOR3(-1.0f, 0.0f, 0.0f );
- vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
- break;
- case D3DCUBEMAP_FACE_POSITIVE_Y:
- vLookDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
- vUpDir = D3DXVECTOR3( 0.0f, 0.0f,-1.0f );
- break;
- case D3DCUBEMAP_FACE_NEGATIVE_Y:
- vLookDir = D3DXVECTOR3( 0.0f,-1.0f, 0.0f );
- vUpDir = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );
- break;
- case D3DCUBEMAP_FACE_POSITIVE_Z:
- vLookDir = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );
- vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
- break;
- case D3DCUBEMAP_FACE_NEGATIVE_Z:
- vLookDir = D3DXVECTOR3( 0.0f, 0.0f,-1.0f );
- vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
- break;
- }
- // Set the view transform for this cubemap surface
- D3DXMATRIXA16 mView;
- D3DXMatrixLookAtLH( &mView, &vEyePt, &vLookDir, &vUpDir );
- return mView;
- }
- //-----------------------------------------------------------------------------
- // Name: D3DUtil_GetRotationFromCursor()
- // Desc: Returns a quaternion for the rotation implied by the window's cursor
- // position.
- //-----------------------------------------------------------------------------
- D3DXQUATERNION D3DUtil_GetRotationFromCursor( HWND hWnd,
- FLOAT fTrackBallRadius )
- {
- POINT pt;
- RECT rc;
- GetCursorPos( &pt );
- GetClientRect( hWnd, &rc );
- ScreenToClient( hWnd, &pt );
- FLOAT sx = ( ( ( 2.0f * pt.x ) / (rc.right-rc.left) ) - 1 );
- FLOAT sy = ( ( ( 2.0f * pt.y ) / (rc.bottom-rc.top) ) - 1 );
- FLOAT sz;
- if( sx == 0.0f && sy == 0.0f )
- return D3DXQUATERNION( 0.0f, 0.0f, 0.0f, 1.0f );
- FLOAT d2 = sqrtf( sx*sx + sy*sy );
- if( d2 < fTrackBallRadius * 0.70710678118654752440 ) // Inside sphere
- sz = sqrtf( fTrackBallRadius*fTrackBallRadius - d2*d2 );
- else // On hyperbola
- sz = (fTrackBallRadius*fTrackBallRadius) / (2.0f*d2);
- // Get two points on trackball's sphere
- D3DXVECTOR3 p1( sx, sy, sz );
- D3DXVECTOR3 p2( 0.0f, 0.0f, fTrackBallRadius );
- // Get axis of rotation, which is cross product of p1 and p2
- D3DXVECTOR3 vAxis;
- D3DXVec3Cross( &vAxis, &p1, &p2);
- // Calculate angle for the rotation about that axis
- D3DXVECTOR3 vecDiff = p2-p1;
- FLOAT t = D3DXVec3Length( &vecDiff ) / ( 2.0f*fTrackBallRadius );
- if( t > +1.0f) t = +1.0f;
- if( t < -1.0f) t = -1.0f;
- FLOAT fAngle = 2.0f * asinf( t );
- // Convert axis to quaternion
- D3DXQUATERNION quat;
- D3DXQuaternionRotationAxis( &quat, &vAxis, fAngle );
- return quat;
- }
- //-----------------------------------------------------------------------------
- // Name: D3DUtil_SetDeviceCursor
- // Desc: Gives the D3D device a cursor with image and hotspot from hCursor.
- //-----------------------------------------------------------------------------
- HRESULT D3DUtil_SetDeviceCursor( LPDIRECT3DDEVICE9 pd3dDevice, HCURSOR hCursor,
- BOOL bAddWatermark )
- {
- HRESULT hr = E_FAIL;
- ICONINFO iconinfo;
- BOOL bBWCursor;
- LPDIRECT3DSURFACE9 pCursorSurface = NULL;
- HDC hdcColor = NULL;
- HDC hdcMask = NULL;
- HDC hdcScreen = NULL;
- BITMAP bm;
- DWORD dwWidth;
- DWORD dwHeightSrc;
- DWORD dwHeightDest;
- COLORREF crColor;
- COLORREF crMask;
- UINT x;
- UINT y;
- BITMAPINFO bmi;
- COLORREF* pcrArrayColor = NULL;
- COLORREF* pcrArrayMask = NULL;
- DWORD* pBitmap;
- HGDIOBJ hgdiobjOld;
- ZeroMemory( &iconinfo, sizeof(iconinfo) );
- if( !GetIconInfo( hCursor, &iconinfo ) )
- goto End;
- if (0 == GetObject((HGDIOBJ)iconinfo.hbmMask, sizeof(BITMAP), (LPVOID)&bm))
- goto End;
- dwWidth = bm.bmWidth;
- dwHeightSrc = bm.bmHeight;
- if( iconinfo.hbmColor == NULL )
- {
- bBWCursor = TRUE;
- dwHeightDest = dwHeightSrc / 2;
- }
- else
- {
- bBWCursor = FALSE;
- dwHeightDest = dwHeightSrc;
- }
- // Create a surface for the fullscreen cursor
- if( FAILED( hr = pd3dDevice->CreateOffscreenPlainSurface( dwWidth, dwHeightDest,
- D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pCursorSurface, NULL ) ) )
- {
- goto End;
- }
- pcrArrayMask = new DWORD[dwWidth * dwHeightSrc];
- ZeroMemory(&bmi, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
- bmi.bmiHeader.biWidth = dwWidth;
- bmi.bmiHeader.biHeight = dwHeightSrc;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = BI_RGB;
- hdcScreen = GetDC( NULL );
- hdcMask = CreateCompatibleDC( hdcScreen );
- if( hdcMask == NULL )
- {
- hr = E_FAIL;
- goto End;
- }
- hgdiobjOld = SelectObject(hdcMask, iconinfo.hbmMask);
- GetDIBits(hdcMask, iconinfo.hbmMask, 0, dwHeightSrc,
- pcrArrayMask, &bmi, DIB_RGB_COLORS);
- SelectObject(hdcMask, hgdiobjOld);
- if (!bBWCursor)
- {
- pcrArrayColor = new DWORD[dwWidth * dwHeightDest];
- hdcColor = CreateCompatibleDC( hdcScreen );
- if( hdcColor == NULL )
- {
- hr = E_FAIL;
- goto End;
- }
- SelectObject(hdcColor, iconinfo.hbmColor);
- GetDIBits(hdcColor, iconinfo.hbmColor, 0, dwHeightDest,
- pcrArrayColor, &bmi, DIB_RGB_COLORS);
- }
- // Transfer cursor image into the surface
- D3DLOCKED_RECT lr;
- pCursorSurface->LockRect( &lr, NULL, 0 );
- pBitmap = (DWORD*)lr.pBits;
- for( y = 0; y < dwHeightDest; y++ )
- {
- for( x = 0; x < dwWidth; x++ )
- {
- if (bBWCursor)
- {
- crColor = pcrArrayMask[dwWidth*(dwHeightDest-1-y) + x];
- crMask = pcrArrayMask[dwWidth*(dwHeightSrc-1-y) + x];
- }
- else
- {
- crColor = pcrArrayColor[dwWidth*(dwHeightDest-1-y) + x];
- crMask = pcrArrayMask[dwWidth*(dwHeightDest-1-y) + x];
- }
- if (crMask == 0)
- pBitmap[dwWidth*y + x] = 0xff000000 | crColor;
- else
- pBitmap[dwWidth*y + x] = 0x00000000;
- // It may be helpful to make the D3D cursor look slightly
- // different from the Windows cursor so you can distinguish
- // between the two when developing/testing code. When
- // bAddWatermark is TRUE, the following code adds some
- // small grey "D3D" characters to the upper-left corner of
- // the D3D cursor image.
- if( bAddWatermark && x < 12 && y < 5 )
- {
- // 11.. 11.. 11.. .... CCC0
- // 1.1. ..1. 1.1. .... A2A0
- // 1.1. .1.. 1.1. .... A4A0
- // 1.1. ..1. 1.1. .... A2A0
- // 11.. 11.. 11.. .... CCC0
- const WORD wMask[5] = { 0xccc0, 0xa2a0, 0xa4a0, 0xa2a0, 0xccc0 };
- if( wMask[y] & (1 << (15 - x)) )
- {
- pBitmap[dwWidth*y + x] |= 0xff808080;
- }
- }
- }
- }
- pCursorSurface->UnlockRect();
- // Set the device cursor
- if( FAILED( hr = pd3dDevice->SetCursorProperties( iconinfo.xHotspot,
- iconinfo.yHotspot, pCursorSurface ) ) )
- {
- goto End;
- }
- hr = S_OK;
- End:
- if( iconinfo.hbmMask != NULL )
- DeleteObject( iconinfo.hbmMask );
- if( iconinfo.hbmColor != NULL )
- DeleteObject( iconinfo.hbmColor );
- if( hdcScreen != NULL )
- ReleaseDC( NULL, hdcScreen );
- if( hdcColor != NULL )
- DeleteDC( hdcColor );
- if( hdcMask != NULL )
- DeleteDC( hdcMask );
- SAFE_DELETE_ARRAY( pcrArrayColor );
- SAFE_DELETE_ARRAY( pcrArrayMask );
- SAFE_RELEASE( pCursorSurface );
- return hr;
- }
- //-----------------------------------------------------------------------------
- // Name: D3DFormatToString
- // Desc: Returns the string for the given D3DFORMAT.
- //-----------------------------------------------------------------------------
- LPCTSTR D3DUtil_D3DFormatToString( D3DFORMAT format, bool bWithPrefix )
- {
- TCHAR* pstr = NULL;
- switch( format )
- {
- case D3DFMT_UNKNOWN: pstr = TEXT("D3DFMT_UNKNOWN"); break;
- case D3DFMT_R8G8B8: pstr = TEXT("D3DFMT_R8G8B8"); break;
- case D3DFMT_A8R8G8B8: pstr = TEXT("D3DFMT_A8R8G8B8"); break;
- case D3DFMT_X8R8G8B8: pstr = TEXT("D3DFMT_X8R8G8B8"); break;
- case D3DFMT_R5G6B5: pstr = TEXT("D3DFMT_R5G6B5"); break;
- case D3DFMT_X1R5G5B5: pstr = TEXT("D3DFMT_X1R5G5B5"); break;
- case D3DFMT_A1R5G5B5: pstr = TEXT("D3DFMT_A1R5G5B5"); break;
- case D3DFMT_A4R4G4B4: pstr = TEXT("D3DFMT_A4R4G4B4"); break;
- case D3DFMT_R3G3B2: pstr = TEXT("D3DFMT_R3G3B2"); break;
- case D3DFMT_A8: pstr = TEXT("D3DFMT_A8"); break;
- case D3DFMT_A8R3G3B2: pstr = TEXT("D3DFMT_A8R3G3B2"); break;
- case D3DFMT_X4R4G4B4: pstr = TEXT("D3DFMT_X4R4G4B4"); break;
- case D3DFMT_A2B10G10R10: pstr = TEXT("D3DFMT_A2B10G10R10"); break;
- case D3DFMT_A8B8G8R8: pstr = TEXT("D3DFMT_A8B8G8R8"); break;
- case D3DFMT_X8B8G8R8: pstr = TEXT("D3DFMT_X8B8G8R8"); break;
- case D3DFMT_G16R16: pstr = TEXT("D3DFMT_G16R16"); break;
- case D3DFMT_A2R10G10B10: pstr = TEXT("D3DFMT_A2R10G10B10"); break;
- case D3DFMT_A16B16G16R16: pstr = TEXT("D3DFMT_A16B16G16R16"); break;
- case D3DFMT_A8P8: pstr = TEXT("D3DFMT_A8P8"); break;
- case D3DFMT_P8: pstr = TEXT("D3DFMT_P8"); break;
- case D3DFMT_L8: pstr = TEXT("D3DFMT_L8"); break;
- case D3DFMT_A8L8: pstr = TEXT("D3DFMT_A8L8"); break;
- case D3DFMT_A4L4: pstr = TEXT("D3DFMT_A4L4"); break;
- case D3DFMT_V8U8: pstr = TEXT("D3DFMT_V8U8"); break;
- case D3DFMT_L6V5U5: pstr = TEXT("D3DFMT_L6V5U5"); break;
- case D3DFMT_X8L8V8U8: pstr = TEXT("D3DFMT_X8L8V8U8"); break;
- case D3DFMT_Q8W8V8U8: pstr = TEXT("D3DFMT_Q8W8V8U8"); break;
- case D3DFMT_V16U16: pstr = TEXT("D3DFMT_V16U16"); break;
- case D3DFMT_A2W10V10U10: pstr = TEXT("D3DFMT_A2W10V10U10"); break;
- case D3DFMT_UYVY: pstr = TEXT("D3DFMT_UYVY"); break;
- case D3DFMT_YUY2: pstr = TEXT("D3DFMT_YUY2"); break;
- case D3DFMT_DXT1: pstr = TEXT("D3DFMT_DXT1"); break;
- case D3DFMT_DXT2: pstr = TEXT("D3DFMT_DXT2"); break;
- case D3DFMT_DXT3: pstr = TEXT("D3DFMT_DXT3"); break;
- case D3DFMT_DXT4: pstr = TEXT("D3DFMT_DXT4"); break;
- case D3DFMT_DXT5: pstr = TEXT("D3DFMT_DXT5"); break;
- case D3DFMT_D16_LOCKABLE: pstr = TEXT("D3DFMT_D16_LOCKABLE"); break;
- case D3DFMT_D32: pstr = TEXT("D3DFMT_D32"); break;
- case D3DFMT_D15S1: pstr = TEXT("D3DFMT_D15S1"); break;
- case D3DFMT_D24S8: pstr = TEXT("D3DFMT_D24S8"); break;
- case D3DFMT_D24X8: pstr = TEXT("D3DFMT_D24X8"); break;
- case D3DFMT_D24X4S4: pstr = TEXT("D3DFMT_D24X4S4"); break;
- case D3DFMT_D16: pstr = TEXT("D3DFMT_D16"); break;
- case D3DFMT_L16: pstr = TEXT("D3DFMT_L16"); break;
- case D3DFMT_VERTEXDATA: pstr = TEXT("D3DFMT_VERTEXDATA"); break;
- case D3DFMT_INDEX16: pstr = TEXT("D3DFMT_INDEX16"); break;
- case D3DFMT_INDEX32: pstr = TEXT("D3DFMT_INDEX32"); break;
- case D3DFMT_Q16W16V16U16: pstr = TEXT("D3DFMT_Q16W16V16U16"); break;
- case D3DFMT_MULTI2_ARGB8: pstr = TEXT("D3DFMT_MULTI2_ARGB8"); break;
- case D3DFMT_R16F: pstr = TEXT("D3DFMT_R16F"); break;
- case D3DFMT_G16R16F: pstr = TEXT("D3DFMT_G16R16F"); break;
- case D3DFMT_A16B16G16R16F: pstr = TEXT("D3DFMT_A16B16G16R16F"); break;
- case D3DFMT_R32F: pstr = TEXT("D3DFMT_R32F"); break;
- case D3DFMT_G32R32F: pstr = TEXT("D3DFMT_G32R32F"); break;
- case D3DFMT_A32B32G32R32F: pstr = TEXT("D3DFMT_A32B32G32R32F"); break;
- case D3DFMT_CxV8U8: pstr = TEXT("D3DFMT_CxV8U8"); break;
- default: pstr = TEXT("Unknown format"); break;
- }
- if( bWithPrefix || _tcsstr( pstr, TEXT("D3DFMT_") )== NULL )
- return pstr;
- else
- return pstr + lstrlen( TEXT("D3DFMT_") );
- }
- //-----------------------------------------------------------------------------
- // Name: D3DUtil_QuaternionUnitAxisToUnitAxis2
- // Desc: 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 D3DUtil_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;
- }
- //-----------------------------------------------------------------------------
- // Name: D3DUtil_QuaternionAxisToAxis
- // Desc: 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 D3DUtil_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 D3DUtil_QuaternionUnitAxisToUnitAxis2(pOut, &vA, &vHalf);
- }
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- CD3DArcBall::CD3DArcBall()
- {
- Reset();
- m_vDownPt = D3DXVECTOR3(0,0,0);
- m_vCurrentPt = D3DXVECTOR3(0,0,0);
- RECT rc;
- GetClientRect( GetForegroundWindow(), &rc );
- SetWindow( rc.right, rc.bottom );
- }
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- void CD3DArcBall::Reset()
- {
- D3DXQuaternionIdentity( &m_qDown );
- D3DXQuaternionIdentity( &m_qNow );
- D3DXMatrixIdentity( &m_mRotation );
- D3DXMatrixIdentity( &m_mTranslation );
- D3DXMatrixIdentity( &m_mTranslationDelta );
- m_bDrag = FALSE;
- m_fRadiusTranslation = 1.0f;
- m_fRadius = 1.0f;
- }
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- D3DXVECTOR3 CD3DArcBall::ScreenToVector( float fScreenPtX, float fScreenPtY )
- {
- // Scale to screen
- FLOAT x = -(fScreenPtX - m_nWidth/2) / (m_fRadius*m_nWidth/2);
- FLOAT y = (fScreenPtY - m_nHeight/2) / (m_fRadius*m_nHeight/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 vector
- return D3DXVECTOR3( x, y, z );
- }
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- D3DXQUATERNION CD3DArcBall::QuatFromBallPoints(const D3DXVECTOR3 &vFrom, const D3DXVECTOR3 &vTo)
- {
- D3DXVECTOR3 vPart;
- float fDot = D3DXVec3Dot(&vFrom, &vTo);
- D3DXVec3Cross(&vPart, &vFrom, &vTo);
- return D3DXQUATERNION(vPart.x, vPart.y, vPart.z, fDot);
- }
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- void CD3DArcBall::OnBegin( int nX, int nY )
- {
- m_bDrag = true;
- m_vDownPt = ScreenToVector( (float)nX, (float)nY );
- }
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- void CD3DArcBall::OnMove( int nX, int nY )
- {
- if (m_bDrag)
- {
- m_vCurrentPt = ScreenToVector( (float)nX, (float)nY );
- m_qNow = m_qDown * QuatFromBallPoints( m_vDownPt, m_vCurrentPt );
- }
- }
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- void CD3DArcBall::OnEnd()
- {
- m_bDrag = false;
- m_qDown = m_qNow;
- }
- //-----------------------------------------------------------------------------
- // Name: HandleMessages
- // Desc:
- //-----------------------------------------------------------------------------
- LRESULT CD3DArcBall::HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- UNREFERENCED_PARAMETER( hWnd );
- // Current mouse position
- int iMouseX = GET_X_LPARAM(lParam);
- int iMouseY = GET_Y_LPARAM(lParam);
- switch( uMsg )
- {
- case WM_LBUTTONDOWN:
- OnBegin( iMouseX, iMouseY );
- return TRUE;
- case WM_LBUTTONUP:
- OnEnd();
- return TRUE;
- case WM_RBUTTONDOWN:
- case WM_MBUTTONDOWN:
- // Store off the position of the cursor when the button is pressed
- m_ptLastMouse.x = iMouseX;
- m_ptLastMouse.y = iMouseY;
- return TRUE;
- case WM_MOUSEMOVE:
- if( MK_LBUTTON&wParam )
- {
- OnMove( iMouseX, iMouseY );
- }
- else if( (MK_RBUTTON&wParam) || (MK_MBUTTON&wParam) )
- {
- // Normalize based on size of window and bounding sphere radius
- FLOAT fDeltaX = ( m_ptLastMouse.x-iMouseX ) * m_fRadiusTranslation / m_nWidth;
- FLOAT fDeltaY = ( m_ptLastMouse.y-iMouseY ) * m_fRadiusTranslation / m_nHeight;
- if( wParam & MK_RBUTTON )
- {
- D3DXMatrixTranslation( &m_mTranslationDelta, -2*fDeltaX, 2*fDeltaY, 0.0f );
- D3DXMatrixMultiply( &m_mTranslation, &m_mTranslation, &m_mTranslationDelta );
- }
- else // wParam & MK_MBUTTON
- {
- D3DXMatrixTranslation( &m_mTranslationDelta, 0.0f, 0.0f, 5*fDeltaY );
- D3DXMatrixMultiply( &m_mTranslation, &m_mTranslation, &m_mTranslationDelta );
- }
- // Store mouse coordinate
- m_ptLastMouse.x = iMouseX;
- m_ptLastMouse.y = iMouseY;
- }
- return TRUE;
- }
- return FALSE;
- }
- //-----------------------------------------------------------------------------
- // Name: CBaseCamera
- // Desc: Constructor
- //-----------------------------------------------------------------------------
- CBaseCamera::CBaseCamera()
- {
- ZeroMemory( m_aKeys, sizeof(BYTE)*CAM_MAX_KEYS );
- // Set attributes for the view matrix
- D3DXVECTOR3 vEyePt = D3DXVECTOR3(0.0f,0.0f,0.0f);
- D3DXVECTOR3 vLookatPt = D3DXVECTOR3(0.0f,0.0f,1.0f);
- // Setup the view matrix
- SetViewParams( &vEyePt, &vLookatPt );
- // Setup the projection matrix
- SetProjParams( D3DX_PI/4, 1.0f, 1.0f, 1000.0f );
- GetCursorPos( &m_ptLastMousePosition );
- m_bMouseLButtonDown = false;
- m_bMouseMButtonDown = false;
- m_bMouseRButtonDown = false;
- m_nCurrentButtonMask = 0;
- m_nMouseWheelDelta = 0;
- m_fCameraYawAngle = 0.0f;
- m_fCameraPitchAngle = 0.0f;
- m_vVelocity = D3DXVECTOR3(0,0,0);
- m_bMovementDrag = false;
- m_vVelocityDrag = D3DXVECTOR3(0,0,0);
- m_fDragTimer = 0.0f;
- m_fTotalDragTimeToZero = 0.25;
- m_vRotVelocity = D3DXVECTOR2(0,0);
- m_fRotationScaler = 0.01f;
- m_fMoveScaler = 5.0f;
- m_bInvertPitch = false;
- m_bEnableYAxisMovement = true;
- m_bEnablePositionMovement = true;
- m_vMouseDelta = D3DXVECTOR2(0,0);
- m_fFramesToSmoothMouseData = 2.0f;
- m_bClipToBoundary = false;
- m_vMinBoundary = D3DXVECTOR3(-1,-1,-1);
- m_vMaxBoundary = D3DXVECTOR3(1,1,1);
- m_bResetCursorAfterMove = false;
- }
- //-----------------------------------------------------------------------------
- // Name: SetViewParams
- // Desc: Client can call this to change the position and direction of camrea
- //-----------------------------------------------------------------------------
- VOID CBaseCamera::SetViewParams( D3DXVECTOR3* pvEyePt, D3DXVECTOR3* pvLookatPt )
- {
- if( NULL == pvEyePt || NULL == pvLookatPt )
- return;
- m_vDefaultEye = m_vEye = *pvEyePt;
- m_vDefaultLookAt = m_vLookAt = *pvLookatPt;
- // Calc the view matrix
- D3DXVECTOR3 vUp(0,1,0);
- D3DXMatrixLookAtLH( &m_mView, pvEyePt, pvLookatPt, &vUp );
- D3DXMATRIX mInvView;
- D3DXMatrixInverse( &mInvView, NULL, &m_mView );
- // The axis basis vectors and camera position are stored inside the
- // position matrix in the 4 rows of the camera's world matrix.
- // To figuire out the yaw/pitch of the camera, we just need the Z basis vector
- D3DXVECTOR3* pZBasis = (D3DXVECTOR3*) &mInvView._31;
- m_fCameraYawAngle = atan2f( pZBasis->x, pZBasis->z );
- float fLen = sqrtf(pZBasis->z*pZBasis->z + pZBasis->x*pZBasis->x);
- m_fCameraPitchAngle = -atan2f( pZBasis->y, fLen );
- }
- //-----------------------------------------------------------------------------
- // Name: SetProjParams
- // Desc: Calculates the projection matrix based on input params
- //-----------------------------------------------------------------------------
- VOID CBaseCamera::SetProjParams( FLOAT fFOV, FLOAT fAspect, FLOAT fNearPlane,
- FLOAT fFarPlane )
- {
- // Set attributes for the projection matrix
- m_fFOV = fFOV;
- m_fAspect = fAspect;
- m_fNearPlane = fNearPlane;
- m_fFarPlane = fFarPlane;
- D3DXMatrixPerspectiveFovLH( &m_mProj, fFOV, fAspect, fNearPlane, fFarPlane );
- }
- //-----------------------------------------------------------------------------
- // Name: HandleMessages
- // Desc: Call this from your message proc so this class can handle window messages
- //-----------------------------------------------------------------------------
- LRESULT CBaseCamera::HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- UNREFERENCED_PARAMETER( hWnd );
- UNREFERENCED_PARAMETER( lParam );
- switch( uMsg )
- {
- case WM_KEYDOWN:
- {
- // Map this key to a D3DUtil_CameraKeys enum and update the
- // state of m_aKeys[] by adding the KEY_WAS_DOWN_MASK|KEY_IS_DOWN_MASK mask
- // only if the key is not down
- D3DUtil_CameraKeys mappedKey = MapKey( (UINT)wParam );
- if( mappedKey != CAM_UNKNOWN )
- {
- if( FALSE == IsKeyDown(m_aKeys[mappedKey]) )
- m_aKeys[ mappedKey ] = KEY_WAS_DOWN_MASK | KEY_IS_DOWN_MASK;
- }
- break;
- }
- case WM_KEYUP:
- {
- // Map this key to a D3DUtil_CameraKeys enum and update the
- // state of m_aKeys[] by removing the KEY_IS_DOWN_MASK mask.
- D3DUtil_CameraKeys mappedKey = MapKey( (UINT)wParam );
- if( mappedKey != CAM_UNKNOWN )
- m_aKeys[ mappedKey ] &= ~KEY_IS_DOWN_MASK;
- break;
- }
- case WM_RBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_LBUTTONDOWN:
- {
- // Update member var state
- if( uMsg == WM_LBUTTONDOWN ) { m_bMouseLButtonDown = true; m_nCurrentButtonMask |= MOUSE_LEFT_BUTTON; }
- if( uMsg == WM_MBUTTONDOWN ) { m_bMouseMButtonDown = true; m_nCurrentButtonMask |= MOUSE_MIDDLE_BUTTON; }
- if( uMsg == WM_RBUTTONDOWN ) { m_bMouseRButtonDown = true; m_nCurrentButtonMask |= MOUSE_RIGHT_BUTTON; }
- // Capture the mouse, so if the mouse button is
- // released outside the window, we'll get the WM_LBUTTONUP message
- SetCapture(hWnd);
- GetCursorPos( &m_ptLastMousePosition );
- return TRUE;
- }
- case WM_RBUTTONUP:
- case WM_MBUTTONUP:
- case WM_LBUTTONUP:
- {
- // Update member var state
- if( uMsg == WM_LBUTTONUP ) { m_bMouseLButtonDown = false; m_nCurrentButtonMask &= ~MOUSE_LEFT_BUTTON; }
- if( uMsg == WM_MBUTTONUP ) { m_bMouseMButtonDown = false; m_nCurrentButtonMask &= ~MOUSE_MIDDLE_BUTTON; }
- if( uMsg == WM_RBUTTONUP ) { m_bMouseRButtonDown = false; m_nCurrentButtonMask &= ~MOUSE_RIGHT_BUTTON; }
- // Release the capture if no mouse buttons down
- if( !m_bMouseLButtonDown &&
- !m_bMouseRButtonDown &&
- !m_bMouseMButtonDown )
- {
- ReleaseCapture();
- }
- break;
- }
- case WM_MOUSEWHEEL:
- // Update member var state
- m_nMouseWheelDelta = (short)HIWORD(wParam) / 120;
- break;
- }
- return FALSE;
- }
- //-----------------------------------------------------------------------------
- // Name: UpdateMouseDelta
- // Desc: Figure out the mouse delta based on mouse movement
- //-----------------------------------------------------------------------------
- void CBaseCamera::UpdateMouseDelta( float fElapsedTime )
- {
- UNREFERENCED_PARAMETER( fElapsedTime );
- POINT ptCurMouseDelta;
- POINT ptCurMousePos;
-
- // Get current position of mouse
- GetCursorPos( &ptCurMousePos );
- // Calc how far it's moved since last frame
- ptCurMouseDelta.x = ptCurMousePos.x - m_ptLastMousePosition.x;
- ptCurMouseDelta.y = ptCurMousePos.y - m_ptLastMousePosition.y;
- // Record current position for next time
- m_ptLastMousePosition = ptCurMousePos;
- if( m_bResetCursorAfterMove )
- {
- // Set position of camera to center of desktop,
- // so it always has room to move. This is very useful
- // if the cursor is hidden. If this isn't done and cursor is hidden,
- // then invisible cursor will hit the edge of the screen
- // and the user can't tell what happened
- POINT ptCenter;
- RECT rcDesktop;
- GetWindowRect( GetDesktopWindow(), &rcDesktop );
- ptCenter.x = (rcDesktop.right - rcDesktop.left) / 2;
- ptCenter.y = (rcDesktop.bottom - rcDesktop.top) / 2;
- SetCursorPos( ptCenter.x, ptCenter.y );
- m_ptLastMousePosition = ptCenter;
- }
- // Smooth the relative mouse data over a few frames so it isn't
- // jerky when moving slowly at low frame rates.
- float fPercentOfNew = 1.0f / m_fFramesToSmoothMouseData;
- float fPercentOfOld = 1.0f - fPercentOfNew;
- m_vMouseDelta.x = m_vMouseDelta.x*fPercentOfOld + ptCurMouseDelta.x*fPercentOfNew;
- m_vMouseDelta.y = m_vMouseDelta.y*fPercentOfOld + ptCurMouseDelta.y*fPercentOfNew;
- m_vRotVelocity = m_vMouseDelta * m_fRotationScaler;
- }
- //-----------------------------------------------------------------------------
- // Name: UpdateVelocity
- // Desc: Figure out the velocity based on keyboard input & drag if any
- //-----------------------------------------------------------------------------
- void CBaseCamera::UpdateVelocity( float fElapsedTime )
- {
- D3DXMATRIX mRotDelta;
- D3DXVECTOR3 vAccel = D3DXVECTOR3(0,0,0);
- if( m_bEnablePositionMovement )
- {
- // Update acceleration vector based on keyboard state
- if( IsKeyDown(m_aKeys[CAM_MOVE_FORWARD]) )
- vAccel.z += 1.0f;
- if( IsKeyDown(m_aKeys[CAM_MOVE_BACKWARD]) )
- vAccel.z -= 1.0f;
- if( m_bEnableYAxisMovement )
- {
- if( IsKeyDown(m_aKeys[CAM_MOVE_UP]) )
- vAccel.y += 1.0f;
- if( IsKeyDown(m_aKeys[CAM_MOVE_DOWN]) )
- vAccel.y -= 1.0f;
- }
- if( IsKeyDown(m_aKeys[CAM_STRAFE_RIGHT]) )
- vAccel.x += 1.0f;
- if( IsKeyDown(m_aKeys[CAM_STRAFE_LEFT]) )
- vAccel.x -= 1.0f;
- }
- // Normalize vector so if moving 2 dirs (left & forward),
- // the camera doesn't move faster than if moving in 1 dir
- D3DXVec3Normalize( &vAccel, &vAccel );
- // Scale the acceleration vector
- vAccel *= m_fMoveScaler;
- if( m_bMovementDrag )
- {
- // Is there any acceleration this frame?
- if( D3DXVec3LengthSq( &vAccel ) > 0 )
- {
- // If so, then this means the user has pressed a movement key
- // so change the velocity immediately to acceleration
- // upon keyboard input. This isn't normal physics
- // but it will give a quick response to keyboard input
- m_vVelocity = vAccel;
- m_fDragTimer = m_fTotalDragTimeToZero;
- m_vVelocityDrag = vAccel / m_fDragTimer;
- }
- else
- {
- // If no key being pressed, then slowly decrease velocity to 0
- if( m_fDragTimer > 0 )
- {
- // Drag until timer is <= 0
- m_vVelocity -= m_vVelocityDrag * fElapsedTime;
- m_fDragTimer -= fElapsedTime;
- }
- else
- {
- // Zero velocity
- m_vVelocity = D3DXVECTOR3(0,0,0);
- }
- }
- }
- else
- {
- // No drag, so immediatly change the velocity
- m_vVelocity = vAccel;
- }
- }
- //-----------------------------------------------------------------------------
- // Name: ConstrainToBoundary
- // Desc: Clamps pV to lie inside m_vMinBoundary & m_vMaxBoundary
- //-----------------------------------------------------------------------------
- void CBaseCamera::ConstrainToBoundary( D3DXVECTOR3* pV )
- {
- // Constrain vector to a bounding box
- pV->x = max(pV->x, m_vMinBoundary.x);
- pV->y = max(pV->y, m_vMinBoundary.y);
- pV->z = max(pV->z, m_vMinBoundary.z);
- pV->x = min(pV->x, m_vMaxBoundary.x);
- pV->y = min(pV->y, m_vMaxBoundary.y);
- pV->z = min(pV->z, m_vMaxBoundary.z);
- }
- //-----------------------------------------------------------------------------
- // Name: MapKey
- // Desc: Maps a windows virtual key to an enum
- //-----------------------------------------------------------------------------
- D3DUtil_CameraKeys CBaseCamera::MapKey( UINT nKey )
- {
- // This could be upgraded to a method that's user-definable but for
- // simplisity, we'll use a hardcoded mapping.
- switch( nKey )
- {
- case VK_LEFT: return CAM_STRAFE_LEFT;
- case VK_RIGHT: return CAM_STRAFE_RIGHT;
- case VK_UP: return CAM_MOVE_FORWARD;
- case VK_DOWN: return CAM_MOVE_BACKWARD;
- case VK_PRIOR: return CAM_MOVE_UP; // pgup
- case VK_NEXT: return CAM_MOVE_DOWN; // pgdn
- case 'A': return CAM_STRAFE_LEFT;
- case 'D': return CAM_STRAFE_RIGHT;
- case 'W': return CAM_MOVE_FORWARD;
- case 'S': return CAM_MOVE_BACKWARD;
- case 'Q': return CAM_MOVE_DOWN;
- case 'E': return CAM_MOVE_UP;
- case VK_NUMPAD4: return CAM_STRAFE_LEFT;
- case VK_NUMPAD6: return CAM_STRAFE_RIGHT;
- case VK_NUMPAD8: return CAM_MOVE_FORWARD;
- case VK_NUMPAD2: return CAM_MOVE_BACKWARD;
- case VK_NUMPAD9: return CAM_MOVE_UP;
- case VK_NUMPAD3: return CAM_MOVE_DOWN;
- case VK_HOME: return CAM_RESET;
- }
- return CAM_UNKNOWN;
- }
- //-----------------------------------------------------------------------------
- // Name: Reset
- // Desc: Reset the camera's position back to the default
- //-----------------------------------------------------------------------------
- VOID CBaseCamera::Reset()
- {
- SetViewParams( &m_vDefaultEye, &m_vDefaultLookAt );
- }
- //-----------------------------------------------------------------------------
- // Name: CFirstPersonCamera
- // Desc: Constructor
- //-----------------------------------------------------------------------------
- CFirstPersonCamera::CFirstPersonCamera()
- {
- }
- //-----------------------------------------------------------------------------
- // Name: FrameMove
- // Desc: Update the view matrix based on user input & elapsed time
- //-----------------------------------------------------------------------------
- VOID CFirstPersonCamera::FrameMove( FLOAT fElapsedTime )
- {
- if( IsKeyDown(m_aKeys[CAM_RESET]) )
- Reset();
- // Get the mouse movement (if any) if the mouse button are down
- if( m_bMouseLButtonDown || m_bMouseMButtonDown || m_bMouseRButtonDown )
- UpdateMouseDelta( fElapsedTime );
- // Get amount of velocity based on the keyboard input and drag (if any)
- UpdateVelocity( fElapsedTime );
- // Simple euler method to calculate position delta
- D3DXVECTOR3 vPosDelta = m_vVelocity * fElapsedTime;
- // If rotating the camera
- if( m_bMouseLButtonDown || m_bMouseMButtonDown || m_bMouseRButtonDown )
- {
- // Update the pitch & yaw angle based on mouse movement
- float fYawDelta = m_vRotVelocity.x;
- float fPitchDelta = m_vRotVelocity.y;
- // Invert pitch if requested
- if( m_bInvertPitch )
- fPitchDelta = -fPitchDelta;
- m_fCameraPitchAngle += fPitchDelta;
- m_fCameraYawAngle += fYawDelta;
- // Limit pitch to straight up or straight down
- m_fCameraPitchAngle = max( -D3DX_PI/2.0f, m_fCameraPitchAngle );
- m_fCameraPitchAngle = min( +D3DX_PI/2.0f, m_fCameraPitchAngle );
- }
- // Make a rotation matrix based on the camera's yaw & pitch
- D3DXMATRIX mCameraRot;
- D3DXMatrixRotationYawPitchRoll( &mCameraRot, m_fCameraYawAngle, m_fCameraPitchAngle, 0 );
- // Transform vectors based on camera's rotation matrix
- D3DXVECTOR3 vWorldUp, vWorldAhead;
- D3DXVECTOR3 vLocalUp = D3DXVECTOR3(0,1,0);
- D3DXVECTOR3 vLocalAhead = D3DXVECTOR3(0,0,1);
- D3DXVec3TransformCoord( &vWorldUp, &vLocalUp, &mCameraRot );
- D3DXVec3TransformCoord( &vWorldAhead, &vLocalAhead, &mCameraRot );
- // Transform the position delta by the camera's rotation
- D3DXVECTOR3 vPosDeltaWorld;
- D3DXVec3TransformCoord( &vPosDeltaWorld, &vPosDelta, &mCameraRot );
- if( !m_bEnableYAxisMovement )
- vPosDeltaWorld.y = 0.0f;
- // Move the eye position
- m_vEye += vPosDeltaWorld;
- if( m_bClipToBoundary )
- ConstrainToBoundary( &m_vEye );
- // Update the lookAt position based on the eye position
- m_vLookAt = m_vEye + vWorldAhead;
- // Update the view matrix
- D3DXMatrixLookAtLH( &m_mView, &m_vEye, &m_vLookAt, &vWorldUp );
- D3DXMatrixInverse( &m_mCameraWorld, NULL, &m_mView );
- }
- //-----------------------------------------------------------------------------
- // Name: CModelViewerCamera
- // Desc: Constructor
- //-----------------------------------------------------------------------------
- CModelViewerCamera::CModelViewerCamera()
- {
- D3DXMatrixIdentity( &m_mWorld );
- D3DXMatrixIdentity( &m_mModelRot );
- D3DXMatrixIdentity( &m_mModelLastRot );
- m_vModelCenter = D3DXVECTOR3(0,0,0);
- m_fRadius = 5.0f;
- m_fDefaultRadius = 5.0f;
- m_fMinRadius = 1.0f;
- m_fMaxRadius = FLT_MAX;
- m_bLimitPitch = false;
- m_bEnablePositionMovement = false;
- m_nRotateModelButtonMask = MOUSE_LEFT_BUTTON;
- m_nZoomButtonMask = MOUSE_WHEEL;
- m_nRotateCameraButtonMask = MOUSE_RIGHT_BUTTON;
- }
- //-----------------------------------------------------------------------------
- // Name: FrameMove
- // Desc: Update the view matrix & the model's world matrix based
- // on user input & elapsed time
- //-----------------------------------------------------------------------------
- VOID CModelViewerCamera::FrameMove( FLOAT fElapsedTime )
- {
- if( IsKeyDown(m_aKeys[CAM_RESET]) )
- Reset();
- // Get the mouse movement (if any) if the mouse button are down
- if( m_nCurrentButtonMask != 0 )
- UpdateMouseDelta( fElapsedTime );
- // Get amount of velocity based on the keyboard input and drag (if any)
- UpdateVelocity( fElapsedTime );
- // Simple euler method to calculate position delta
- D3DXVECTOR3 vPosDelta = m_vVelocity * fElapsedTime;
- // Change the radius from the camera to the model based on wheel scrolling
- if( m_nMouseWheelDelta && m_nZoomButtonMask == MOUSE_WHEEL )
- m_fRadius -= m_nMouseWheelDelta * m_fRadius * 0.1f;
- m_fRadius = min( m_fMaxRadius, m_fRadius );
- m_fRadius = max( m_fMinRadius, m_fRadius );
- m_nMouseWheelDelta = 0;
- // Get the inverse of the arcball's rotation matrix
- D3DXMATRIX mCameraRot;
- D3DXMatrixInverse( &mCameraRot, NULL, m_ViewArcBall.GetRotationMatrix() );
- // Transform vectors based on camera's rotation matrix
- D3DXVECTOR3 vWorldUp, vWorldAhead;
- D3DXVECTOR3 vLocalUp = D3DXVECTOR3(0,1,0);
- D3DXVECTOR3 vLocalAhead = D3DXVECTOR3(0,0,1);
- D3DXVec3TransformCoord( &vWorldUp, &vLocalUp, &mCameraRot );
- D3DXVec3TransformCoord( &vWorldAhead, &vLocalAhead, &mCameraRot );
- // Transform the position delta by the camera's rotation
- D3DXVECTOR3 vPosDeltaWorld;
- D3DXVec3TransformCoord( &vPosDeltaWorld, &vPosDelta, &mCameraRot );
- // Move the lookAt position
- m_vLookAt += vPosDeltaWorld;
- if( m_bClipToBoundary )
- ConstrainToBoundary( &m_vLookAt );
- // Update the eye point based on a radius away from the lookAt position
- m_vEye = m_vLookAt - vWorldAhead * m_fRadius;
- // Update the view matrix
- D3DXMatrixLookAtLH( &m_mView, &m_vEye, &m_vLookAt, &vWorldUp );
- D3DXMATRIX mInvView;
- D3DXMatrixInverse( &mInvView, NULL, &m_mView );
- mInvView._41 = mInvView._42 = mInvView._43 = 0;
- D3DXMATRIX mModelLastRotInv;
- D3DXMatrixInverse(&mModelLastRotInv, NULL, &m_mModelLastRot);
- // Accumulate the delta of the arcball's rotation in view space.
- // Note that per-frame delta rotations could be problematic over long periods of time.
- D3DXMATRIX mModelRot;
- mModelRot = *m_WorldArcBall.GetRotationMatrix();
- m_mModelRot *= m_mView * mModelLastRotInv * mModelRot * mInvView;
- m_mModelLastRot = mModelRot;
- // Since we're accumulating delta rotations, we need to orthonormalize
- // the matrix to prevent eventual matrix skew
- D3DXVECTOR3* pXBasis = (D3DXVECTOR3*) &m_mWorld._11;
- D3DXVECTOR3* pYBasis = (D3DXVECTOR3*) &m_mWorld._21;
- D3DXVECTOR3* pZBasis = (D3DXVECTOR3*) &m_mWorld._31;
- D3DXVec3Normalize( pXBasis, pXBasis );
- D3DXVec3Cross( pYBasis, pZBasis, pXBasis );
- D3DXVec3Normalize( pYBasis, pYBasis );
- D3DXVec3Cross( pZBasis, pXBasis, pYBasis );
- // Translate the rotation matrix to the same position as the lookAt position
- m_mModelRot._41 = m_vLookAt.x;
- m_mModelRot._42 = m_vLookAt.y;
- m_mModelRot._43 = m_vLookAt.z;
- // Translate world matrix so its at the center of the model
- D3DXMATRIX mTrans;
- D3DXMatrixTranslation( &mTrans, -m_vModelCenter.x, -m_vModelCenter.y, -m_vModelCenter.z );
- m_mWorld = mTrans * m_mModelRot;
- }
- //-----------------------------------------------------------------------------
- // Name: Reset
- // Desc: Reset the camera's position back to the default
- //-----------------------------------------------------------------------------
- VOID CModelViewerCamera::Reset()
- {
- CBaseCamera::Reset();
- D3DXMatrixIdentity( &m_mWorld );
- m_fRadius = m_fDefaultRadius;
- m_WorldArcBall.Reset();
- m_ViewArcBall.Reset();
- }
- //-----------------------------------------------------------------------------
- // Name: HandleMessages
- // Desc: Call this from your message proc so this class can handle window messages
- //-----------------------------------------------------------------------------
- LRESULT CModelViewerCamera::HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- CBaseCamera::HandleMessages( hWnd, uMsg, wParam, lParam );
- if( (uMsg == WM_LBUTTONDOWN && m_nRotateModelButtonMask == MOUSE_LEFT_BUTTON) ||
- (uMsg == WM_MBUTTONDOWN && m_nRotateModelButtonMask == MOUSE_MIDDLE_BUTTON) ||
- (uMsg == WM_RBUTTONDOWN && m_nRotateModelButtonMask == MOUSE_RIGHT_BUTTON) )
- {
- int iMouseX = GET_X_LPARAM(lParam);
- int iMouseY = GET_Y_LPARAM(lParam);
- m_WorldArcBall.OnBegin( iMouseX, iMouseY );
- }
- if( (uMsg == WM_LBUTTONDOWN && m_nRotateCameraButtonMask == MOUSE_LEFT_BUTTON) ||
- (uMsg == WM_MBUTTONDOWN && m_nRotateCameraButtonMask == MOUSE_MIDDLE_BUTTON) ||
- (uMsg == WM_RBUTTONDOWN && m_nRotateCameraButtonMask == MOUSE_RIGHT_BUTTON) )
- {
- int iMouseX = GET_X_LPARAM(lParam);
- int iMouseY = GET_Y_LPARAM(lParam);
- m_ViewArcBall.OnBegin( iMouseX, iMouseY );
- }
- if( uMsg == WM_MOUSEMOVE )
- {
- int iMouseX = GET_X_LPARAM(lParam);
- int iMouseY = GET_Y_LPARAM(lParam);
- m_WorldArcBall.OnMove( iMouseX, iMouseY );
- m_ViewArcBall.OnMove( iMouseX, iMouseY );
- }
- if( (uMsg == WM_LBUTTONUP && m_nRotateModelButtonMask == MOUSE_LEFT_BUTTON) ||
- (uMsg == WM_MBUTTONUP && m_nRotateModelButtonMask == MOUSE_MIDDLE_BUTTON) ||
- (uMsg == WM_RBUTTONUP && m_nRotateModelButtonMask == MOUSE_RIGHT_BUTTON) )
- {
- m_WorldArcBall.OnEnd();
- }
- if( (uMsg == WM_LBUTTONUP && m_nRotateCameraButtonMask == MOUSE_LEFT_BUTTON) ||
- (uMsg == WM_MBUTTONUP && m_nRotateCameraButtonMask == MOUSE_MIDDLE_BUTTON) ||
- (uMsg == WM_RBUTTONUP && m_nRotateCameraButtonMask == MOUSE_RIGHT_BUTTON) )
- {
- m_ViewArcBall.OnEnd();
- }
- return FALSE;
- }