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.model; 8 import creator.viewport.model.deform; 9 import creator.widgets.tooltip; 10 import creator.widgets.label; 11 import creator.widgets.texture; 12 import creator.widgets.dummy; 13 import creator.widgets.dragdrop; 14 import creator.widgets.button; 15 import creator.core.input; 16 import creator.core; 17 import creator.viewport.vertex; 18 import creator; 19 import inochi2d; 20 import bindbc.imgui; 21 import i18n; 22 import std.stdio; 23 24 private { 25 Part[] foundParts; 26 27 enum ENTRY_SIZE = 48; 28 } 29 30 void incViewportModelMenuOpening() { 31 foundParts.length = 0; 32 33 vec2 mpos = incInputGetMousePosition()*-1; 34 mloop: foreach(ref Part part; incActivePuppet.getAllParts()) { 35 rect b = rect(part.bounds.x, part.bounds.y, part.bounds.z-part.bounds.x, part.bounds.w-part.bounds.y); 36 if (b.intersects(mpos)) { 37 38 // Skip already selected parts 39 foreach(pn; incSelectedNodes()) { 40 if (pn.uuid == part.uuid) continue mloop; 41 } 42 foundParts ~= part; 43 } 44 } 45 46 import std.algorithm.sorting : sort; 47 import std.algorithm.mutation : SwapStrategy; 48 import std.math : cmp; 49 sort!((a, b) => cmp( 50 a.zSortNoOffset, 51 b.zSortNoOffset) < 0, SwapStrategy.stable)(foundParts); 52 } 53 54 void incViewportModelMenu() { 55 if (incSelectedNode() != incActivePuppet().root) { 56 if (igMenuItem(__("Focus Selected"))) { 57 incFocusCamera(incSelectedNode()); 58 } 59 } 60 61 if (igBeginChild("FOUND_PARTS", ImVec2(256, 256), false)) { 62 if (foundParts.length > 0) { 63 ImVec2 avail = incAvailableSpace(); 64 ImVec2 cursorPos; 65 foreach(Part part; foundParts) { 66 igPushID(part.uuid); 67 ImVec2 nameSize = incMeasureString(part.name); 68 69 // Selectable 70 igGetCursorPos(&cursorPos); 71 if (igSelectable("###PartSelectable", false, ImGuiSelectableFlags.None, ImVec2(avail.x, ENTRY_SIZE))) { 72 73 // Add selection if ctrl is down, otherwise set selection 74 if (igIsKeyDown(ImGuiKey.LeftCtrl) || igIsKeyDown(ImGuiKey.RightCtrl)) incAddSelectNode(part); 75 else incSelectNode(part); 76 77 // Escape early, we're already done. 78 igPopID(); 79 igEndChild(); 80 igCloseCurrentPopup(); 81 return; 82 } 83 igSetItemAllowOverlap(); 84 85 if(igBeginDragDropSource(ImGuiDragDropFlags.SourceAllowNullID)) { 86 igSetDragDropPayload("_PUPPETNTREE", cast(void*)&part, (&part).sizeof, ImGuiCond.Always); 87 incDragdropNodeList(part); 88 igEndDragDropSource(); 89 } 90 91 // ICON 92 igSetCursorPos(ImVec2(cursorPos.x+2, cursorPos.y+2)); 93 incTextureSlotUntitled("ICON", part.textures[0], ImVec2(ENTRY_SIZE-4, ENTRY_SIZE-4), 24, ImGuiWindowFlags.NoInputs); 94 95 // Name 96 igSetCursorPos(ImVec2(cursorPos.x + ENTRY_SIZE + 4, cursorPos.y + (ENTRY_SIZE/2) - (nameSize.y/2))); 97 incText(part.name); 98 99 // Move to next line 100 igSetCursorPos(ImVec2(cursorPos.x, cursorPos.y + ENTRY_SIZE + 3)); 101 igPopID(); 102 } 103 } else { 104 incText(_("No parts found")); 105 } 106 } 107 igEndChild(); 108 } 109 110 void incViewportModelTools() { 111 if (incArmedParameter()) { 112 incViewportModelDeformTools(); 113 } 114 } 115 116 void incViewportModelConfirmBar() { 117 118 // If parameter is armed we should *not* show the edit mesh button 119 if (incArmedParameter()) return; 120 121 igPushStyleVar(ImGuiStyleVar.FramePadding, ImVec2(16, 4)); 122 if (Drawable node = cast(Drawable)incSelectedNode()) { 123 if (igButton(__(" Edit Mesh"), ImVec2(0, 26))) { 124 incVertexEditStartEditing(node); 125 } 126 127 // Allow copying mesh data via drag n drop for now 128 if(igBeginDragDropTarget()) { 129 incTooltip(_("Copy Mesh Data")); 130 131 const(ImGuiPayload)* payload = igAcceptDragDropPayload("_PUPPETNTREE"); 132 if (payload !is null) { 133 if (Drawable payloadDrawable = cast(Drawable)*cast(Node*)payload.Data) { 134 incSetEditMode(EditMode.VertexEdit); 135 incSelectNode(node); 136 incVertexEditSetTarget(node); 137 incFocusCamera(node, vec2(0, 0)); 138 incVertexEditCopyMeshDataToTarget(payloadDrawable.getMesh()); 139 } 140 } 141 igEndDragDropTarget(); 142 } else { 143 144 145 // Switches Inochi Creator over to Mesh Edit mode 146 // and selects the mesh that you had selected previously 147 // in Model Edit mode. 148 incTooltip(_("Edit Mesh")); 149 } 150 } 151 igPopStyleVar(); 152 } 153 154 void incViewportModelOptions() { 155 igPushStyleVar(ImGuiStyleVar.ItemSpacing, ImVec2(0, 0)); 156 igPushStyleVar(ImGuiStyleVar.WindowPadding, ImVec2(4, 4)); 157 if (!incArmedParameter()) { 158 if(incBeginDropdownMenu("GIZMOS", "")) { 159 160 if (incButtonColored("", ImVec2(0, 0), incShowVertices ? ImVec4.init : ImVec4(0.6, 0.6, 0.6, 1))) { 161 incShowVertices = !incShowVertices; 162 } 163 incTooltip(incShowVertices ? _("Hide Vertices") : _("Show Vertices")); 164 165 igSameLine(0, 4); 166 if (incButtonColored("", ImVec2(0, 0), incShowBounds ? ImVec4.init : ImVec4(0.6, 0.6, 0.6, 1))) { 167 incShowBounds = !incShowBounds; 168 } 169 incTooltip(incShowBounds ? _("Hide Bounds") : _("Show Bounds")); 170 171 igSameLine(0, 4); 172 if (incButtonColored("", ImVec2(0, 0), incShowOrientation ? ImVec4.init : ImVec4(0.6, 0.6, 0.6, 1))) { 173 incShowOrientation = !incShowOrientation; 174 } 175 incTooltip(incShowOrientation ? _("Hide Orientation Gizmo") : _("Show Orientation Gizmo")); 176 177 incEndDropdownMenu(); 178 } 179 incTooltip(_("Gizmos")); 180 } 181 igPopStyleVar(2); 182 } 183 184 void incViewportModelNodeSelectionChanged() { 185 incViewportModelDeformNodeSelectionChanged(); 186 } 187 188 void incViewportModelUpdate(ImGuiIO* io, Camera camera) { 189 if (Parameter param = incArmedParameter()) { 190 incViewportModelDeformUpdate(io, camera, param); 191 } 192 } 193 194 void incViewportModelDraw(Camera camera) { 195 Parameter param = incArmedParameter(); 196 incActivePuppet.update(); 197 incActivePuppet.draw(); 198 199 if (param) { 200 incViewportModelDeformDraw(camera, param); 201 } else { 202 if (incSelectedNodes.length > 0) { 203 foreach(selectedNode; incSelectedNodes) { 204 if (selectedNode is null) continue; 205 if (incShowOrientation) selectedNode.drawOrientation(); 206 if (incShowBounds) selectedNode.drawBounds(); 207 208 209 if (Drawable selectedDraw = cast(Drawable)selectedNode) { 210 211 if (incShowVertices || incEditMode != EditMode.ModelEdit) { 212 selectedDraw.drawMeshLines(); 213 selectedDraw.drawMeshPoints(); 214 } 215 } 216 217 if (Driver selectedDriver = cast(Driver)selectedNode) { 218 selectedDriver.drawDebug(); 219 } 220 } 221 } 222 } 223 } 224 225 void incViewportModelToolSettings() { 226 incViewportModelDeformToolSettings(); 227 } 228 229 void incViewportModelPresent() { 230 231 } 232 233 void incViewportModelWithdraw() { 234 235 } 236 237 void incViewportModelToolbar() { 238 239 }