void ResetCamera() { g_model.getCenter(g_targetPos[0], g_targetPos[1], g_targetPos[2]); g_cameraPos[0] = g_targetPos[0]; g_cameraPos[1] = g_targetPos[1]; g_cameraPos[2] = g_targetPos[2] + g_model.getRadius() + CAMERA_ZNEAR + 0.4f; g_pitch = 0.0f; g_heading = 0.0f; }
void ProcessMouseInput(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { // Use the left mouse button to track the camera. // Use the middle mouse button to dolly the camera. // Use the right mouse button to orbit the camera. enum CameraMode {CAMERA_NONE, CAMERA_TRACK, CAMERA_DOLLY, CAMERA_ORBIT}; static CameraMode cameraMode = CAMERA_NONE; static POINT ptMousePrev = {0}; static POINT ptMouseCurrent = {0}; static int mouseButtonsDown = 0; static float dx = 0.0f; static float dy = 0.0f; switch (msg) { case WM_LBUTTONDOWN: cameraMode = CAMERA_TRACK; ++mouseButtonsDown; SetCapture(hWnd); ptMousePrev.x = static_cast<int>(static_cast<short>(LOWORD(lParam))); ptMousePrev.y = static_cast<int>(static_cast<short>(HIWORD(lParam))); ClientToScreen(hWnd, &ptMousePrev); break; case WM_RBUTTONDOWN: cameraMode = CAMERA_ORBIT; ++mouseButtonsDown; SetCapture(hWnd); ptMousePrev.x = static_cast<int>(static_cast<short>(LOWORD(lParam))); ptMousePrev.y = static_cast<int>(static_cast<short>(HIWORD(lParam))); ClientToScreen(hWnd, &ptMousePrev); break; case WM_MBUTTONDOWN: cameraMode = CAMERA_DOLLY; ++mouseButtonsDown; SetCapture(hWnd); ptMousePrev.x = static_cast<int>(static_cast<short>(LOWORD(lParam))); ptMousePrev.y = static_cast<int>(static_cast<short>(HIWORD(lParam))); ClientToScreen(hWnd, &ptMousePrev); break; case WM_MOUSEMOVE: ptMouseCurrent.x = static_cast<int>(static_cast<short>(LOWORD(lParam))); ptMouseCurrent.y = static_cast<int>(static_cast<short>(HIWORD(lParam))); ClientToScreen(hWnd, &ptMouseCurrent); switch (cameraMode) { case CAMERA_TRACK: dx = static_cast<float>(ptMouseCurrent.x - ptMousePrev.x); dx *= MOUSE_TRACK_SPEED; dy = static_cast<float>(ptMouseCurrent.y - ptMousePrev.y); dy *= MOUSE_TRACK_SPEED; g_cameraPos[0] -= dx; g_cameraPos[1] += dy; g_targetPos[0] -= dx; g_targetPos[1] += dy; break; case CAMERA_DOLLY: dy = static_cast<float>(ptMouseCurrent.y - ptMousePrev.y); dy *= MOUSE_DOLLY_SPEED; g_cameraPos[2] -= dy; if (g_cameraPos[2] < g_model.getRadius() + CAMERA_ZNEAR) g_cameraPos[2] = g_model.getRadius() + CAMERA_ZNEAR; if (g_cameraPos[2] > CAMERA_ZFAR - g_model.getRadius()) g_cameraPos[2] = CAMERA_ZFAR - g_model.getRadius(); break; case CAMERA_ORBIT: dx = static_cast<float>(ptMouseCurrent.x - ptMousePrev.x); dx *= MOUSE_ORBIT_SPEED; dy = static_cast<float>(ptMouseCurrent.y - ptMousePrev.y); dy *= MOUSE_ORBIT_SPEED; g_heading += dx; g_pitch += dy; if (g_pitch > 90.0f) g_pitch = 90.0f; if (g_pitch < -90.0f) g_pitch = -90.0f; break; } ptMousePrev.x = ptMouseCurrent.x; ptMousePrev.y = ptMouseCurrent.y; break; case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP: if (--mouseButtonsDown <= 0) { mouseButtonsDown = 0; cameraMode = CAMERA_NONE; ReleaseCapture(); } else { if (wParam & MK_LBUTTON) cameraMode = CAMERA_TRACK; else if (wParam & MK_RBUTTON) cameraMode = CAMERA_ORBIT; else if (wParam & MK_MBUTTON) cameraMode = CAMERA_DOLLY; } break; default: break; } }