diff --git a/README.md b/README.md
index 97f0787..6a75221 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,7 @@ Merged set of MelonLoader mods for ChilloutVR.
|:---------:|:----------:|:--------------:| :----------------------------------------------------------------|
| [Avatar Motion Tweaker](/ml_amt/README.md) | ml_amt | 1.3.6 [:arrow_down:](../../releases/latest/download/ml_amt.dll)| ✔ Yes
:hourglass: Update review |
| [Avatar Synced Look](/ml_asl/README.md) | ml_asl | 1.0.0 [:arrow_down:](../../releases/latest/download/ml_asl.dll)| ✔ Yes |
+| [Desktop Head Tracking](/ml_dht/README.md) | ml_dht | 1.2.0 [:arrow_down:](../../releases/latest/download/ml_dht.dll) | ✔ Yes (`Retired` group)
:hourglass: Update review |
| [Leap Motion Extension](/ml_lme/README.md)| ml_lme | 1.4.5 [:arrow_down:](../../releases/latest/download/ml_lme.dll)| ✔ Yes |
| [Pickup Arm Movement](/ml_pam/README.md)| ml_pam | 1.0.9 [:arrow_down:](../../releases/latest/download/ml_pam.dll)| ✔ Yes |
| [Player Movement Copycat](/ml_pmc/README.md)| ml_pmc | 1.0.4 [:arrow_down:](../../releases/latest/download/ml_pmc.dll)| ✔ Yes |
@@ -16,7 +17,6 @@ Merged set of MelonLoader mods for ChilloutVR.
| Full name | Short name | Notes |
|:---------:|:----------:|-------|
| Avatar Change Info | ml_aci | Superseded by `Extended Game Notifications` |
-| Desktop Head Tracking | ml_dht | Unable to emulate fake data |
| Desktop Reticle Switch | ml_drs | Boring functionality |
| Extended Game Notifications | ml_egn | In-game feature sine 2023r172 update |
| Four Point Tracking | ml_fpt | In-game feature since 2022r170 update |
diff --git a/archived/ml_dht/resources/menu.js b/archived/ml_dht/resources/menu.js
deleted file mode 100644
index 37727c7..0000000
--- a/archived/ml_dht/resources/menu.js
+++ /dev/null
@@ -1,245 +0,0 @@
-// Add settings
-var g_modSettingsDHT = [];
-
-engine.on('updateModSettingDHT', function (_name, _value) {
- for (var i = 0; i < g_modSettingsDHT.length; i++) {
- if (g_modSettingsDHT[i].name == _name) {
- g_modSettingsDHT[i].updateValue(_value);
- break;
- }
- }
-});
-
-// Modified from original `inp` types, because I have no js knowledge to hook stuff
-function inp_slider_mod_dht(_obj, _callbackName) {
- this.obj = _obj;
- this.callbackName = _callbackName;
- this.minValue = parseFloat(_obj.getAttribute('data-min'));
- this.maxValue = parseFloat(_obj.getAttribute('data-max'));
- this.percent = 0;
- this.value = parseFloat(_obj.getAttribute('data-current'));
- this.dragActive = false;
- this.name = _obj.id;
- this.type = _obj.getAttribute('data-type');
- this.stepSize = _obj.getAttribute('data-stepSize') || 0;
- this.format = _obj.getAttribute('data-format') || '{value}';
-
- var self = this;
-
- if (this.stepSize != 0)
- this.value = Math.round(this.value / this.stepSize) * this.stepSize;
- else
- this.value = Math.round(this.value);
-
- this.valueLabelBackground = document.createElement('div');
- this.valueLabelBackground.className = 'valueLabel background';
- this.valueLabelBackground.innerHTML = this.format.replace('{value}', this.value);
- this.obj.appendChild(this.valueLabelBackground);
-
- this.valueBar = document.createElement('div');
- this.valueBar.className = 'valueBar';
- this.valueBar.setAttribute('style', 'width: ' + (((this.value - this.minValue) / (this.maxValue - this.minValue)) * 100) + '%;');
- this.obj.appendChild(this.valueBar);
-
- this.valueLabelForeground = document.createElement('div');
- this.valueLabelForeground.className = 'valueLabel foreground';
- this.valueLabelForeground.innerHTML = this.format.replace('{value}', this.value);
- this.valueLabelForeground.setAttribute('style', 'width: ' + (1.0 / ((this.value - this.minValue) / (this.maxValue - this.minValue)) * 100) + '%;');
- this.valueBar.appendChild(this.valueLabelForeground);
-
- this.mouseDown = function (_e) {
- self.dragActive = true;
- self.mouseMove(_e, false);
- }
-
- this.mouseMove = function (_e, _write) {
- if (self.dragActive) {
- var rect = _obj.getBoundingClientRect();
- var start = rect.left;
- var end = rect.right;
- self.percent = Math.min(Math.max((_e.clientX - start) / rect.width, 0), 1);
- var value = self.percent;
- value *= (self.maxValue - self.minValue);
- value += self.minValue;
- if (self.stepSize != 0) {
- value = Math.round(value / self.stepSize);
- self.value = value * self.stepSize;
- self.percent = (self.value - self.minValue) / (self.maxValue - self.minValue);
- }
- else
- self.value = Math.round(value);
-
- self.valueBar.setAttribute('style', 'width: ' + (self.percent * 100) + '%;');
- self.valueLabelForeground.setAttribute('style', 'width: ' + (1.0 / self.percent * 100) + '%;');
- self.valueLabelBackground.innerHTML = self.valueLabelForeground.innerHTML = self.format.replace('{value}', self.value);
-
- engine.call(self.callbackName, self.name, "" + self.value);
- self.displayImperial();
- }
- }
-
- this.mouseUp = function (_e) {
- self.mouseMove(_e, true);
- self.dragActive = false;
- }
-
- _obj.addEventListener('mousedown', this.mouseDown);
- document.addEventListener('mousemove', this.mouseMove);
- document.addEventListener('mouseup', this.mouseUp);
-
- this.getValue = function () {
- return self.value;
- }
-
- this.updateValue = function (value) {
- if (self.stepSize != 0)
- self.value = Math.round(value * self.stepSize) / self.stepSize;
- else
- self.value = Math.round(value);
- self.percent = (self.value - self.minValue) / (self.maxValue - self.minValue);
- self.valueBar.setAttribute('style', 'width: ' + (self.percent * 100) + '%;');
- self.valueLabelForeground.setAttribute('style', 'width: ' + (1.0 / self.percent * 100) + '%;');
- self.valueLabelBackground.innerHTML = self.valueLabelForeground.innerHTML = self.format.replace('{value}', self.value);
- self.displayImperial();
- }
-
- this.displayImperial = function () {
- var displays = document.querySelectorAll('.imperialDisplay');
- for (var i = 0; i < displays.length; i++) {
- var binding = displays[i].getAttribute('data-binding');
- if (binding == self.name) {
- var realFeet = ((self.value * 0.393700) / 12);
- var feet = Math.floor(realFeet);
- var inches = Math.floor((realFeet - feet) * 12);
- displays[i].innerHTML = feet + "'" + inches + '''';
- }
- }
- }
-
- return {
- name: this.name,
- value: this.getValue,
- updateValue: this.updateValue
- }
-}
-
-// Modified from original `inp` types, because I have no js knowledge to hook stuff
-function inp_toggle_mod_dht(_obj, _callbackName) {
- this.obj = _obj;
- this.callbackName = _callbackName;
- this.value = _obj.getAttribute('data-current');
- this.name = _obj.id;
- this.type = _obj.getAttribute('data-type');
-
- var self = this;
-
- this.mouseDown = function (_e) {
- self.value = self.value == "True" ? "False" : "True";
- self.updateState();
- }
-
- this.updateState = function () {
- self.obj.classList.remove("checked");
- if (self.value == "True") {
- self.obj.classList.add("checked");
- }
-
- engine.call(self.callbackName, self.name, self.value);
- }
-
- _obj.addEventListener('mousedown', this.mouseDown);
-
- this.getValue = function () {
- return self.value;
- }
-
- this.updateValue = function (value) {
- self.value = value;
-
- self.obj.classList.remove("checked");
- if (self.value == "True") {
- self.obj.classList.add("checked");
- }
- }
-
- this.updateValue(this.value);
-
- return {
- name: this.name,
- value: this.getValue,
- updateValue: this.updateValue
- }
-}
-
-// Add own menu
-{
- let l_block = document.createElement('div');
- l_block.innerHTML = `
-
-
Desktop Head Tracking
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Movement smoothing:
-
-
-
-
-
Override face tracking:
-
-
- `;
- document.getElementById('settings-implementation').appendChild(l_block);
-
- // Update sliders in new menu block
- let l_sliders = l_block.querySelectorAll('.inp_slider');
- for (var i = 0; i < l_sliders.length; i++) {
- g_modSettingsDHT[g_modSettingsDHT.length] = new inp_slider_mod_dht(l_sliders[i], 'MelonMod_DHT_Call_InpSlider');
- }
-
- // Update toggles in new menu block
- let l_toggles = l_block.querySelectorAll('.inp_toggle');
- for (var i = 0; i < l_toggles.length; i++) {
- g_modSettingsDHT[g_modSettingsDHT.length] = new inp_toggle_mod_dht(l_toggles[i], 'MelonMod_DHT_Call_InpToggle');
- }
-}
diff --git a/ml_amt/ml_amt.csproj b/ml_amt/ml_amt.csproj
index df42050..2292594 100644
--- a/ml_amt/ml_amt.csproj
+++ b/ml_amt/ml_amt.csproj
@@ -41,42 +41,52 @@
D:\Games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\0Harmony.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\cohtml.Net.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Cohtml.Runtime.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\MelonLoader.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AnimationModule.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.PhysicsModule.dll
false
+ false
diff --git a/ml_asl/ml_asl.csproj b/ml_asl/ml_asl.csproj
index a80c681..0fc712e 100644
--- a/ml_asl/ml_asl.csproj
+++ b/ml_asl/ml_asl.csproj
@@ -17,30 +17,37 @@
D:\Games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\0Harmony.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\cohtml.Net.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Cohtml.Runtime.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\MelonLoader.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll
false
+ false
diff --git a/archived/ml_dht/.github/img_01.png b/ml_dht/.github/img_01.png
similarity index 100%
rename from archived/ml_dht/.github/img_01.png
rename to ml_dht/.github/img_01.png
diff --git a/archived/ml_dht/HeadTracked.cs b/ml_dht/HeadTracked.cs
similarity index 51%
rename from archived/ml_dht/HeadTracked.cs
rename to ml_dht/HeadTracked.cs
index 915b104..dc27209 100644
--- a/archived/ml_dht/HeadTracked.cs
+++ b/ml_dht/HeadTracked.cs
@@ -1,185 +1,144 @@
-using ABI.CCK.Components;
-using ABI_RC.Core.Player;
-using RootMotion.FinalIK;
-using System.Reflection;
-using UnityEngine;
-using ViveSR.anipal.Lip;
-
-namespace ml_dht
-{
- [DisallowMultipleComponent]
- class HeadTracked : MonoBehaviour
- {
- static FieldInfo ms_emotePlaying = typeof(PlayerSetup).GetField("_emotePlaying", BindingFlags.NonPublic | BindingFlags.Instance);
-
- bool m_enabled = false;
- bool m_headTracking = true;
- bool m_blinking = true;
- bool m_eyeTracking = true;
- float m_smoothing = 0.5f;
- bool m_mirrored = false;
- bool m_faceOverride = true;
-
- CVRAvatar m_avatarDescriptor = null;
- LookAtIK m_lookIK = null;
- Transform m_headBone = null;
-
- Vector3 m_headPosition;
- Quaternion m_headRotation;
- Vector2 m_gazeDirection;
- float m_blinkProgress = 0f;
- Vector2 m_mouthShapes;
- float m_eyebrowsProgress = 0f;
-
- Quaternion m_bindRotation;
- Quaternion m_lastHeadRotation;
-
- // Unity events
- void Start()
- {
- Settings.EnabledChange += this.SetEnabled;
- Settings.HeadTrackingChange += this.SetHeadTracking;
- Settings.EyeTrackingChange += this.SetEyeTracking;
- Settings.BlinkingChange += this.SetBlinking;
- Settings.SmoothingChange += this.SetSmoothing;
- Settings.MirroredChange += this.SetMirrored;
- Settings.FaceOverrideChange += this.SetFaceOverride;
- }
-
- void OnDestroy()
- {
- Settings.EnabledChange -= this.SetEnabled;
- Settings.HeadTrackingChange -= this.SetHeadTracking;
- Settings.EyeTrackingChange -= this.SetEyeTracking;
- Settings.BlinkingChange -= this.SetBlinking;
- Settings.SmoothingChange -= this.SetSmoothing;
- Settings.MirroredChange -= this.SetMirrored;
- Settings.FaceOverrideChange -= this.SetFaceOverride;
- }
-
- // Tracking updates
- public void UpdateTrackingData(ref TrackingData p_data)
- {
- m_headPosition.Set(p_data.m_headPositionX * (m_mirrored ? -1f : 1f), p_data.m_headPositionY, p_data.m_headPositionZ);
- m_headRotation.Set(p_data.m_headRotationX, p_data.m_headRotationY * (m_mirrored ? -1f : 1f), p_data.m_headRotationZ * (m_mirrored ? -1f : 1f), p_data.m_headRotationW);
- m_gazeDirection.Set(m_mirrored ? (1f - p_data.m_gazeX) : p_data.m_gazeX, p_data.m_gazeY);
- m_blinkProgress = p_data.m_blink;
- m_mouthShapes.Set(p_data.m_mouthOpen, p_data.m_mouthShape);
- m_eyebrowsProgress = p_data.m_brows;
- }
-
- void OnLookIKPostUpdate()
- {
- if(m_enabled && m_headTracking && (m_headBone != null))
- {
- m_lastHeadRotation = Quaternion.Slerp(m_lastHeadRotation, m_avatarDescriptor.transform.rotation * (m_headRotation * m_bindRotation), m_smoothing);
-
- if(!(bool)ms_emotePlaying.GetValue(PlayerSetup.Instance))
- m_headBone.rotation = m_lastHeadRotation;
- }
- }
-
- // Game events
- internal void OnEyeControllerUpdate(CVREyeController p_component)
- {
- if(m_enabled)
- {
- // Gaze
- if(m_eyeTracking)
- {
- Transform l_camera = PlayerSetup.Instance.GetActiveCamera().transform;
-
- p_component.manualViewTarget = true;
- p_component.targetViewPosition = l_camera.position + l_camera.rotation * new Vector3((m_gazeDirection.x - 0.5f) * 2f, (m_gazeDirection.y - 0.5f) * 2f, 1f);
- }
-
- // Blink
- if(m_blinking)
- {
- p_component.manualBlinking = true;
- p_component.blinkProgress = m_blinkProgress;
- }
- }
- }
-
- internal void OnFaceTrackingUpdate(CVRFaceTracking p_component)
- {
- if(m_enabled && m_faceOverride)
- {
- if(m_avatarDescriptor != null)
- m_avatarDescriptor.useVisemeLipsync = false;
-
- float l_weight = Mathf.Clamp01(Mathf.InverseLerp(0.25f, 1f, Mathf.Abs(m_mouthShapes.y))) * 100f;
-
- p_component.BlendShapeValues[(int)LipShape_v2.Jaw_Open] = m_mouthShapes.x * 100f;
- p_component.BlendShapeValues[(int)LipShape_v2.Mouth_Pout] = ((m_mouthShapes.y > 0f) ? l_weight : 0f);
- p_component.BlendShapeValues[(int)LipShape_v2.Mouth_Smile_Left] = ((m_mouthShapes.y < 0f) ? l_weight : 0f);
- p_component.BlendShapeValues[(int)LipShape_v2.Mouth_Smile_Right] = ((m_mouthShapes.y < 0f) ? l_weight : 0f);
- p_component.LipSyncWasUpdated = true;
- p_component.UpdateLipShapes();
- }
- }
-
- internal void OnSetupAvatar()
- {
- m_avatarDescriptor = PlayerSetup.Instance._avatar.GetComponent();
- m_headBone = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.Head);
- m_lookIK = PlayerSetup.Instance._avatar.GetComponent();
-
- if(m_headBone != null)
- m_bindRotation = (m_avatarDescriptor.transform.GetMatrix().inverse * m_headBone.GetMatrix()).rotation;
-
- if(m_lookIK != null)
- m_lookIK.solver.OnPostUpdate += this.OnLookIKPostUpdate;
-
- }
- internal void OnAvatarClear()
- {
- m_avatarDescriptor = null;
- m_lookIK = null;
- m_headBone = null;
- m_lastHeadRotation = Quaternion.identity;
- m_bindRotation = Quaternion.identity;
- }
-
- // Settings
- internal void SetEnabled(bool p_state)
- {
- if(m_enabled != p_state)
- {
- m_enabled = p_state;
- if(m_enabled && m_headTracking)
- m_lastHeadRotation = ((m_headBone != null) ? m_headBone.rotation : m_bindRotation);
- }
- }
- internal void SetHeadTracking(bool p_state)
- {
- if(m_headTracking != p_state)
- {
- m_headTracking = p_state;
- if(m_enabled && m_headTracking)
- m_lastHeadRotation = ((m_headBone != null) ? m_headBone.rotation : m_bindRotation);
- }
- }
- internal void SetEyeTracking(bool p_state)
- {
- m_eyeTracking = p_state;
- }
- internal void SetBlinking(bool p_state)
- {
- m_blinking = p_state;
- }
- internal void SetSmoothing(float p_value)
- {
- m_smoothing = 1f - Mathf.Clamp(p_value, 0f, 0.99f);
- }
- internal void SetMirrored(bool p_state)
- {
- m_mirrored = p_state;
- }
- internal void SetFaceOverride(bool p_state)
- {
- m_faceOverride = p_state;
- }
- }
-}
+using ABI.CCK.Components;
+using ABI_RC.Core.Player;
+using RootMotion.FinalIK;
+using System.Reflection;
+using UnityEngine;
+using ViveSR.anipal.Lip;
+
+namespace ml_dht
+{
+ [DisallowMultipleComponent]
+ class HeadTracked : MonoBehaviour
+ {
+ static FieldInfo ms_emotePlaying = typeof(PlayerSetup).GetField("_emotePlaying", BindingFlags.NonPublic | BindingFlags.Instance);
+
+ bool m_enabled = false;
+ bool m_headTracking = true;
+ float m_smoothing = 0.5f;
+
+ CVRAvatar m_avatarDescriptor = null;
+ Transform m_camera = null;
+ LookAtIK m_lookIK = null;
+ Transform m_headBone = null;
+
+ Vector3 m_headPosition;
+ Quaternion m_headRotation;
+ Vector2 m_gazeDirection;
+ float m_blinkProgress = 0f;
+
+ Quaternion m_bindRotation;
+ Quaternion m_lastHeadRotation;
+
+ // Unity events
+ void Start()
+ {
+ SetEnabled(Settings.Enabled);
+ SetHeadTracking(Settings.HeadTracking);
+ SetSmoothing(Settings.Smoothing);
+
+ Settings.EnabledChange += this.SetEnabled;
+ Settings.HeadTrackingChange += this.SetHeadTracking;
+ Settings.SmoothingChange += this.SetSmoothing;
+ }
+
+ void OnDestroy()
+ {
+ Settings.EnabledChange -= this.SetEnabled;
+ Settings.HeadTrackingChange -= this.SetHeadTracking;
+ Settings.SmoothingChange -= this.SetSmoothing;
+ }
+
+ // Tracking updates
+ public void UpdateTrackingData(ref TrackingData p_data)
+ {
+ m_headPosition.Set(p_data.m_headPositionX * (Settings.Mirrored ? -1f : 1f), p_data.m_headPositionY, p_data.m_headPositionZ);
+ m_headRotation.Set(p_data.m_headRotationX, p_data.m_headRotationY * (Settings.Mirrored ? -1f : 1f), p_data.m_headRotationZ * (Settings.Mirrored ? -1f : 1f), p_data.m_headRotationW);
+ m_gazeDirection.Set(Settings.Mirrored ? (1f - p_data.m_gazeX) : p_data.m_gazeX, p_data.m_gazeY);
+ m_blinkProgress = p_data.m_blink;
+ }
+
+ void OnLookIKPostUpdate()
+ {
+ if(m_enabled && m_headTracking && (m_headBone != null))
+ {
+ m_lastHeadRotation = Quaternion.Slerp(m_lastHeadRotation, m_avatarDescriptor.transform.rotation * (m_headRotation * m_bindRotation), m_smoothing);
+
+ if(!(bool)ms_emotePlaying.GetValue(PlayerSetup.Instance))
+ m_headBone.rotation = m_lastHeadRotation;
+ }
+ }
+
+ // Game events
+ internal void OnSetupAvatar()
+ {
+ m_camera = PlayerSetup.Instance.GetActiveCamera().transform;
+ m_avatarDescriptor = PlayerSetup.Instance._avatar.GetComponent();
+ m_headBone = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.Head);
+ m_lookIK = PlayerSetup.Instance._avatar.GetComponent();
+
+ if(m_headBone != null)
+ m_bindRotation = (m_avatarDescriptor.transform.GetMatrix().inverse * m_headBone.GetMatrix()).rotation;
+
+ if(m_lookIK != null)
+ m_lookIK.solver.OnPostUpdate += this.OnLookIKPostUpdate;
+
+ }
+ internal void OnAvatarClear()
+ {
+ m_avatarDescriptor = null;
+ m_lookIK = null;
+ m_headBone = null;
+ m_lastHeadRotation = Quaternion.identity;
+ m_bindRotation = Quaternion.identity;
+ }
+
+ internal void OnEyeControllerUpdate(CVREyeController p_component)
+ {
+ if(m_enabled)
+ {
+ // Gaze
+ if(Settings.EyeTracking && (m_camera != null))
+ {
+ p_component.manualViewTarget = true;
+ p_component.targetViewPosition = m_camera.position + m_camera.rotation * new Vector3((m_gazeDirection.x - 0.5f) * 2f, (m_gazeDirection.y - 0.5f) * 2f, 1f);
+ }
+
+ // Blink
+ if(Settings.Blinking)
+ {
+ p_component.manualBlinking = true;
+ p_component.blinkProgress = m_blinkProgress;
+ }
+ }
+ }
+
+ // Settings
+ void SetEnabled(bool p_state)
+ {
+ if(m_enabled != p_state)
+ {
+ m_enabled = p_state;
+ TryRestoreHeadRotation();
+ }
+ }
+ void SetHeadTracking(bool p_state)
+ {
+ if(m_headTracking != p_state)
+ {
+ m_headTracking = p_state;
+ TryRestoreHeadRotation();
+ }
+ }
+ void SetSmoothing(float p_value)
+ {
+ m_smoothing = 1f - Mathf.Clamp(p_value, 0f, 0.99f);
+ }
+
+ // Arbitrary
+ void TryRestoreHeadRotation()
+ {
+ if(m_enabled && m_headTracking)
+ m_lastHeadRotation = ((m_headBone != null) ? m_headBone.rotation : m_bindRotation);
+ }
+ }
+}
diff --git a/archived/ml_dht/Main.cs b/ml_dht/Main.cs
similarity index 61%
rename from archived/ml_dht/Main.cs
rename to ml_dht/Main.cs
index 4246ff3..beeec86 100644
--- a/archived/ml_dht/Main.cs
+++ b/ml_dht/Main.cs
@@ -1,146 +1,119 @@
-using ABI.CCK.Components;
-using ABI_RC.Core.Player;
-using System.Reflection;
-
-namespace ml_dht
-{
- public class DesktopHeadTracking : MelonLoader.MelonMod
- {
- static DesktopHeadTracking ms_instance = null;
-
- MemoryMapReader m_mapReader = null;
- byte[] m_buffer = null;
- TrackingData m_trackingData;
-
- HeadTracked m_localTracked = null;
-
- public override void OnInitializeMelon()
- {
- if(ms_instance == null)
- ms_instance = this;
-
- Settings.Init();
-
- m_mapReader = new MemoryMapReader();
- m_buffer = new byte[1024];
-
- m_mapReader.Open("head/data");
-
- // Patches
- HarmonyInstance.Patch(
- typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.ClearAvatar)),
- null,
- new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnAvatarClear_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
- );
- HarmonyInstance.Patch(
- typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.SetupAvatar)),
- null,
- new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
- );
- HarmonyInstance.Patch(
- typeof(CVREyeController).GetMethod("Update", BindingFlags.Instance | BindingFlags.NonPublic),
- null,
- new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnEyeControllerUpdate_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
- );
- HarmonyInstance.Patch(
- typeof(CVRFaceTracking).GetMethod("Update", BindingFlags.Instance | BindingFlags.NonPublic),
- null,
- new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnFaceTrackingUpdate_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
- );
-
- MelonLoader.MelonCoroutines.Start(WaitForPlayer());
- }
-
- System.Collections.IEnumerator WaitForPlayer()
- {
- while(PlayerSetup.Instance == null)
- yield return null;
-
- m_localTracked = PlayerSetup.Instance.gameObject.AddComponent();
- m_localTracked.SetEnabled(Settings.Enabled);
- m_localTracked.SetHeadTracking(Settings.HeadTracking);
- m_localTracked.SetEyeTracking(Settings.EyeTracking);
- m_localTracked.SetBlinking(Settings.Blinking);
- m_localTracked.SetMirrored(Settings.Mirrored);
- m_localTracked.SetSmoothing(Settings.Smoothing);
- m_localTracked.SetFaceOverride(Settings.FaceOverride);
- }
-
- public override void OnDeinitializeMelon()
- {
- if(ms_instance == this)
- ms_instance = null;
-
- m_mapReader?.Close();
- m_mapReader = null;
- m_buffer = null;
- m_localTracked = null;
- }
-
- public override void OnUpdate()
- {
- if(Settings.Enabled && m_mapReader.Read(ref m_buffer))
- {
- m_trackingData = TrackingData.ToObject(m_buffer);
- if(m_localTracked != null)
- m_localTracked.UpdateTrackingData(ref m_trackingData);
- }
- }
-
- static void OnSetupAvatar_Postfix() => ms_instance?.OnSetupAvatar();
- void OnSetupAvatar()
- {
- try
- {
- if(m_localTracked != null)
- m_localTracked.OnSetupAvatar();
- }
- catch(System.Exception e)
- {
- MelonLoader.MelonLogger.Error(e);
- }
- }
-
- static void OnAvatarClear_Postfix() => ms_instance?.OnAvatarClear();
- void OnAvatarClear()
- {
- try
- {
- if(m_localTracked != null)
- m_localTracked.OnAvatarClear();
- }
- catch(System.Exception e)
- {
- MelonLoader.MelonLogger.Error(e);
- }
- }
-
- static void OnEyeControllerUpdate_Postfix(ref CVREyeController __instance) => ms_instance?.OnEyeControllerUpdate(__instance);
- void OnEyeControllerUpdate(CVREyeController p_component)
- {
- try
- {
- if(p_component.isLocal && (m_localTracked != null))
- m_localTracked.OnEyeControllerUpdate(p_component);
- }
- catch(System.Exception e)
- {
- MelonLoader.MelonLogger.Error(e);
- }
- }
-
- static void OnFaceTrackingUpdate_Postfix(ref CVRFaceTracking __instance) => ms_instance?.OnFaceTrackingUpdate(__instance);
- void OnFaceTrackingUpdate(CVRFaceTracking p_component)
- {
- try
- {
- if(p_component.isLocal && (m_localTracked != null))
- m_localTracked.OnFaceTrackingUpdate(p_component);
- }
- catch(System.Exception e)
- {
- MelonLoader.MelonLogger.Error(e);
- }
- }
- }
+using ABI_RC.Core.Player;
+using ABI_RC.Core.Savior;
+using ABI_RC.Systems.FaceTracking;
+using System.Reflection;
+
+namespace ml_dht
+{
+ public class DesktopHeadTracking : MelonLoader.MelonMod
+ {
+ static DesktopHeadTracking ms_instance = null;
+
+ TrackingModule m_trackingModule = null;
+ HeadTracked m_localTracked = null;
+
+ public override void OnInitializeMelon()
+ {
+ if(ms_instance == null)
+ ms_instance = this;
+
+ Settings.Init();
+
+ m_trackingModule = new TrackingModule();
+
+ // Patches
+ HarmonyInstance.Patch(
+ typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.ClearAvatar)),
+ null,
+ new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnAvatarClear_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
+ );
+ HarmonyInstance.Patch(
+ typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.SetupAvatar)),
+ null,
+ new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
+ );
+
+ MelonLoader.MelonCoroutines.Start(WaitForInstances());
+ }
+
+ System.Collections.IEnumerator WaitForInstances()
+ {
+ while(MetaPort.Instance == null)
+ yield return null;
+
+ while(PlayerSetup.Instance == null)
+ yield return null;
+
+ m_localTracked = PlayerSetup.Instance.gameObject.AddComponent();
+ FaceTrackingManager.Instance.RegisterModule(m_trackingModule);
+
+ // If you think it's a joke to put patch here, go on, try to put it in OnInitializeMelon, you melon :>
+ HarmonyInstance.Patch(
+ typeof(CVREyeController).GetMethod("Update", BindingFlags.Instance | BindingFlags.NonPublic),
+ null,
+ new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnEyeControllerUpdate_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
+ );
+ }
+
+ public override void OnDeinitializeMelon()
+ {
+ if(ms_instance == this)
+ ms_instance = null;
+
+ m_trackingModule = null;
+ m_localTracked = null;
+ }
+
+ public override void OnUpdate()
+ {
+ if(Settings.Enabled && (m_trackingModule != null))
+ {
+ m_trackingModule.Update();
+ if(m_localTracked != null)
+ m_localTracked.UpdateTrackingData(ref m_trackingModule.GetLatestTrackingData());
+ }
+ }
+
+ static void OnSetupAvatar_Postfix() => ms_instance?.OnSetupAvatar();
+ void OnSetupAvatar()
+ {
+ try
+ {
+ if(m_localTracked != null)
+ m_localTracked.OnSetupAvatar();
+ }
+ catch(System.Exception e)
+ {
+ MelonLoader.MelonLogger.Error(e);
+ }
+ }
+
+ static void OnAvatarClear_Postfix() => ms_instance?.OnAvatarClear();
+ void OnAvatarClear()
+ {
+ try
+ {
+ if(m_localTracked != null)
+ m_localTracked.OnAvatarClear();
+ }
+ catch(System.Exception e)
+ {
+ MelonLoader.MelonLogger.Error(e);
+ }
+ }
+
+ static void OnEyeControllerUpdate_Postfix(ref CVREyeController __instance) => ms_instance?.OnEyeControllerUpdate(__instance);
+ void OnEyeControllerUpdate(CVREyeController p_component)
+ {
+ try
+ {
+ if(p_component.isLocal && (m_localTracked != null))
+ m_localTracked.OnEyeControllerUpdate(p_component);
+ }
+ catch(System.Exception e)
+ {
+ MelonLoader.MelonLogger.Error(e);
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/archived/ml_dht/MemoryMapReader.cs b/ml_dht/MemoryMapReader.cs
similarity index 100%
rename from archived/ml_dht/MemoryMapReader.cs
rename to ml_dht/MemoryMapReader.cs
diff --git a/archived/ml_dht/Properties/AssemblyInfo.cs b/ml_dht/Properties/AssemblyInfo.cs
similarity index 77%
rename from archived/ml_dht/Properties/AssemblyInfo.cs
rename to ml_dht/Properties/AssemblyInfo.cs
index 5982313..dbe24dc 100644
--- a/archived/ml_dht/Properties/AssemblyInfo.cs
+++ b/ml_dht/Properties/AssemblyInfo.cs
@@ -1,4 +1,4 @@
-[assembly: MelonLoader.MelonInfo(typeof(ml_dht.DesktopHeadTracking), "DesktopHeadTracking", "1.1.2-ex", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
-[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
-[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
+[assembly: MelonLoader.MelonInfo(typeof(ml_dht.DesktopHeadTracking), "DesktopHeadTracking", "1.2.0", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
+[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
+[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
\ No newline at end of file
diff --git a/archived/ml_dht/README.md b/ml_dht/README.md
similarity index 74%
rename from archived/ml_dht/README.md
rename to ml_dht/README.md
index 4388afb..7057fd6 100644
--- a/archived/ml_dht/README.md
+++ b/ml_dht/README.md
@@ -1,29 +1,31 @@
-# Desktop Head Tracking
-This mod adds desktop head tracking based on data from memory-mapped file `head/data`.
-Refer to `TrackingData.cs` for reference in case of implementing own software.
-
-[![](.github/img_01.png)](https://youtu.be/jgcFhSNi9DM)
-
-# Features
-* Head rotation
-* Eyes gaze direction
-* Blinking
-* Basic mouth shapes
-
-# Installation
-* Install [latest MelonLoader](https://github.com/LavaGang/MelonLoader)
-* Get [latest release DLL](../../../releases/latest):
- * Put `ml_dht.dll` in `Mods` folder of game
-
-# Usage
-Available mod's settings in `Settings - Implementation - Desktop Head Tracking`:
-* **Enabled:** enables mod's activity; default value - `false`.
-* **Use head tracking:** enables head tracking; default value - `true`.
-* **Use eyes tracking:** uses eyes tracking from data; default value - `true`.
-* **Use blinking:** uses blinking from data; default value - `true`.
-* **Mirrored movement:** mirrors movement and gaze along 0YZ plane; default value - `false`.
-* **Movement smoothing:** smoothing factor between new and old movement data; default value - `50`.
-* **Override face tracking:** overrides and activates avatar's `VRC Face Tracking` components. List of used shapes: `Jaw_Open`, `Mouth_Pout`, `Mouth_Smile_Left`, `Mouth_Smile_Right`; default value - `true`.
-
-# Known compatible tracking software
-* [VSeeFace](https://www.vseeface.icu) with [Tracking Data Parser mod](https://github.com/SDraw/ml_mods_vsf)
+# Desktop Head Tracking
+This mod adds desktop head tracking based on data from memory-mapped file `head/data`.
+Refer to `TrackingData.cs` for reference in case of implementing own software.
+
+[![](.github/img_01.png)](https://youtu.be/jgcFhSNi9DM)
+
+# Features
+* Head rotation
+* Eyes gaze direction
+* Basic mouth shapes: open, smile and pout
+* Blinking
+
+# Installation
+* Install [latest MelonLoader](https://github.com/LavaGang/MelonLoader)
+* Get [latest release DLL](../../../releases/latest):
+ * Put `ml_dht.dll` in `Mods` folder of game
+
+# Usage
+Available mod's settings in `Settings - Implementation - Desktop Head Tracking`:
+* **Enabled:** enables mod's activity; default value - `false`.
+* **Use head tracking:** enables head tracking; default value - `true`.
+* **Use eyes tracking:** enables eyes tracking; default value - `true`.
+* **Use face tracking:** enables mouth shapes tracking; default value - `true`.
+ * **Note:** You need to enable desktop tracking of `Vive Face tracking` in `Settings - Implementation` menu page.
+ * **Note:** Your avatar should have configured `CVR Face Tracking` component.
+* **Use blinking:** uses blinking from data; default value - `true`.
+* **Mirrored movement:** mirrors movement and gaze along 0YZ plane; default value - `false`.
+* **Movement smoothing:** smoothing factor between new and old movement data; default value - `50`.
+
+# Known compatible tracking software
+* [VSeeFace](https://www.vseeface.icu) with [Tracking Data Parser mod](https://github.com/SDraw/ml_mods_vsf)
diff --git a/archived/ml_dht/Scripts.cs b/ml_dht/ResourcesHandler.cs
similarity index 85%
rename from archived/ml_dht/Scripts.cs
rename to ml_dht/ResourcesHandler.cs
index 0b1ccaf..b7c0553 100644
--- a/archived/ml_dht/Scripts.cs
+++ b/ml_dht/ResourcesHandler.cs
@@ -1,26 +1,26 @@
-using System;
-using System.IO;
-using System.Reflection;
-
-namespace ml_dht
-{
- static class Scripts
- {
- public static string GetEmbeddedScript(string p_name)
- {
- string l_result = "";
- Assembly l_assembly = Assembly.GetExecutingAssembly();
- string l_assemblyName = l_assembly.GetName().Name;
-
- try
- {
- Stream l_libraryStream = l_assembly.GetManifestResourceStream(l_assemblyName + ".resources." + p_name);
- StreamReader l_streadReader = new StreamReader(l_libraryStream);
- l_result = l_streadReader.ReadToEnd();
- }
- catch(Exception) { }
-
- return l_result;
- }
- }
-}
+using System;
+using System.IO;
+using System.Reflection;
+
+namespace ml_dht
+{
+ static class ResourcesHandler
+ {
+ public static string GetEmbeddedResource(string p_name)
+ {
+ string l_result = "";
+ Assembly l_assembly = Assembly.GetExecutingAssembly();
+ string l_assemblyName = l_assembly.GetName().Name;
+
+ try
+ {
+ Stream l_libraryStream = l_assembly.GetManifestResourceStream(l_assemblyName + ".resources." + p_name);
+ StreamReader l_streadReader = new StreamReader(l_libraryStream);
+ l_result = l_streadReader.ReadToEnd();
+ }
+ catch(Exception) { }
+
+ return l_result;
+ }
+ }
+}
diff --git a/archived/ml_dht/Settings.cs b/ml_dht/Settings.cs
similarity index 84%
rename from archived/ml_dht/Settings.cs
rename to ml_dht/Settings.cs
index db21eef..60bd767 100644
--- a/archived/ml_dht/Settings.cs
+++ b/ml_dht/Settings.cs
@@ -1,163 +1,160 @@
-using ABI_RC.Core.InteractionSystem;
-using System;
-using System.Collections.Generic;
-
-namespace ml_dht
-{
- static class Settings
- {
- enum ModSetting
- {
- Enabled = 0,
- HeadTracking,
- EyeTracking,
- Blinking,
- Mirrored,
- Smoothing,
- FaceOverride
- }
-
- public static bool Enabled { get; private set; } = false;
- public static bool HeadTracking { get; private set; } = true;
- public static bool EyeTracking { get; private set; } = true;
- public static bool Blinking { get; private set; } = true;
- public static bool Mirrored { get; private set; } = false;
- public static float Smoothing { get; private set; } = 0.5f;
- public static bool FaceOverride { get; private set; } = true;
-
- static MelonLoader.MelonPreferences_Category ms_category = null;
- static List ms_entries = null;
-
- static public event Action EnabledChange;
- static public event Action HeadTrackingChange;
- static public event Action EyeTrackingChange;
- static public event Action BlinkingChange;
- static public event Action MirroredChange;
- static public event Action SmoothingChange;
- static public event Action FaceOverrideChange;
-
- internal static void Init()
- {
- ms_category = MelonLoader.MelonPreferences.CreateCategory("DHT");
-
- ms_entries = new List()
- {
- ms_category.CreateEntry(ModSetting.Enabled.ToString(), Enabled),
- ms_category.CreateEntry(ModSetting.HeadTracking.ToString(), HeadTracking),
- ms_category.CreateEntry(ModSetting.EyeTracking.ToString(), EyeTracking),
- ms_category.CreateEntry(ModSetting.Blinking.ToString(), Blinking),
- ms_category.CreateEntry(ModSetting.Mirrored.ToString(), Mirrored),
- ms_category.CreateEntry(ModSetting.Smoothing.ToString(), (int)(Smoothing * 50f)),
- ms_category.CreateEntry(ModSetting.FaceOverride.ToString(), FaceOverride)
- };
-
- Load();
-
- MelonLoader.MelonCoroutines.Start(WaitMainMenuUi());
- }
-
- static System.Collections.IEnumerator WaitMainMenuUi()
- {
- while(ViewManager.Instance == null)
- yield return null;
- while(ViewManager.Instance.gameMenuView == null)
- yield return null;
- while(ViewManager.Instance.gameMenuView.Listener == null)
- yield return null;
-
- ViewManager.Instance.gameMenuView.Listener.ReadyForBindings += () =>
- {
- ViewManager.Instance.gameMenuView.View.BindCall("MelonMod_DHT_Call_InpSlider", new Action(OnSliderUpdate));
- ViewManager.Instance.gameMenuView.View.BindCall("MelonMod_DHT_Call_InpToggle", new Action(OnToggleUpdate));
- };
- ViewManager.Instance.gameMenuView.Listener.FinishLoad += (_) =>
- {
- ViewManager.Instance.gameMenuView.View.ExecuteScript(Scripts.GetEmbeddedScript("menu.js"));
- foreach(var l_entry in ms_entries)
- ViewManager.Instance.gameMenuView.View.TriggerEvent("updateModSettingDHT", l_entry.DisplayName, l_entry.GetValueAsString());
- };
- }
-
- static void Load()
- {
- Enabled = (bool)ms_entries[(int)ModSetting.Enabled].BoxedValue;
- HeadTracking = (bool)ms_entries[(int)ModSetting.HeadTracking].BoxedValue;
- EyeTracking = (bool)ms_entries[(int)ModSetting.EyeTracking].BoxedValue;
- Blinking = (bool)ms_entries[(int)ModSetting.Blinking].BoxedValue;
- Mirrored = (bool)ms_entries[(int)ModSetting.Mirrored].BoxedValue;
- Smoothing = ((int)ms_entries[(int)ModSetting.Smoothing].BoxedValue) * 0.01f;
- FaceOverride = (bool)ms_entries[(int)ModSetting.FaceOverride].BoxedValue;
- }
-
- static void OnSliderUpdate(string p_name, string p_value)
- {
- if(Enum.TryParse(p_name, out ModSetting l_setting))
- {
- switch(l_setting)
- {
- case ModSetting.Smoothing:
- {
- Smoothing = int.Parse(p_value) * 0.01f;
- SmoothingChange?.Invoke(Smoothing);
- }
- break;
- }
-
- ms_entries[(int)l_setting].BoxedValue = int.Parse(p_value);
- }
- }
-
- static void OnToggleUpdate(string p_name, string p_value)
- {
- if(Enum.TryParse(p_name, out ModSetting l_setting))
- {
- switch(l_setting)
- {
- case ModSetting.Enabled:
- {
- Enabled = bool.Parse(p_value);
- EnabledChange?.Invoke(Enabled);
- }
- break;
-
- case ModSetting.HeadTracking:
- {
- HeadTracking = bool.Parse(p_value);
- HeadTrackingChange?.Invoke(HeadTracking);
- }
- break;
-
- case ModSetting.EyeTracking:
- {
- EyeTracking = bool.Parse(p_value);
- EyeTrackingChange?.Invoke(EyeTracking);
- }
- break;
-
- case ModSetting.Blinking:
- {
- Blinking = bool.Parse(p_value);
- BlinkingChange?.Invoke(Blinking);
- }
- break;
-
- case ModSetting.Mirrored:
- {
- Mirrored = bool.Parse(p_value);
- MirroredChange?.Invoke(Mirrored);
- }
- break;
-
- case ModSetting.FaceOverride:
- {
- FaceOverride = bool.Parse(p_value);
- FaceOverrideChange?.Invoke(FaceOverride);
- }
- break;
- }
-
- ms_entries[(int)l_setting].BoxedValue = bool.Parse(p_value);
- }
- }
- }
-}
+using ABI_RC.Core.InteractionSystem;
+using System;
+using System.Collections.Generic;
+
+namespace ml_dht
+{
+ static class Settings
+ {
+ enum ModSetting
+ {
+ Enabled = 0,
+ HeadTracking,
+ EyeTracking,
+ FaceTracking,
+ Blinking,
+ Mirrored,
+ Smoothing,
+ }
+
+ public static bool Enabled { get; private set; } = false;
+ public static bool HeadTracking { get; private set; } = true;
+ public static bool EyeTracking { get; private set; } = true;
+ public static bool FaceTracking { get; private set; } = true;
+ public static bool Blinking { get; private set; } = true;
+ public static bool Mirrored { get; private set; } = false;
+ public static float Smoothing { get; private set; } = 0.5f;
+
+ static MelonLoader.MelonPreferences_Category ms_category = null;
+ static List ms_entries = null;
+
+ static public event Action EnabledChange;
+ static public event Action HeadTrackingChange;
+ static public event Action EyeTrackingChange;
+ static public event Action FaceTrackingChange;
+ static public event Action BlinkingChange;
+ static public event Action MirroredChange;
+ static public event Action SmoothingChange;
+
+
+ internal static void Init()
+ {
+ ms_category = MelonLoader.MelonPreferences.CreateCategory("DHT");
+
+ ms_entries = new List()
+ {
+ ms_category.CreateEntry(ModSetting.Enabled.ToString(), Enabled),
+ ms_category.CreateEntry(ModSetting.HeadTracking.ToString(), HeadTracking),
+ ms_category.CreateEntry(ModSetting.EyeTracking.ToString(), EyeTracking),
+ ms_category.CreateEntry(ModSetting.FaceTracking.ToString(), FaceTracking),
+ ms_category.CreateEntry(ModSetting.Blinking.ToString(), Blinking),
+ ms_category.CreateEntry(ModSetting.Mirrored.ToString(), Mirrored),
+ ms_category.CreateEntry(ModSetting.Smoothing.ToString(), (int)(Smoothing * 50f)),
+ };
+
+ Enabled = (bool)ms_entries[(int)ModSetting.Enabled].BoxedValue;
+ HeadTracking = (bool)ms_entries[(int)ModSetting.HeadTracking].BoxedValue;
+ EyeTracking = (bool)ms_entries[(int)ModSetting.EyeTracking].BoxedValue;
+ FaceTracking = (bool)ms_entries[(int)ModSetting.FaceTracking].BoxedValue;
+ Blinking = (bool)ms_entries[(int)ModSetting.Blinking].BoxedValue;
+ Mirrored = (bool)ms_entries[(int)ModSetting.Mirrored].BoxedValue;
+ Smoothing = ((int)ms_entries[(int)ModSetting.Smoothing].BoxedValue) * 0.01f;
+
+ MelonLoader.MelonCoroutines.Start(WaitMainMenuUi());
+ }
+
+ static System.Collections.IEnumerator WaitMainMenuUi()
+ {
+ while(ViewManager.Instance == null)
+ yield return null;
+ while(ViewManager.Instance.gameMenuView == null)
+ yield return null;
+ while(ViewManager.Instance.gameMenuView.Listener == null)
+ yield return null;
+
+ ViewManager.Instance.gameMenuView.Listener.ReadyForBindings += () =>
+ {
+ ViewManager.Instance.gameMenuView.View.BindCall("OnToggleUpdate_" + ms_category.Identifier, new Action(OnToggleUpdate));
+ ViewManager.Instance.gameMenuView.View.BindCall("OnSliderUpdate_" + ms_category.Identifier, new Action(OnSliderUpdate));
+ };
+ ViewManager.Instance.gameMenuView.Listener.FinishLoad += (_) =>
+ {
+ ViewManager.Instance.gameMenuView.View.ExecuteScript(ResourcesHandler.GetEmbeddedResource("mods_extension.js"));
+ ViewManager.Instance.gameMenuView.View.ExecuteScript(ResourcesHandler.GetEmbeddedResource("mod_menu.js"));
+ foreach(var l_entry in ms_entries)
+ ViewManager.Instance.gameMenuView.View.TriggerEvent("updateModSetting", ms_category.Identifier, l_entry.DisplayName, l_entry.GetValueAsString());
+ };
+ }
+
+ static void OnSliderUpdate(string p_name, string p_value)
+ {
+ if(Enum.TryParse(p_name, out ModSetting l_setting))
+ {
+ switch(l_setting)
+ {
+ case ModSetting.Smoothing:
+ {
+ Smoothing = int.Parse(p_value) * 0.01f;
+ SmoothingChange?.Invoke(Smoothing);
+ }
+ break;
+ }
+
+ ms_entries[(int)l_setting].BoxedValue = int.Parse(p_value);
+ }
+ }
+
+ static void OnToggleUpdate(string p_name, string p_value)
+ {
+ if(Enum.TryParse(p_name, out ModSetting l_setting))
+ {
+ switch(l_setting)
+ {
+ case ModSetting.Enabled:
+ {
+ Enabled = bool.Parse(p_value);
+ EnabledChange?.Invoke(Enabled);
+ }
+ break;
+
+ case ModSetting.HeadTracking:
+ {
+ HeadTracking = bool.Parse(p_value);
+ HeadTrackingChange?.Invoke(HeadTracking);
+ }
+ break;
+
+ case ModSetting.EyeTracking:
+ {
+ EyeTracking = bool.Parse(p_value);
+ EyeTrackingChange?.Invoke(EyeTracking);
+ }
+ break;
+
+ case ModSetting.FaceTracking:
+ {
+ FaceTracking = bool.Parse(p_value);
+ FaceTrackingChange?.Invoke(FaceTracking);
+ }
+ break;
+
+ case ModSetting.Blinking:
+ {
+ Blinking = bool.Parse(p_value);
+ BlinkingChange?.Invoke(Blinking);
+ }
+ break;
+
+ case ModSetting.Mirrored:
+ {
+ Mirrored = bool.Parse(p_value);
+ MirroredChange?.Invoke(Mirrored);
+ }
+ break;
+ }
+
+ ms_entries[(int)l_setting].BoxedValue = bool.Parse(p_value);
+ }
+ }
+ }
+}
diff --git a/archived/ml_dht/TrackingData.cs b/ml_dht/TrackingData.cs
similarity index 100%
rename from archived/ml_dht/TrackingData.cs
rename to ml_dht/TrackingData.cs
diff --git a/ml_dht/TrackingModule.cs b/ml_dht/TrackingModule.cs
new file mode 100644
index 0000000..01d1f5c
--- /dev/null
+++ b/ml_dht/TrackingModule.cs
@@ -0,0 +1,70 @@
+using ABI_RC.Systems.FaceTracking;
+using System;
+using UnityEngine;
+using ViveSR.anipal.Lip;
+
+namespace ml_dht
+{
+ class TrackingModule : ITrackingModule
+ {
+ bool m_registered = false;
+ bool m_activeAsModule = false;
+ MemoryMapReader m_mapReader = null;
+ byte[] m_buffer = null;
+ TrackingData m_trackingData;
+ LipData_v2 m_lipData;
+
+ public TrackingModule()
+ {
+ m_lipData = new LipData_v2();
+ m_lipData.frame = 0;
+ m_lipData.time = 0;
+ m_lipData.image = IntPtr.Zero;
+ m_lipData.prediction_data = new PredictionData_v2();
+ m_lipData.prediction_data.blend_shape_weight = new float[(int)LipShape_v2.Max];
+
+ m_buffer = new byte[1024];
+ m_mapReader = new MemoryMapReader();
+ m_mapReader.Open("head/data");
+ }
+ ~TrackingModule()
+ {
+ m_mapReader.Close();
+ m_mapReader = null;
+ }
+
+ public (bool, bool) Initialize(bool useEye, bool useLip)
+ {
+ m_registered = true;
+ m_activeAsModule = true;
+ return (false, true);
+ }
+
+ public void Shutdown()
+ {
+ m_activeAsModule = false;
+ }
+
+ public bool IsEyeDataAvailable() => false;
+ public bool IsLipDataAvailable() => true;
+
+ internal void Update()
+ {
+ if(m_mapReader.Read(ref m_buffer))
+ {
+ m_trackingData = TrackingData.ToObject(m_buffer);
+
+ float l_weight = Mathf.Clamp01(Mathf.InverseLerp(0.25f, 1f, Mathf.Abs(m_trackingData.m_mouthShape)));
+ m_lipData.prediction_data.blend_shape_weight[(int)LipShape_v2.Jaw_Open] = m_trackingData.m_mouthOpen;
+ m_lipData.prediction_data.blend_shape_weight[(int)LipShape_v2.Mouth_Pout] = ((m_trackingData.m_mouthShape > 0f) ? l_weight : 0f);
+ m_lipData.prediction_data.blend_shape_weight[(int)LipShape_v2.Mouth_Smile_Left] = ((m_trackingData.m_mouthShape < 0f) ? l_weight : 0f);
+ m_lipData.prediction_data.blend_shape_weight[(int)LipShape_v2.Mouth_Smile_Right] = ((m_trackingData.m_mouthShape < 0f) ? l_weight : 0f);
+
+ if(m_registered && m_activeAsModule && Settings.FaceTracking)
+ FaceTrackingManager.Instance.SubmitNewFacialData(m_lipData);
+ }
+ }
+
+ internal ref TrackingData GetLatestTrackingData() => ref m_trackingData;
+ }
+}
diff --git a/archived/ml_dht/Utils.cs b/ml_dht/Utils.cs
similarity index 57%
rename from archived/ml_dht/Utils.cs
rename to ml_dht/Utils.cs
index bf8f374..d835fca 100644
--- a/archived/ml_dht/Utils.cs
+++ b/ml_dht/Utils.cs
@@ -1,18 +1,18 @@
-using ABI_RC.Core.UI;
-using System.Reflection;
-using UnityEngine;
-
-namespace ml_dht
-{
- static class Utils
- {
- static FieldInfo ms_cohtmlView = typeof(CohtmlControlledViewDisposable).GetField("_view", BindingFlags.NonPublic | BindingFlags.Instance);
-
- public static Matrix4x4 GetMatrix(this Transform p_transform, bool p_pos = true, bool p_rot = true, bool p_scl = false)
- {
- return Matrix4x4.TRS(p_pos ? p_transform.position : Vector3.zero, p_rot ? p_transform.rotation : Quaternion.identity, p_scl ? p_transform.localScale : Vector3.one);
- }
-
- public static void ExecuteScript(this CohtmlControlledViewDisposable p_viewDisposable, string p_script) => ((cohtml.Net.View)ms_cohtmlView.GetValue(p_viewDisposable))?.ExecuteScript(p_script);
- }
-}
+using ABI_RC.Core.UI;
+using System.Reflection;
+using UnityEngine;
+
+namespace ml_dht
+{
+ static class Utils
+ {
+ static readonly FieldInfo ms_view = typeof(CohtmlControlledViewWrapper).GetField("_view", BindingFlags.NonPublic | BindingFlags.Instance);
+
+ static public void ExecuteScript(this CohtmlControlledViewWrapper p_instance, string p_script) => ((cohtml.Net.View)ms_view.GetValue(p_instance)).ExecuteScript(p_script);
+
+ public static Matrix4x4 GetMatrix(this Transform p_transform, bool p_pos = true, bool p_rot = true, bool p_scl = false)
+ {
+ return Matrix4x4.TRS(p_pos ? p_transform.position : Vector3.zero, p_rot ? p_transform.rotation : Quaternion.identity, p_scl ? p_transform.localScale : Vector3.one);
+ }
+ }
+}
diff --git a/archived/ml_dht/ml_dht.csproj b/ml_dht/ml_dht.csproj
similarity index 77%
rename from archived/ml_dht/ml_dht.csproj
rename to ml_dht/ml_dht.csproj
index 5bed49c..fb08a1e 100644
--- a/archived/ml_dht/ml_dht.csproj
+++ b/ml_dht/ml_dht.csproj
@@ -1,71 +1,84 @@
-
-
-
- netstandard2.1
- DesktopHeadTracking
- SDraw
- None
- DesktopHeadTracking
- 1.1.2
- x64
-
-
-
- x64
- none
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
- D:\games\Steam\steamapps\common\ChilloutVR\MelonLoader\0Harmony.dll
- false
-
-
- D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll
- false
-
-
- D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll
- false
-
-
- D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\cohtml.Net.dll
- false
-
-
- D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Cohtml.Runtime.dll
- false
-
-
- D:\games\Steam\steamapps\common\ChilloutVR\MelonLoader\MelonLoader.dll
- false
-
-
- D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.dll
- false
-
-
- D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AnimationModule.dll
- false
-
-
- D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll
- false
-
-
-
-
-
-
-
-
+
+
+
+ netstandard2.1
+ DesktopHeadTracking
+ SDraw
+ None
+ DesktopHeadTracking
+ 1.2.0
+ x64
+
+
+
+ x64
+ none
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ D:\games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\0Harmony.dll
+ false
+ false
+
+
+ D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll
+ false
+ false
+
+
+ D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll
+ false
+ false
+
+
+ D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\cohtml.Net.dll
+ false
+ false
+
+
+ D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Cohtml.Runtime.dll
+ false
+ false
+
+
+ D:\games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\MelonLoader.dll
+ false
+ false
+
+
+ D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.dll
+ false
+ false
+
+
+ D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AnimationModule.dll
+ false
+ false
+
+
+ D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll
+ false
+ false
+
+
+
+
+
+
+
+
diff --git a/ml_dht/resources/mod_menu.js b/ml_dht/resources/mod_menu.js
new file mode 100644
index 0000000..e52b0ff
--- /dev/null
+++ b/ml_dht/resources/mod_menu.js
@@ -0,0 +1,70 @@
+// Add own menu
+{
+ let l_block = document.createElement('div');
+ l_block.innerHTML = `
+
+
Desktop Head Tracking
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Movement smoothing:
+
+
+
+
+ `;
+ document.getElementById('settings-implementation').appendChild(l_block);
+
+ // Toggles
+ for (let l_toggle of l_block.querySelectorAll('.inp_toggle'))
+ modsExtension.addSetting('DHT', l_toggle.id, modsExtension.createToggle(l_toggle, 'OnToggleUpdate_DHT'));
+
+ // Sliders
+ for (let l_slider of l_block.querySelectorAll('.inp_slider'))
+ modsExtension.addSetting('DHT', l_slider.id, modsExtension.createSlider(l_slider, 'OnSliderUpdate_DHT'));
+}
diff --git a/ml_lme/ml_lme.csproj b/ml_lme/ml_lme.csproj
index 089c7cd..793413b 100644
--- a/ml_lme/ml_lme.csproj
+++ b/ml_lme/ml_lme.csproj
@@ -41,50 +41,62 @@
D:\Games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\0Harmony.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\cohtml.Net.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Cohtml.Runtime.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\MelonLoader.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\Mods\ml_pmc.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AnimationModule.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AssetBundleModule.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.XRModule.dll
false
+ false
diff --git a/ml_mods_cvr.sln b/ml_mods_cvr.sln
index 35b3cf5..573d2e1 100644
--- a/ml_mods_cvr.sln
+++ b/ml_mods_cvr.sln
@@ -18,9 +18,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_vei", "ml_vei\ml_vei.csp
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_prm", "ml_prm\ml_prm.csproj", "{C4C3F080-379F-49DB-ADC6-6328BE884AE3}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ml_asl", "ml_asl\ml_asl.csproj", "{5B4EC6EF-541A-47D2-B602-915205590553}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_asl", "ml_asl\ml_asl.csproj", "{5B4EC6EF-541A-47D2-B602-915205590553}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ml_pin", "ml_pin\ml_pin.csproj", "{7E493C28-7202-46F8-9789-D6C6FF7E5241}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_pin", "ml_pin\ml_pin.csproj", "{7E493C28-7202-46F8-9789-D6C6FF7E5241}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_dht", "ml_dht\ml_dht.csproj", "{31987392-989C-40C1-A48B-7F6099816EBE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -54,6 +56,10 @@ Global
{7E493C28-7202-46F8-9789-D6C6FF7E5241}.Debug|x64.ActiveCfg = Debug|x64
{7E493C28-7202-46F8-9789-D6C6FF7E5241}.Release|x64.ActiveCfg = Release|x64
{7E493C28-7202-46F8-9789-D6C6FF7E5241}.Release|x64.Build.0 = Release|x64
+ {31987392-989C-40C1-A48B-7F6099816EBE}.Debug|x64.ActiveCfg = Debug|x64
+ {31987392-989C-40C1-A48B-7F6099816EBE}.Debug|x64.Build.0 = Debug|x64
+ {31987392-989C-40C1-A48B-7F6099816EBE}.Release|x64.ActiveCfg = Release|x64
+ {31987392-989C-40C1-A48B-7F6099816EBE}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/ml_pam/ml_pam.csproj b/ml_pam/ml_pam.csproj
index 7a42043..901ce8b 100644
--- a/ml_pam/ml_pam.csproj
+++ b/ml_pam/ml_pam.csproj
@@ -32,42 +32,52 @@
D:\games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\0Harmony.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\cohtml.Net.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Cohtml.Runtime.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\MelonLoader.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AnimationModule.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.InputLegacyModule.dll
false
+ false
diff --git a/ml_pin/ml_pin.csproj b/ml_pin/ml_pin.csproj
index 83a6959..150b487 100644
--- a/ml_pin/ml_pin.csproj
+++ b/ml_pin/ml_pin.csproj
@@ -30,42 +30,52 @@
D:\Games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\0Harmony.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\cohtml.Net.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Cohtml.Runtime.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\MelonLoader.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AudioModule.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.UnityWebRequestModule.dll
false
+ false
diff --git a/ml_pmc/ml_pmc.csproj b/ml_pmc/ml_pmc.csproj
index 9bf36de..9be3650 100644
--- a/ml_pmc/ml_pmc.csproj
+++ b/ml_pmc/ml_pmc.csproj
@@ -28,38 +28,47 @@
D:\games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\0Harmony.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\Mods\BTKUILib.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\MelonLoader.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AnimationModule.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.PhysicsModule.dll
false
+ false
diff --git a/ml_prm/ml_prm.csproj b/ml_prm/ml_prm.csproj
index 4eb706f..6c579ab 100644
--- a/ml_prm/ml_prm.csproj
+++ b/ml_prm/ml_prm.csproj
@@ -24,50 +24,62 @@
D:\games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\0Harmony.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\Mods\BTKUILib.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\MelonLoader.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AnimationModule.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.ClothModule.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.InputLegacyModule.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.PhysicsModule.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.ParticleSystemModule.dll
false
+ false
diff --git a/ml_vei/ml_vei.csproj b/ml_vei/ml_vei.csproj
index 10674f2..d55a724 100644
--- a/ml_vei/ml_vei.csproj
+++ b/ml_vei/ml_vei.csproj
@@ -19,38 +19,47 @@
D:\games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\0Harmony.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\cohtml.Net.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Cohtml.Runtime.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\MelonLoader.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Unity.Postprocessing.Runtime.dll
false
+ false
D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AnimationModule.dll
false
+ false
D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll
false
+ false