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.input; 11 import bindbc.imgui; 12 import creator.viewport.model; 13 import creator.viewport.vertex; 14 import creator.viewport.anim; 15 import creator.viewport.test; 16 17 /** 18 Draws the viewport contents 19 */ 20 void incViewportDraw() { 21 auto camera = inGetCamera(); 22 inBeginScene(); 23 24 switch(incEditMode) { 25 case EditMode.ModelEdit: 26 incViewportModelDraw(camera); 27 break; 28 case EditMode.VertexEdit: 29 incViewportVertexDraw(camera); 30 break; 31 case EditMode.AnimEdit: 32 incViewportAnimDraw(camera); 33 break; 34 case EditMode.ModelTest: 35 incViewportTestDraw(camera); 36 break; 37 default: assert(0); 38 } 39 inEndScene(); 40 } 41 42 /** 43 Draws the viewport overlay (if any) 44 */ 45 void incViewportDrawOverlay() { 46 switch(incEditMode) { 47 case EditMode.ModelEdit: 48 incViewportModelOverlay(); 49 break; 50 case EditMode.VertexEdit: 51 incViewportVertexOverlay(); 52 break; 53 case EditMode.AnimEdit: 54 incViewportAnimOverlay(); 55 break; 56 case EditMode.ModelTest: 57 incViewportTestOverlay(); 58 break; 59 default: assert(0); 60 } 61 } 62 63 /** 64 Begins polling for viewport interactivity 65 */ 66 void incViewportPoll() { 67 incInputPoll(); 68 ImVec2 pos; 69 ImVec2 mpos; 70 igGetItemRectMin(&pos); 71 igGetMousePos(&mpos); 72 incInputSetViewportMouse(pos.x-mpos.x, pos.y-mpos.y); 73 } 74 75 /** 76 Updates the viewport 77 */ 78 void incViewportUpdate() { 79 ImGuiIO* io = igGetIO(); 80 auto camera = inGetCamera(); 81 82 // First update viewport movement 83 incViewportMovement(io, camera); 84 85 // Then update sub-stuff 86 switch(incEditMode) { 87 case EditMode.ModelEdit: 88 incViewportModelUpdate(io, camera); 89 break; 90 case EditMode.VertexEdit: 91 incViewportVertexUpdate(io, camera); 92 break; 93 case EditMode.AnimEdit: 94 incViewportAnimUpdate(io, camera); 95 break; 96 case EditMode.ModelTest: 97 incViewportTestUpdate(io, camera); 98 break; 99 default: assert(0); 100 } 101 } 102 103 /** 104 Updates the viewport toolbars 105 */ 106 void incViewportToolbar() { 107 switch(incEditMode) { 108 case EditMode.ModelEdit: 109 incViewportModelToolbar(); 110 break; 111 case EditMode.VertexEdit: 112 incViewportVertexToolbar(); 113 break; 114 case EditMode.AnimEdit: 115 incViewportAnimToolbar(); 116 break; 117 case EditMode.ModelTest: 118 incViewportTestToolbar(); 119 break; 120 default: assert(0); 121 } 122 } 123 124 /** 125 Called on editing mode present 126 */ 127 void incViewportPresentMode(EditMode mode) { 128 switch(editMode_) { 129 case EditMode.ModelEdit: 130 incViewportModelPresent(); 131 break; 132 case EditMode.VertexEdit: 133 incViewportVertexPresent(); 134 break; 135 case EditMode.AnimEdit: 136 incViewportAnimPresent(); 137 break; 138 case EditMode.ModelTest: 139 incViewportTestPresent(); 140 break; 141 default: assert(0); 142 } 143 } 144 145 /** 146 Called on editing mode withdraw 147 */ 148 void incViewportWithdrawMode(EditMode mode) { 149 switch(editMode_) { 150 case EditMode.ModelEdit: 151 incViewportModelWithdraw(); 152 break; 153 case EditMode.VertexEdit: 154 incViewportVertexWithdraw(); 155 break; 156 case EditMode.AnimEdit: 157 incViewportAnimWithdraw(); 158 break; 159 case EditMode.ModelTest: 160 incViewportTestWithdraw(); 161 break; 162 default: assert(0); 163 } 164 } 165 166 167 /** 168 Updates the viewport tool settings 169 */ 170 void incViewportToolSettings() { 171 switch(incEditMode) { 172 case EditMode.ModelEdit: 173 incViewportModelToolSettings(); 174 break; 175 case EditMode.VertexEdit: 176 incViewportVertexToolSettings(); 177 break; 178 default: 179 incViewportToolSettingsNoTool(); 180 break; 181 } 182 } 183 184 /// For when there's no tools for that view 185 void incViewportToolSettingsNoTool() { 186 import i18n : __; 187 igText(__("No tool selected...")); 188 } 189 190 191 192 193 // 194 // VIEWPORT CAMERA HANDLING 195 // 196 197 enum incVIEWPORT_ZOOM_MIN = 0.05; 198 enum incVIEWPORT_ZOOM_MAX = 8.0; 199 200 /** 201 Target camera position in scene 202 */ 203 vec2 incViewportTargetPosition = vec2(0); 204 205 /** 206 Target camera zoom in scene 207 */ 208 float incViewportTargetZoom = 1; 209 210 /** 211 The actual zoom of the viewport 212 */ 213 float incViewportZoom = 1; 214 215 /** 216 Resets the viewport 217 */ 218 void incViewportReset() { 219 incViewportTargetPosition = vec2(0); 220 incViewportTargetZoom = 1; 221 } 222 223 224 // 225 // Internal Viewport Stuff(TM) 226 // 227 private { 228 bool isMovingViewport; 229 float sx, sy; 230 float csx, csy; 231 bool isMovingPart; 232 233 void incViewportMovement(ImGuiIO* io, Camera camera) { 234 235 // HANDLE MOVE VIEWPORT 236 if (!isMovingViewport && io.MouseDown[1] && incInputIsDragRequested()) { 237 isMovingViewport = true; 238 sx = io.MousePos.x; 239 sy = io.MousePos.y; 240 csx = camera.position.x; 241 csy = camera.position.y; 242 } 243 244 if (isMovingViewport && !io.MouseDown[1]) { 245 isMovingViewport = false; 246 } 247 248 if (isMovingViewport) { 249 250 camera.position = vec2( 251 csx+((io.MousePos.x-sx)/incViewportZoom), 252 csy+((io.MousePos.y-sy)/incViewportZoom) 253 ); 254 255 incViewportTargetPosition = camera.position; 256 } 257 258 // HANDLE ZOOM 259 if (io.MouseWheel != 0) { 260 incViewportZoom += (io.MouseWheel/50)*incViewportZoom; 261 incViewportZoom = clamp(incViewportZoom, incVIEWPORT_ZOOM_MIN, incVIEWPORT_ZOOM_MAX); 262 camera.scale = vec2(incViewportZoom); 263 incViewportTargetZoom = incViewportZoom; 264 } 265 } 266 }