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 }