1 /* 2 Copyright © 2020, Inochi2D Project 3 Distributed under the 2-Clause BSD License, see LICENSE file. 4 5 Authors: Luna Nielsen 6 */ 7 module creator.viewport; 8 import inochi2d; 9 import creator; 10 import creator.core; 11 import creator.core.input; 12 import bindbc.imgui; 13 import creator.viewport.model; 14 import creator.viewport.vertex; 15 import creator.viewport.anim; 16 import creator.viewport.test; 17 18 /** 19 Draws the viewport contents 20 */ 21 void incViewportDraw() { 22 auto camera = inGetCamera(); 23 inBeginScene(); 24 25 switch(incEditMode) { 26 case EditMode.ModelEdit: 27 incViewportModelDraw(camera); 28 break; 29 case EditMode.VertexEdit: 30 incViewportVertexDraw(camera); 31 break; 32 case EditMode.AnimEdit: 33 incViewportAnimDraw(camera); 34 break; 35 case EditMode.ModelTest: 36 incViewportTestDraw(camera); 37 break; 38 default: assert(0); 39 } 40 inEndScene(); 41 42 if (incShouldPostProcess) { 43 inPostProcessScene(); 44 } 45 } 46 47 /** 48 Draws the viewport overlay (if any) 49 */ 50 void incViewportDrawTools() { 51 switch(incEditMode) { 52 case EditMode.VertexEdit: 53 incViewportVertexTools(); 54 break; 55 case EditMode.ModelEdit: 56 incViewportModelTools(); 57 break; 58 case EditMode.AnimEdit: 59 case EditMode.ModelTest: 60 break; 61 default: assert(0); 62 } 63 } 64 65 void incViewportDrawOptions() { 66 switch(incEditMode) { 67 case EditMode.ModelEdit: 68 incViewportModelOptions(); 69 break; 70 case EditMode.VertexEdit: 71 incViewportVertexOptions(); 72 break; 73 case EditMode.AnimEdit: 74 incViewportAnimOverlay(); 75 break; 76 case EditMode.ModelTest: 77 incViewportTestOverlay(); 78 break; 79 default: assert(0); 80 } 81 } 82 83 void incViewportDrawConfirmBar() { 84 switch(incEditMode) { 85 case EditMode.VertexEdit: 86 incViewportVertexConfirmBar(); 87 break; 88 case EditMode.ModelEdit: 89 incViewportModelConfirmBar(); 90 break; 91 case EditMode.AnimEdit: 92 case EditMode.ModelTest: 93 break; 94 default: assert(0); 95 } 96 } 97 98 /** 99 Begins polling for viewport interactivity 100 */ 101 void incViewportPoll() { 102 incInputPoll(); 103 ImVec2 pos; 104 ImVec2 mpos; 105 igGetItemRectMin(&pos); 106 igGetMousePos(&mpos); 107 incInputSetViewportMouse(pos.x-mpos.x, pos.y-mpos.y); 108 } 109 110 /** 111 Updates the viewport 112 */ 113 void incViewportUpdate(bool localOnly = false) { 114 ImGuiIO* io = igGetIO(); 115 auto camera = inGetCamera(); 116 117 // First update viewport movement 118 if (!localOnly) incViewportMovement(io, camera); 119 120 // Then update sub-stuff 121 switch(incEditMode) { 122 case EditMode.ModelEdit: 123 incViewportModelUpdate(io, camera); 124 break; 125 case EditMode.VertexEdit: 126 incViewportVertexUpdate(io, camera); 127 break; 128 case EditMode.AnimEdit: 129 incViewportAnimUpdate(io, camera); 130 break; 131 case EditMode.ModelTest: 132 incViewportTestUpdate(io, camera); 133 break; 134 default: assert(0); 135 } 136 } 137 138 /** 139 Updates the viewport toolbars 140 */ 141 void incViewportToolbar() { 142 switch(incEditMode) { 143 case EditMode.ModelEdit: 144 incViewportModelToolbar(); 145 break; 146 case EditMode.VertexEdit: 147 incViewportVertexToolbar(); 148 break; 149 case EditMode.AnimEdit: 150 incViewportAnimToolbar(); 151 break; 152 case EditMode.ModelTest: 153 incViewportTestToolbar(); 154 break; 155 default: assert(0); 156 } 157 } 158 159 /** 160 Called on editing mode present 161 */ 162 void incViewportPresentMode(EditMode mode) { 163 switch(editMode_) { 164 case EditMode.ModelEdit: 165 incViewportModelPresent(); 166 break; 167 case EditMode.VertexEdit: 168 incViewportVertexPresent(); 169 break; 170 case EditMode.AnimEdit: 171 incViewportAnimPresent(); 172 break; 173 case EditMode.ModelTest: 174 incViewportTestPresent(); 175 break; 176 default: assert(0); 177 } 178 } 179 180 /** 181 Called on editing mode withdraw 182 */ 183 void incViewportWithdrawMode(EditMode mode) { 184 switch(editMode_) { 185 case EditMode.ModelEdit: 186 incViewportModelWithdraw(); 187 break; 188 case EditMode.VertexEdit: 189 incViewportVertexWithdraw(); 190 break; 191 case EditMode.AnimEdit: 192 incViewportAnimWithdraw(); 193 break; 194 case EditMode.ModelTest: 195 incViewportTestWithdraw(); 196 break; 197 default: assert(0); 198 } 199 } 200 201 void incViewportMenu() { 202 switch(incEditMode) { 203 case EditMode.ModelEdit: 204 incViewportModelMenu(); 205 break; 206 default: return; 207 } 208 } 209 210 void incViewportMenuOpening() { 211 switch(incEditMode) { 212 case EditMode.ModelEdit: 213 incViewportModelMenuOpening(); 214 break; 215 default: return; 216 } 217 } 218 219 bool incViewportHasMenu() { 220 switch(incEditMode) { 221 case EditMode.ModelEdit: return true; 222 default: return false; 223 } 224 } 225 226 /** 227 Updates the viewport tool settings 228 */ 229 void incViewportToolSettings() { 230 switch(incEditMode) { 231 case EditMode.ModelEdit: 232 incViewportModelToolSettings(); 233 break; 234 case EditMode.VertexEdit: 235 incViewportVertexToolSettings(); 236 break; 237 default: 238 incViewportToolSettingsNoTool(); 239 break; 240 } 241 } 242 243 bool incViewportAlwaysUpdate() { 244 switch(incEditMode) { 245 case EditMode.ModelTest: 246 return true; 247 default: return false; 248 } 249 } 250 251 /// For when there's no tools for that view 252 void incViewportToolSettingsNoTool() { 253 import i18n : _; 254 import creator.widgets.label; 255 incText(_("No tool selected...")); 256 } 257 258 bool incStartedDrag(int btn) { 259 return isDragging[btn]; 260 } 261 262 void incBeginDrag(int btn) { 263 isDragging[btn] = true; 264 } 265 266 void incEndDrag(int btn) { 267 isDragging[btn] = false; 268 } 269 270 bool incDragStartedInViewport(int btn) { 271 return isDraggingInViewport[btn]; 272 } 273 274 void incBeginDragInViewport(int btn) { 275 isDraggingInViewport[btn] = true; 276 } 277 278 void incEndDragInViewport(int btn) { 279 isDraggingInViewport[btn] = false; 280 } 281 282 // 283 // VIEWPORT CAMERA HANDLING 284 // 285 286 enum incVIEWPORT_ZOOM_MIN = 0.05; 287 enum incVIEWPORT_ZOOM_MAX = 12.0; 288 289 /** 290 Target camera position in scene 291 */ 292 vec2 incViewportTargetPosition = vec2(0); 293 294 /** 295 Target camera zoom in scene 296 */ 297 float incViewportTargetZoom = 1; 298 299 /** 300 The actual zoom of the viewport 301 */ 302 float incViewportZoom = 1; 303 304 /** 305 Resets the viewport 306 */ 307 void incViewportReset() { 308 incViewportTargetPosition = vec2(0); 309 incViewportTargetZoom = 1; 310 } 311 312 313 // 314 // Internal Viewport Stuff(TM) 315 // 316 private { 317 bool[ImGuiMouseButton.COUNT] isDraggingInViewport; 318 bool[ImGuiMouseButton.COUNT] isDragging; 319 bool isMovingViewport; 320 float sx, sy; 321 float csx, csy; 322 bool isMovingPart; 323 324 void incViewportMovement(ImGuiIO* io, Camera camera) { 325 float uiScale = incGetUIScale(); 326 327 // HANDLE MOVE VIEWPORT 328 if (!isMovingViewport && io.MouseDown[1] && incInputIsDragRequested()) { 329 isMovingViewport = true; 330 sx = io.MousePos.x; 331 sy = io.MousePos.y; 332 csx = camera.position.x; 333 csy = camera.position.y; 334 } 335 336 if (isMovingViewport && !io.MouseDown[1]) { 337 isMovingViewport = false; 338 } 339 340 if (isMovingViewport) { 341 342 camera.position = vec2( 343 csx+((io.MousePos.x-sx)/incViewportZoom)*uiScale, 344 csy+((io.MousePos.y-sy)/incViewportZoom)*uiScale 345 ); 346 347 incViewportTargetPosition = camera.position; 348 } 349 350 // HANDLE ZOOM 351 if (io.MouseWheel != 0) { 352 incViewportZoom += (io.MouseWheel/50)*incViewportZoom*uiScale; 353 incViewportZoom = clamp(incViewportZoom, incVIEWPORT_ZOOM_MIN, incVIEWPORT_ZOOM_MAX); 354 camera.scale = vec2(incViewportZoom); 355 incViewportTargetZoom = incViewportZoom; 356 } 357 } 358 }