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 = (receiverName~_(" Receiver")).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 void onUpdate() { 55 56 if (incEditMode == EditMode.ModelTest) { 57 ImVec2 avail = incAvailableSpace(); 58 59 if (trackingModeCheckbox("VMC", _("A reciever which uses your phone and associated app to track your body"), TrackingMode.VMC)) { 60 auto adaptorOptions = incTestGetAdaptorOptions(); 61 62 string bindingIP = incSettingsGet("vmc_bind_ip", "0.0.0.0"); 63 if (incInputText(__("Bind Address"), avail.x/2, bindingIP, ImGuiInputTextFlags.None)) { 64 incSettingsSet("vmc_bind_ip", bindingIP); 65 66 if (this.canParseAddr(bindingIP)) { 67 incSettingsSave(); 68 adaptorOptions["address"] = bindingIP; 69 incTestRestartTracker(); 70 } 71 } 72 incTooltip(_("The IP address that the VMC binding server should listen on, default 0.0.0.0")); 73 74 int bindingPort = incSettingsGet("vmc_bind_port", 39540); 75 if (igInputInt(__("Port"), &bindingPort)) { 76 incSettingsSet("vmc_bind_port", bindingPort); 77 78 if (bindingPort > 1 && bindingPort < ushort.max) { 79 incSettingsSave(); 80 optionValues["port"] = bindingPort.text; 81 incTestRestartTracker(); 82 } 83 } 84 incTooltip(_("The port that the VMC binding server should listen on, default 39540")); 85 } 86 87 if (trackingModeCheckbox("VTube Studio", _("A reciever which uses the VTubeStudio iOS app"), TrackingMode.VTS)) { 88 89 string bindingIP = incSettingsGet!string("vts_phone_ip"); 90 if (incInputText(__("iPhone IP"), avail.x/2, bindingIP, ImGuiInputTextFlags.None)) { 91 incSettingsSet("vts_phone_ip", bindingIP); 92 93 if (this.canParseAddr(bindingIP)) { 94 incSettingsSave(); 95 optionValues["phoneIP"] = bindingIP; 96 incTestRestartTracker(); 97 } 98 } 99 incTooltip(_("The IP Address of your iPhone,\nYou can find it in the VSeeFace Config panel in VTube Studio")); 100 } 101 102 if (igCollapsingHeader(__("Tracking Bindings"), ImGuiTreeNodeFlags.DefaultOpen)) { 103 if (igBeginListBox("")) { 104 foreach(i, binding; incTestGetTrackingBindings()) { 105 igPushID(cast(int)i); 106 107 const(char)* nm = _("%s bound to %s").format(binding.key, binding.param.name).toStringz; 108 if (igSelectable(nm)) { 109 incTestRemoveTrackingBinding(binding); 110 } 111 112 igPopID(); 113 } 114 igEndListBox(); 115 } 116 117 if (igButton("", ImVec2(0, 32))) { 118 incPushWindowList(new TrackingBindingWindow(incViewportTestGetCurrBindable())); 119 } 120 } 121 } else { 122 igText(__("Not in Test Mode...")); 123 } 124 } 125 126 public: 127 this() { 128 super("Tracking", _("Tracking"), false); 129 } 130 } 131 132 /** 133 Generate tracking panel frame 134 */ 135 mixin incPanel!TrackingPanel; 136 137