#include #include #include #include #include #include #include namespace { bool gIsDebugCameraActive = false; index_t gPreviousCameraIndex = 0; float gPitch = 0.0f; float gYaw = 0.0f; bool gFirstUpdate = true; bool gIsFpsModeActive = false; bool gWasRightMouseButtonDown = false; } // namespace void ActivateDebugController() { Assert(gIsDebugCameraActive == false); Camera* currentCam = GetCurrentCamera(); gPreviousCameraIndex = currentCam->Index; SetCurrentCamera(kDebugCamera); gIsDebugCameraActive = true; gFirstUpdate = true; gIsFpsModeActive = false; gWasRightMouseButtonDown = false; } void DeactivateDebugController() { Assert(gIsDebugCameraActive); gIsDebugCameraActive = false; SetCurrentCamera(gPreviousCameraIndex); } bool IsDebugControllerActive() { return gIsDebugCameraActive; } void UpdateDebugController(float dt) { Camera* currentCam = GetCurrentCamera(); if (gFirstUpdate) { Vector3 dir = Vector3{ 0.0f, 0.0f, 0.0f } - currentCam->Position; dir = Normalize(dir); gPitch = asinf(dir.z); gYaw = atan2f(dir.y, dir.x); gFirstUpdate = false; Vector3 forward; forward.x = cosf(gPitch) * cosf(gYaw); forward.y = cosf(gPitch) * sinf(gYaw); forward.z = sinf(gPitch); Vector3 right = Normalize(Cross(Vector3{ 0.0f, 0.0f, 1.0f }, forward)); currentCam->Target = currentCam->Position + forward; currentCam->Up = Cross(forward, right); } bool isRightMouseButtonDown = IsMouseButtonDown(MouseButton::Right); if (isRightMouseButtonDown && !gWasRightMouseButtonDown) { gIsFpsModeActive = !gIsFpsModeActive; } gWasRightMouseButtonDown = isRightMouseButtonDown; if (!gIsFpsModeActive) { return; } MousePosition mouseDelta = GetMouseDelta(); float sensitivity = 0.005f; gYaw += mouseDelta.X * sensitivity; gPitch -= mouseDelta.Y * sensitivity; gPitch = std::min(gPitch, 1.5f); gPitch = std::max(gPitch, -1.5f); if (IsKeyDown(ScanCode::Q)) { gYaw -= 2.0f * dt; } if (IsKeyDown(ScanCode::E)) { gYaw += 2.0f * dt; } Vector3 forward; forward.x = cosf(gPitch) * cosf(gYaw); forward.y = cosf(gPitch) * sinf(gYaw); forward.z = sinf(gPitch); Vector3 right = Normalize(Cross(Vector3{ 0.0f, 0.0f, 1.0f }, forward)); Vector3 defaultUp = Cross(forward, right); static const float kMovementPerFrame = 10.f; // 10m/s float speedPerFrame = kMovementPerFrame; if (IsKeyDown(ScanCode::LeftShift)) { speedPerFrame *= 10.f; // 100m/s } if (IsKeyDown(ScanCode::W)) { currentCam->Position = currentCam->Position + forward * (speedPerFrame * dt); } if (IsKeyDown(ScanCode::S)) { currentCam->Position = currentCam->Position - forward * (speedPerFrame * dt); } if (IsKeyDown(ScanCode::D)) { currentCam->Position = currentCam->Position + right * (speedPerFrame * dt); } if (IsKeyDown(ScanCode::A)) { currentCam->Position = currentCam->Position - right * (speedPerFrame * dt); } if (IsKeyDown(ScanCode::Space)) { currentCam->Position = currentCam->Position + defaultUp * (speedPerFrame * dt); } if (IsKeyDown(ScanCode::LeftControl)) { currentCam->Position = currentCam->Position - defaultUp * (speedPerFrame * dt); } currentCam->Target = currentCam->Position + forward; currentCam->Up = defaultUp; } #if JULIET_DEBUG void RenderImGuiDebugController(float dt) { Camera* currentCam = GetCurrentCamera(); ImGui::Text("Delta time: %f", dt); ImGui::Text("Camera:"); ImGui::Indent(); ImGui::BulletText("Index: %zu", (size_t)currentCam->Index); ImGui::BulletText("Position: (%.3f, %.3f, %.3f)", currentCam->Position.x, currentCam->Position.y, currentCam->Position.z); ImGui::BulletText("Target: (%.3f, %.3f, %.3f)", currentCam->Target.x, currentCam->Target.y, currentCam->Target.z); ImGui::BulletText("Up: (%.3f, %.3f, %.3f)", currentCam->Up.x, currentCam->Up.y, currentCam->Up.z); ImGui::BulletText("FOV: %.3f rad", currentCam->FOV); ImGui::BulletText("AspectRatio: %.3f", currentCam->AspectRatio); ImGui::BulletText("NearPlane: %.3f", currentCam->NearPlane); ImGui::BulletText("FarPlane: %.3f", currentCam->FarPlane); ImGui::BulletText("Pitch: %.3f, Yaw: %.3f", gPitch, gYaw); ImGui::BulletText("FPS Mode: %s", gIsFpsModeActive ? "Active" : "Inactive"); ImGui::Unindent(); } #endif