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.panels.tracking; 8 import creator.core; 9 import creator.viewport.test; 10 import creator.panels; 11 import creator.windows; 12 import creator.widgets; 13 import creator; 14 import bindbc.imgui; 15 import inochi2d; 16 import std.conv; 17 import i18n; 18 import std.string; 19 20 /** 21 The textures frame 22 */ 23 class TrackingPanel : Panel { 24 private: 25 string[string] optionValues; 26 27 bool trackingModeCheckbox(string receiverName, string tooltip, TrackingMode mode) { 28 bool track = incTestGetTrackingMode() == mode; 29 30 // Appended to the name of a face tracking receiver 31 // in the Tracking settings panel 32 const(char)* recvName = _("%s Receiver").format(receiverName).toStringz; 33 34 if (igCheckbox(recvName, &track)) { 35 incTestSetTrackingMode(track ? mode : TrackingMode.None); 36 incTestRestartTracker(); 37 } 38 incTooltip(tooltip); 39 return track; 40 } 41 42 bool canParseAddr(string addr) { 43 import std.socket : parseAddress; 44 try { 45 parseAddress(addr); 46 return true; 47 } catch (Exception ex) { 48 return false; 49 } 50 } 51 52 protected: 53 override 54 debug(InExperimental) 55 void onUpdate() { 56 57 if (incEditMode == EditMode.ModelTest) { 58 ImVec2 avail = incAvailableSpace(); 59 60 if (trackingModeCheckbox("VMC", _("A reciever which uses your phone and associated app to track your body"), TrackingMode.VMC)) { 61 auto adaptorOptions = incTestGetAdaptorOptions(); 62 63 string bindingIP = incSettingsGet("vmc_bind_ip", "0.0.0.0"); 64 if (incInputText(_("Bind Address"), avail.x/2, bindingIP, ImGuiInputTextFlags.None)) { 65 incSettingsSet("vmc_bind_ip", bindingIP); 66 67 if (this.canParseAddr(bindingIP)) { 68 incSettingsSave(); 69 adaptorOptions["address"] = bindingIP; 70 incTestRestartTracker(); 71 } 72 } 73 incTooltip(_("The IP address that the VMC binding server should listen on, default 0.0.0.0")); 74 75 int bindingPort = incSettingsGet("vmc_bind_port", 39540); 76 if (igInputInt(__("Port"), &bindingPort)) { 77 incSettingsSet("vmc_bind_port", bindingPort); 78 79 if (bindingPort > 1 && bindingPort < ushort.max) { 80 incSettingsSave(); 81 optionValues["port"] = bindingPort.text; 82 incTestRestartTracker(); 83 } 84 } 85 incTooltip(_("The port that the VMC binding server should listen on, default 39540")); 86 } 87 88 if (trackingModeCheckbox("VTube Studio", _("A reciever which uses the VTubeStudio iOS app"), TrackingMode.VTS)) { 89 90 string bindingIP = incSettingsGet!string("vts_phone_ip"); 91 if (incInputText("iPhoneIP", _("iPhone IP"), avail.x/2, bindingIP, ImGuiInputTextFlags.None)) { 92 incSettingsSet("vts_phone_ip", bindingIP); 93 94 if (this.canParseAddr(bindingIP)) { 95 incSettingsSave(); 96 optionValues["phoneIP"] = bindingIP; 97 incTestRestartTracker(); 98 } 99 } 100 incTooltip(_("The IP Address of your iPhone,\nYou can find it in the VSeeFace Config panel in VTube Studio")); 101 } 102 103 if (trackingModeCheckbox("OpenSeeFace", _("A receiver which uses OpenSeeFace application"), TrackingMode.OSF)) { 104 string bindingIP = incSettingsGet("osf_bind_ip", "0.0.0.0"); 105 if (incInputText("osfBindAddress", _("OSF Bind Address"), avail.x/2, bindingIP, ImGuiInputTextFlags.None)) { 106 incSettingsSet("osf_bind_ip", bindingIP); 107 108 if (this.canParseAddr(bindingIP)) { 109 incSettingsSave(); 110 optionValues["osf_bind_ip"] = bindingIP; 111 incTestRestartTracker(); 112 } 113 } 114 115 int bindingPort = incSettingsGet("osf_bind_port", 11573); 116 if (igInputInt(__("OSF Listen Port"), &bindingPort)) { 117 incSettingsSet("osf_bind_port", bindingPort); 118 119 if (bindingPort > 1 && bindingPort < ushort.max) { 120 incSettingsSave(); 121 optionValues["osf_bind_port"] = bindingPort.text; 122 incTestRestartTracker(); 123 } 124 } 125 } 126 127 128 if (igCollapsingHeader(__("Tracking Bindings"), ImGuiTreeNodeFlags.DefaultOpen)) { 129 if (igBeginListBox("###BINDINGS")) { 130 foreach(i, binding; incTestGetTrackingBindings()) { 131 igPushID(cast(int)i); 132 133 const(char)* nm = _("%s bound to %s").format(binding.key, binding.param.name).toStringz; 134 if (igSelectable(nm)) { 135 incTestRemoveTrackingBinding(binding); 136 } 137 138 igPopID(); 139 } 140 igEndListBox(); 141 } 142 143 if (igButton("", ImVec2(0, 32))) { 144 incPushWindowList(new TrackingBindingWindow(incViewportTestGetCurrBindable())); 145 } 146 } 147 } else { 148 incLabelOver(_("Not in Test Mode..."), ImVec2(0, 0), true); 149 } 150 } 151 152 public: 153 this() { 154 super("Tracking", _("Tracking"), false); 155 } 156 } 157 158 /** 159 Generate tracking panel frame 160 */ 161 debug(InExperimental) mixin incPanel!TrackingPanel; 162 163