?? dxutmisc.cpp
字號:
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 figure 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 );
}
//--------------------------------------------------------------------------------------
// 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 );
}
//--------------------------------------------------------------------------------------
// 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;
++m_cKeysDown;
}
}
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 && (DWORD)mappedKey < 8 )
{
m_aKeys[ mappedKey ] &= ~KEY_IS_DOWN_MASK;
--m_cKeysDown;
}
break;
}
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_LBUTTONDOWN:
case WM_RBUTTONDBLCLK:
case WM_MBUTTONDBLCLK:
case WM_LBUTTONDBLCLK:
{
// Compute the drag rectangle in screen coord.
POINT ptCursor = { (short)LOWORD(lParam), (short)HIWORD(lParam) };
// Update member var state
if( ( uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK ) && PtInRect( &m_rcDrag, ptCursor ) )
{ m_bMouseLButtonDown = true; m_nCurrentButtonMask |= MOUSE_LEFT_BUTTON; }
if( ( uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONDBLCLK ) && PtInRect( &m_rcDrag, ptCursor ) )
{ m_bMouseMButtonDown = true; m_nCurrentButtonMask |= MOUSE_MIDDLE_BUTTON; }
if( ( uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONDBLCLK ) && PtInRect( &m_rcDrag, ptCursor ) )
{ 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_CAPTURECHANGED:
{
if( (HWND)lParam != hWnd )
{
if( (m_nCurrentButtonMask & MOUSE_LEFT_BUTTON) ||
(m_nCurrentButtonMask & MOUSE_MIDDLE_BUTTON) ||
(m_nCurrentButtonMask & MOUSE_RIGHT_BUTTON) )
{
m_bMouseLButtonDown = false;
m_bMouseMButtonDown = false;
m_bMouseRButtonDown = false;
m_nCurrentButtonMask &= ~MOUSE_LEFT_BUTTON;
m_nCurrentButtonMask &= ~MOUSE_MIDDLE_BUTTON;
m_nCurrentButtonMask &= ~MOUSE_RIGHT_BUTTON;
ReleaseCapture();
}
}
break;
}
case WM_MOUSEWHEEL:
// Update member var state
m_nMouseWheelDelta = (short)HIWORD(wParam) / 120;
break;
}
return FALSE;
}
//--------------------------------------------------------------------------------------
// Figure out the velocity based on keyboard input & drag if any
//--------------------------------------------------------------------------------------
void CBaseCamera::GetInput( bool bGetKeyboardInput, bool bGetMouseInput, bool bGetGamepadInput, bool bResetCursorAfterMove )
{
m_vKeyboardDirection = D3DXVECTOR3(0,0,0);
if( bGetKeyboardInput )
{
// Update acceleration vector based on keyboard state
if( IsKeyDown(m_aKeys[CAM_MOVE_FORWARD]) )
m_vKeyboardDirection.z += 1.0f;
if( IsKeyDown(m_aKeys[CAM_MOVE_BACKWARD]) )
m_vKeyboardDirection.z -= 1.0f;
if( m_bEnableYAxisMovement )
{
if( IsKeyDown(m_aKeys[CAM_MOVE_UP]) )
m_vKeyboardDirection.y += 1.0f;
if( IsKeyDown(m_aKeys[CAM_MOVE_DOWN]) )
m_vKeyboardDirection.y -= 1.0f;
}
if( IsKeyDown(m_aKeys[CAM_STRAFE_RIGHT]) )
m_vKeyboardDirection.x += 1.0f;
if( IsKeyDown(m_aKeys[CAM_STRAFE_LEFT]) )
m_vKeyboardDirection.x -= 1.0f;
}
if( bGetMouseInput )
{
// Get current position of mouse
POINT ptCurMouseDelta;
POINT ptCurMousePos;
if( 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;
}
else
{
// If GetCursorPos() returns false, just set delta to zero
ptCurMouseDelta.x = 0;
ptCurMouseDelta.y = 0;
}
if( bResetCursorAfterMove && DXUTIsActive() )
{
// 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;
// Get the center of the current monitor
MONITORINFO mi;
mi.cbSize = sizeof(MONITORINFO);
DXUTGetMonitorInfo( DXUTMonitorFromWindow(DXUTGetHWND(),MONITOR_DEFAULTTONEAREST), &mi );
ptCenter.x = (mi.rcMonitor.left + mi.rcMonitor.right) / 2;
ptCenter.y = (mi.rcMonitor.top + mi.rcMonitor.bottom) / 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;
}
if( bGetGamepadInput )
{
m_vGamePadLeftThumb = D3DXVECTOR3(0,0,0);
m_vGamePadRightThumb = D3DXVECTOR3(0,0,0);
// Get controller state
for( DWORD iUserIndex=0; iUserIndex<DXUT_MAX_CONTROLLERS; iUserIndex++ )
{
DXUTGetGamepadState( iUserIndex, &m_GamePad[iUserIndex], true, true );
// Mark time if the controller is in a non-zero state
if( m_GamePad[iUserIndex].wButtons ||
m_GamePad[iUserIndex].sThumbLX || m_GamePad[iUserIndex].sThumbLX ||
m_GamePad[iUserIndex].sThumbRX || m_GamePad[iUserIndex].sThumbRY ||
m_GamePad[iUserIndex].bLeftTrigger || m_GamePad[iUserIndex].bRightTrigger )
{
m_GamePadLastActive[iUserIndex] = DXUTGetTime();
}
}
// Find out which controller was non-zero last
int iMostRecentlyActive = -1;
double fMostRecentlyActiveTime = 0.0f;
for( DWORD iUserIndex=0; iUserIndex<DXUT_MAX_CONTROLLERS; iUserIndex++ )
{
if( m_GamePadLastActive[iUserIndex] > fMostRecentlyActiveTime )
{
fMostRecentlyActiveTime = m_GamePadLastActive[iUserIndex];
iMostRecentlyActive = iUserIndex;
}
}
// Use the most recent non-zero controller if its connected
if( iMostRecentlyActive >= 0 && m_GamePad[iMostRecentlyActive].bConnected )
{
m_vGamePadLeftThumb.x = m_GamePad[iMostRecentlyActive].fThumbLX;
m_vGamePadLeftThumb.y = 0.0f;
m_vGamePadLeftThumb.z = m_GamePad[iMostRecentlyActive].fThumbLY;
m_vGamePadRightThumb.x = m_GamePad[iMostRecentlyActive].fThumbRX;
m_vGamePadRightThumb.y = 0.0f;
m_vGamePadRightThumb.z = m_GamePad[iMostRecentlyActive].fThumbRY;
}
}
}
//--------------------------------------------------------------------------------------
// Figure out the velocity based on keyboard input & drag if any
//--------------------------------------------------------------------------------------
void CBaseCamera::UpdateVelocity( float fElapsedTime )
{
D3DXMATRIX mRotDelta;
D3DXVECTOR2 vGamePadRightThumb = D3DXVECTOR2(m_vGamePadRightThumb.x, -m_vGamePadRightThumb.z);
m_vRotVelocity = m_vMouseDelta * m_fRotationScaler + vGamePadRightThumb * 0.02f;
D3DXVECTOR3 vAccel = m_vKeyboardDirection + m_vGamePadLeftThumb;
// 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 immediately change the velocity
m_vVelocity = vAccel;
}
}
//--------------------------------------------------------------------------------------
// Clamps pV to lie inside m_vMinBoundary & m_vMaxBoundary
//-------------------------------------------------
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -