|
| 1 | +#ifndef CAMERAWINDOW_H |
| 2 | +#define CAMERAWINDOW_H |
| 3 | + |
| 4 | +#include <imgui/imgui.h> |
| 5 | +#include <imgui/imgui_impl_glfw.h> |
| 6 | +#include <imgui/imgui_impl_opengl3.h> |
| 7 | + |
| 8 | +#ifdef WINDOWS |
| 9 | +#include <imgui/imgui_impl_win32.h> |
| 10 | +#endif |
| 11 | + |
| 12 | +#ifdef MACOS |
| 13 | +#include <imgui/imgui_impl_osx.h> |
| 14 | +#endif |
| 15 | + |
| 16 | +#include <camera.h> |
| 17 | +#include <commandLine.h> |
| 18 | +#include <atom.h> |
| 19 | +#include <helpMarker.h> |
| 20 | + |
| 21 | +/** |
| 22 | + * @brief The camera controls window. |
| 23 | + * |
| 24 | + */ |
| 25 | +class CameraWindow |
| 26 | +{ |
| 27 | +public: |
| 28 | + |
| 29 | + /** |
| 30 | + * @brief If the Camera or Atoms require updates. |
| 31 | + * |
| 32 | + */ |
| 33 | + struct CameraUpdates |
| 34 | + { |
| 35 | + CameraUpdates() |
| 36 | + : cameraMoved(false), |
| 37 | + atomsMoved(false) |
| 38 | + {} |
| 39 | + |
| 40 | + bool cameraMoved; |
| 41 | + bool atomsMoved; |
| 42 | + }; |
| 43 | + |
| 44 | + CameraWindow() {} |
| 45 | + |
| 46 | + /** |
| 47 | + * @brief Draw the window with Imgui |
| 48 | + * |
| 49 | + * @param options the current options. |
| 50 | + * |
| 51 | + * @remark Actions in the UI are queued for later application. |
| 52 | + * @see CameraWindow::applyQueueActions. |
| 53 | + */ |
| 54 | + void draw |
| 55 | + ( |
| 56 | + CommandLine & options |
| 57 | + ) |
| 58 | + { |
| 59 | + ImGui::Begin("Camera"); |
| 60 | + ImGui::Text("Zoom "); |
| 61 | + ImGui::SameLine(); |
| 62 | + |
| 63 | + ImGui::PushItemFlag(ImGuiItemFlags_ButtonRepeat, true); |
| 64 | + if (ImGui::ArrowButton("##zoomin", ImGuiDir_Up)) { zoomQueue--; } |
| 65 | + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); |
| 66 | + if (ImGui::ArrowButton("##zoomout", ImGuiDir_Down)) { zoomQueue++; } |
| 67 | + ImGui::PopItemFlag(); |
| 68 | + ImGui::SameLine(); HelpMarker("Zoom to and from the focus (W/S)"); |
| 69 | + |
| 70 | + ImGui::Text("Rotate "); |
| 71 | + ImGui::SameLine(); |
| 72 | + |
| 73 | + ImGui::PushItemFlag(ImGuiItemFlags_ButtonRepeat, true); |
| 74 | + if (ImGui::ArrowButton("##rotatel", ImGuiDir_Left)) { rotateQueue--; } |
| 75 | + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); |
| 76 | + if (ImGui::ArrowButton("##rotater", ImGuiDir_Right)) { rotateQueue++; } |
| 77 | + ImGui::PopItemFlag(); |
| 78 | + ImGui::SameLine(); HelpMarker("Rotate around the focus (A/D)"); |
| 79 | + |
| 80 | + ImGui::Text("Incline "); |
| 81 | + ImGui::SameLine(); |
| 82 | + |
| 83 | + ImGui::PushItemFlag(ImGuiItemFlags_ButtonRepeat, true); |
| 84 | + if (ImGui::ArrowButton("##inclineu", ImGuiDir_Up)) { inclineQueue--; } |
| 85 | + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); |
| 86 | + if (ImGui::ArrowButton("##inclined", ImGuiDir_Down)) { inclineQueue++; } |
| 87 | + ImGui::PopItemFlag(); |
| 88 | + ImGui::SameLine(); HelpMarker("Incline around the focus (Q/E)"); |
| 89 | + |
| 90 | + ImGui::Text("Pan x "); |
| 91 | + ImGui::SameLine(); |
| 92 | + |
| 93 | + ImGui::PushItemFlag(ImGuiItemFlags_ButtonRepeat, true); |
| 94 | + if (ImGui::ArrowButton("##panx-", ImGuiDir_Left)) { panxQueue--; } |
| 95 | + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); |
| 96 | + if (ImGui::ArrowButton("##panx+", ImGuiDir_Right)) { panxQueue++; } |
| 97 | + ImGui::PopItemFlag(); |
| 98 | + ImGui::SameLine(); HelpMarker("Pan in x (Left/Right)"); |
| 99 | + |
| 100 | + ImGui::Text("Pan y "); |
| 101 | + ImGui::SameLine(); |
| 102 | + |
| 103 | + ImGui::PushItemFlag(ImGuiItemFlags_ButtonRepeat, true); |
| 104 | + if (ImGui::ArrowButton("##pany-", ImGuiDir_Left)) { panyQueue--; } |
| 105 | + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); |
| 106 | + if (ImGui::ArrowButton("##pany+", ImGuiDir_Right)) { panyQueue++; } |
| 107 | + ImGui::PopItemFlag(); |
| 108 | + ImGui::SameLine(); HelpMarker("Pan in y (Up/Down)"); |
| 109 | + |
| 110 | + ImGui::Text("Pan z "); |
| 111 | + ImGui::SameLine(); |
| 112 | + |
| 113 | + ImGui::PushItemFlag(ImGuiItemFlags_ButtonRepeat, true); |
| 114 | + if (ImGui::ArrowButton("##panz-", ImGuiDir_Left)) { panzQueue--; } |
| 115 | + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); |
| 116 | + if (ImGui::ArrowButton("##panz+", ImGuiDir_Right)) { panzQueue++; } |
| 117 | + ImGui::PopItemFlag(); |
| 118 | + ImGui::SameLine(); HelpMarker("Pan in z (.//)"); |
| 119 | + |
| 120 | + ImGui::PushItemWidth(200); |
| 121 | + ImGui::InputFloat("Zoom speed: ", &options.cameraZoomSpeed.value, 0.01f, 1.0f, "%.2f"); |
| 122 | + ImGui::SameLine(); HelpMarker("Modify zoom rate (CTRL-CLICK for faster steps)"); |
| 123 | + |
| 124 | + ImGui::PushItemWidth(200); |
| 125 | + ImGui::InputFloat("Rotate speed: ", &options.cameraRotateSpeed.value, 0.01f, 1.0f, "%.2f"); |
| 126 | + ImGui::SameLine(); HelpMarker("Modify rotate rate (CTRL-CLICK for faster steps)"); |
| 127 | + |
| 128 | + ImGui::PushItemWidth(200); |
| 129 | + ImGui::InputFloat("Incline speed: ", &options.cameraInclineSpeed.value, 0.01f, 1.0f, "%.2f"); |
| 130 | + ImGui::SameLine(); HelpMarker("Modify inclination rate (CTRL-CLICK for faster steps)"); |
| 131 | + |
| 132 | + ImGui::PushItemWidth(200); |
| 133 | + ImGui::InputFloat("Pan speed: ", &options.cameraPanSpeed.value, 0.01f, 1.0f, "%.2f"); |
| 134 | + ImGui::SameLine(); HelpMarker("Modify pan rate (CTRL-CLICK for faster steps)"); |
| 135 | + |
| 136 | + if (ImGui::Button("Reset Camera ")) |
| 137 | + { |
| 138 | + resetCamera = true; |
| 139 | + } |
| 140 | + |
| 141 | + ImGui::End(); |
| 142 | + } |
| 143 | + |
| 144 | + /** |
| 145 | + * @brief Apply queued actions from the UI. |
| 146 | + * |
| 147 | + * @param camera the Camera to update. |
| 148 | + * @param atoms the Atoms to update. |
| 149 | + * @param options the options to use for actions. |
| 150 | + * @param dr the length unit. |
| 151 | + * @param dtheta the rotation unit. |
| 152 | + * @param dphi the incline unit. |
| 153 | + * @return CameraUpdates Whether the Camera or Atoms were updated. |
| 154 | + */ |
| 155 | + CameraUpdates applyQueueActions |
| 156 | + ( |
| 157 | + Camera & camera, |
| 158 | + std::vector<Atom> & atoms, |
| 159 | + const CommandLine & options, |
| 160 | + const float & dr, |
| 161 | + const float & dtheta, |
| 162 | + const float & dphi |
| 163 | + ) |
| 164 | + { |
| 165 | + CameraUpdates moved; |
| 166 | + |
| 167 | + if (zoomQueue != 0) |
| 168 | + { |
| 169 | + camera.zoom(dr*options.cameraZoomSpeed.value*zoomQueue); |
| 170 | + zoomQueue = 0; |
| 171 | + moved.cameraMoved = true; |
| 172 | + } |
| 173 | + |
| 174 | + if (rotateQueue != 0) |
| 175 | + { |
| 176 | + camera.rotate(dtheta*options.cameraRotateSpeed.value*rotateQueue); |
| 177 | + rotateQueue = 0; |
| 178 | + moved.cameraMoved = true; |
| 179 | + } |
| 180 | + |
| 181 | + if (inclineQueue != 0) |
| 182 | + { |
| 183 | + camera.incline(dphi*options.cameraInclineSpeed.value*inclineQueue); |
| 184 | + inclineQueue = 0; |
| 185 | + moved.cameraMoved = true; |
| 186 | + } |
| 187 | + |
| 188 | + if (resetCamera) |
| 189 | + { |
| 190 | + if (!options.noCentering.value) { center(atoms); } |
| 191 | + if (options.focus.value < atoms.size()) { centerOn(atoms, options.focus.value); } |
| 192 | + camera.reset(atoms); |
| 193 | + moved.atomsMoved = true; |
| 194 | + moved.cameraMoved = true; |
| 195 | + resetCamera = false; |
| 196 | + } |
| 197 | + |
| 198 | + if (panxQueue != 0) |
| 199 | + { |
| 200 | + translate(atoms, {dr*options.cameraPanSpeed.value*panxQueue, 0.0, 0.0}); |
| 201 | + panxQueue = 0; |
| 202 | + moved.atomsMoved = true; |
| 203 | + } |
| 204 | + |
| 205 | + if (panyQueue != 0) |
| 206 | + { |
| 207 | + translate(atoms, {0.0, dr*options.cameraPanSpeed.value*panyQueue, 0.0}); |
| 208 | + panyQueue = 0; |
| 209 | + moved.atomsMoved = true; |
| 210 | + } |
| 211 | + |
| 212 | + if (panzQueue != 0) |
| 213 | + { |
| 214 | + translate(atoms, {0.0, 0.0, dr*options.cameraPanSpeed.value*panzQueue}); |
| 215 | + panzQueue = 0; |
| 216 | + moved.atomsMoved = true; |
| 217 | + } |
| 218 | + |
| 219 | + return moved; |
| 220 | + } |
| 221 | + |
| 222 | +private: |
| 223 | + |
| 224 | + inline static int zoomQueue = 0; |
| 225 | + inline static int rotateQueue = 0; |
| 226 | + inline static int inclineQueue = 0; |
| 227 | + inline static int panxQueue = 0; |
| 228 | + inline static int panyQueue = 0; |
| 229 | + inline static int panzQueue = 0; |
| 230 | + inline static bool resetCamera = false; |
| 231 | + |
| 232 | +}; |
| 233 | + |
| 234 | +#endif /* CAMERAWINDOW_H */ |
0 commit comments