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
-
-
- -
-
Enabled:
-
-
-
-
- -
-
Use head tracking:
-
-
-
-
- -
-
Use eyes tracking:
-
-
-
-
- -
-
Use blinking:
-
-
-
-
- -
-
Mirrored movement:
-
-
-
-
- -
-
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
+
+
+ +
+
Enabled:
+
+
+
+
+ +
+
Use head tracking:
+
+
+
+
+ +
+
Use eyes tracking:
+
+
+
+
+ +
+
Use face tracking:
+
+
+
+
+ +
+
Use blinking:
+
+
+
+
+ +
+
Mirrored movement:
+
+
+
+
+ +
+
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