mirror of
https://github.com/hanetzer/sdraw_mods_cvr.git
synced 2025-09-03 18:39:23 +00:00
Input implementation
Internal keyword usage (wow!)
This commit is contained in:
parent
9afa795626
commit
8737f61bdc
22 changed files with 1037 additions and 623 deletions
|
@ -9,6 +9,6 @@ Merged set of MelonLoader mods for ChilloutVR.
|
|||
| Desktop Reticle Switch | ml_drs | 1.0.0 | Yes | Working |
|
||||
| Extended Game Notifications | ml_egn | 1.0.0 | Yes | Working
|
||||
| Four Point Tracking | ml_fpt | 1.0.9 | Retired | Deprecated | In-game feature since 2022r170 update
|
||||
| Leap Motion Extension | ml_lme | 1.2.9 | Yes | Working |
|
||||
| Leap Motion Extension | ml_lme | 1.3.0 | Yes, update review | Working |
|
||||
| Pickup Arm Movement | ml_pam | 1.0.0 | Yes | Working |
|
||||
| Server Connection Info | ml_sci | 1.0.2 | Retired | Retired | Superseded by `Extended Game Notifications`
|
||||
|
|
|
@ -4,6 +4,7 @@ using ABI_RC.Systems.IK.SubSystems;
|
|||
using ABI_RC.Systems.MovementSystem;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
namespace ml_amt
|
||||
{
|
||||
|
@ -71,7 +72,7 @@ namespace ml_amt
|
|||
MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer());
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator WaitForLocalPlayer()
|
||||
IEnumerator WaitForLocalPlayer()
|
||||
{
|
||||
while(PlayerSetup.Instance == null)
|
||||
yield return null;
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace ml_amt
|
|||
|
||||
readonly List<AvatarParameter> m_parameters = null;
|
||||
|
||||
public MotionTweaker()
|
||||
internal MotionTweaker()
|
||||
{
|
||||
m_parameters = new List<AvatarParameter>();
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ namespace ml_amt
|
|||
}
|
||||
}
|
||||
|
||||
public void OnAvatarClear()
|
||||
internal void OnAvatarClear()
|
||||
{
|
||||
m_vrIk = null;
|
||||
m_locomotionLayer = -1;
|
||||
|
@ -181,7 +181,7 @@ namespace ml_amt
|
|||
m_parameters.Clear();
|
||||
}
|
||||
|
||||
public void OnSetupAvatar()
|
||||
internal void OnSetupAvatar()
|
||||
{
|
||||
m_isInVR = Utils.IsInVR();
|
||||
m_vrIk = PlayerSetup.Instance._avatar.GetComponent<VRIK>();
|
||||
|
@ -239,7 +239,7 @@ namespace ml_amt
|
|||
m_avatarReady = true;
|
||||
}
|
||||
|
||||
public void OnCalibrate()
|
||||
internal void OnCalibrate()
|
||||
{
|
||||
if(m_avatarReady && BodySystem.isCalibratedAsFullBody && BodySystem.enableHipTracking && !BodySystem.enableRightFootTracking && !BodySystem.enableLeftFootTracking && !BodySystem.enableLeftKneeTracking && !BodySystem.enableRightKneeTracking)
|
||||
{
|
||||
|
|
|
@ -49,22 +49,24 @@ namespace ml_amt
|
|||
static public event Action<bool> FollowHipsChange;
|
||||
static public event Action<bool> CollisionScaleChange;
|
||||
|
||||
public static void Init()
|
||||
internal static void Init()
|
||||
{
|
||||
ms_category = MelonLoader.MelonPreferences.CreateCategory("AMT");
|
||||
|
||||
ms_entries = new List<MelonLoader.MelonPreferences_Entry>();
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.IKOverrideCrouch.ToString(), true));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.CrouchLimit.ToString(), 65));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.IKOverrideProne.ToString(), true));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.ProneLimit.ToString(), 30));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.PoseTransitions.ToString(), true));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.AdjustedMovement.ToString(), true));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.IKOverrideFly.ToString(), true));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.IKOverrideJump.ToString(), true));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.DetectEmotes.ToString(), true));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.FollowHips.ToString(), true));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.CollisionScale.ToString(), true));
|
||||
ms_entries = new List<MelonLoader.MelonPreferences_Entry>()
|
||||
{
|
||||
ms_category.CreateEntry(ModSetting.IKOverrideCrouch.ToString(), true),
|
||||
ms_category.CreateEntry(ModSetting.CrouchLimit.ToString(), 65),
|
||||
ms_category.CreateEntry(ModSetting.IKOverrideProne.ToString(), true),
|
||||
ms_category.CreateEntry(ModSetting.ProneLimit.ToString(), 30),
|
||||
ms_category.CreateEntry(ModSetting.PoseTransitions.ToString(), true),
|
||||
ms_category.CreateEntry(ModSetting.AdjustedMovement.ToString(), true),
|
||||
ms_category.CreateEntry(ModSetting.IKOverrideFly.ToString(), true),
|
||||
ms_category.CreateEntry(ModSetting.IKOverrideJump.ToString(), true),
|
||||
ms_category.CreateEntry(ModSetting.DetectEmotes.ToString(), true),
|
||||
ms_category.CreateEntry(ModSetting.FollowHips.ToString(), true),
|
||||
ms_category.CreateEntry(ModSetting.CollisionScale.ToString(), true)
|
||||
};
|
||||
|
||||
Load();
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace ml_dht
|
|||
}
|
||||
}
|
||||
|
||||
public void OnEyeControllerUpdate(CVREyeController p_component)
|
||||
internal void OnEyeControllerUpdate(CVREyeController p_component)
|
||||
{
|
||||
if(m_enabled)
|
||||
{
|
||||
|
@ -99,7 +99,7 @@ namespace ml_dht
|
|||
}
|
||||
}
|
||||
|
||||
public void OnFaceTrackingUpdate(CVRFaceTracking p_component)
|
||||
internal void OnFaceTrackingUpdate(CVRFaceTracking p_component)
|
||||
{
|
||||
if(m_enabled && m_faceOverride)
|
||||
{
|
||||
|
@ -117,7 +117,7 @@ namespace ml_dht
|
|||
}
|
||||
}
|
||||
|
||||
public void OnSetupAvatar()
|
||||
internal void OnSetupAvatar()
|
||||
{
|
||||
m_avatarDescriptor = PlayerSetup.Instance._avatar.GetComponent<CVRAvatar>();
|
||||
m_headBone = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.Head);
|
||||
|
@ -130,7 +130,7 @@ namespace ml_dht
|
|||
m_lookIK.solver.OnPostUpdate += this.OnLookIKPostUpdate;
|
||||
|
||||
}
|
||||
public void OnAvatarClear()
|
||||
internal void OnAvatarClear()
|
||||
{
|
||||
m_avatarDescriptor = null;
|
||||
m_lookIK = null;
|
||||
|
|
|
@ -37,18 +37,20 @@ namespace ml_dht
|
|||
static public event Action<float> SmoothingChange;
|
||||
static public event Action<bool> FaceOverrideChange;
|
||||
|
||||
public static void Init()
|
||||
internal static void Init()
|
||||
{
|
||||
ms_category = MelonLoader.MelonPreferences.CreateCategory("DHT");
|
||||
|
||||
ms_entries = new List<MelonLoader.MelonPreferences_Entry>();
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.Enabled.ToString(), false));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.HeadTracking.ToString(), false));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.EyeTracking.ToString(), true));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.Blinking.ToString(), true));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.Mirrored.ToString(), false));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.Smoothing.ToString(), 50));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.FaceOverride.ToString(), true));
|
||||
ms_entries = new List<MelonLoader.MelonPreferences_Entry>()
|
||||
{
|
||||
ms_category.CreateEntry(ModSetting.Enabled.ToString(), false),
|
||||
ms_category.CreateEntry(ModSetting.HeadTracking.ToString(), false),
|
||||
ms_category.CreateEntry(ModSetting.EyeTracking.ToString(), true),
|
||||
ms_category.CreateEntry(ModSetting.Blinking.ToString(), true),
|
||||
ms_category.CreateEntry(ModSetting.Mirrored.ToString(), false),
|
||||
ms_category.CreateEntry(ModSetting.Smoothing.ToString(), 50),
|
||||
ms_category.CreateEntry(ModSetting.FaceOverride.ToString(), true)
|
||||
};
|
||||
|
||||
Load();
|
||||
|
||||
|
@ -80,9 +82,9 @@ namespace ml_dht
|
|||
static void Load()
|
||||
{
|
||||
ms_enabled = (bool)ms_entries[(int)ModSetting.Enabled].BoxedValue;
|
||||
ms_headTracking = (bool)ms_entries[(int)ModSetting.HeadTracking].BoxedValue;
|
||||
ms_eyeTracking = (bool)ms_entries[(int)ModSetting.EyeTracking].BoxedValue;
|
||||
ms_blinking = (bool)ms_entries[(int)ModSetting.Blinking].BoxedValue;
|
||||
ms_headTracking = (bool)ms_entries[(int)ModSetting.HeadTracking].BoxedValue;
|
||||
ms_eyeTracking = (bool)ms_entries[(int)ModSetting.EyeTracking].BoxedValue;
|
||||
ms_blinking = (bool)ms_entries[(int)ModSetting.Blinking].BoxedValue;
|
||||
ms_mirrored = (bool)ms_entries[(int)ModSetting.Mirrored].BoxedValue;
|
||||
ms_smoothing = ((int)ms_entries[(int)ModSetting.Smoothing].BoxedValue) * 0.01f;
|
||||
ms_faceOverride = (bool)ms_entries[(int)ModSetting.FaceOverride].BoxedValue;
|
||||
|
@ -130,13 +132,15 @@ namespace ml_dht
|
|||
{
|
||||
ms_eyeTracking = bool.Parse(p_value);
|
||||
EyeTrackingChange?.Invoke(ms_eyeTracking);
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.Blinking:
|
||||
{
|
||||
ms_blinking = bool.Parse(p_value);
|
||||
BlinkingChange?.Invoke(ms_blinking);
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.Mirrored:
|
||||
{
|
||||
|
@ -149,7 +153,8 @@ namespace ml_dht
|
|||
{
|
||||
ms_faceOverride = bool.Parse(p_value);
|
||||
FaceOverrideChange?.Invoke(ms_faceOverride);
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ms_entries[(int)l_setting].BoxedValue = bool.Parse(p_value);
|
||||
|
|
|
@ -88,6 +88,6 @@
|
|||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>copy /y "$(TargetPath)" "C:\Games\Steam\common\ChilloutVR\Mods\"</PostBuildEvent>
|
||||
<PostBuildEvent>copy /y "$(TargetPath)" "D:\Games\Steam\steamapps\common\ChilloutVR\Mods\"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ReferencePath>C:\Games\Steam\common\ChilloutVR\MelonLoader\;C:\Games\Steam\common\ChilloutVR\ChilloutVR_Data\Managed\</ReferencePath>
|
||||
<ReferencePath>D:\Games\Steam\steamapps\common\ChilloutVR\MelonLoader\;D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\</ReferencePath>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -59,7 +59,7 @@ namespace ml_egn
|
|||
else
|
||||
{
|
||||
if(Utils.IsMenuOpened())
|
||||
ViewManager.Instance.TriggerAlert("Prop Error", "Not connected to live instance", -1, true);
|
||||
Utils.ShowMenuAlert("Prop Error", "Not connected to live instance");
|
||||
else
|
||||
Utils.ShowHUDNotification("(Local) Client", "Unable to spawn prop", "Not connected to live instance");
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ namespace ml_egn
|
|||
}
|
||||
}
|
||||
|
||||
static void OnGameNetworkConnectionClosed(object __0, DisconnectedEventArgs __1)
|
||||
static void OnGameNetworkConnectionClosed(DisconnectedEventArgs __1)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
@ -14,100 +14,75 @@ namespace ml_lme
|
|||
new Vector2(-10f, 25f)
|
||||
};
|
||||
|
||||
public class GesturesData
|
||||
public class HandData
|
||||
{
|
||||
readonly public static int ms_handsCount = 2;
|
||||
readonly public static int ms_fingersCount = 5;
|
||||
public bool m_present = false;
|
||||
public Vector3 m_position = Vector3.zero;
|
||||
public Quaternion m_rotation = Quaternion.identity;
|
||||
public Vector3 m_elbowPosition = Vector3.zero;
|
||||
public readonly float[] m_spreads = null;
|
||||
public readonly float[] m_bends = null;
|
||||
public float m_grabStrength = 0f;
|
||||
|
||||
public bool[] m_handsPresenses = null;
|
||||
public Vector3[] m_handsPositons = null;
|
||||
public Quaternion[] m_handsRotations = null;
|
||||
public Vector3[] m_elbowsPositions = null;
|
||||
public float[] m_leftFingersBends = null;
|
||||
public float[] m_leftFingersSpreads = null;
|
||||
public float[] m_rightFingersBends = null;
|
||||
public float[] m_rightFingersSpreads = null;
|
||||
|
||||
public GesturesData()
|
||||
public HandData()
|
||||
{
|
||||
m_handsPresenses = new bool[ms_handsCount];
|
||||
m_handsPositons = new Vector3[ms_handsCount];
|
||||
m_handsRotations = new Quaternion[ms_handsCount];
|
||||
m_elbowsPositions = new Vector3[ms_handsCount];
|
||||
m_leftFingersBends = new float[ms_fingersCount];
|
||||
m_leftFingersSpreads = new float[ms_fingersCount];
|
||||
m_rightFingersBends = new float[ms_fingersCount];
|
||||
m_rightFingersSpreads = new float[ms_fingersCount];
|
||||
m_spreads = new float[5];
|
||||
m_bends = new float[5];
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
m_present = false;
|
||||
for(int i = 0; i < 5; i++)
|
||||
{
|
||||
m_bends[i] = 0f;
|
||||
m_spreads[i] = 0f;
|
||||
}
|
||||
m_grabStrength = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetGestures(Leap.Frame p_frame, ref GesturesData p_data)
|
||||
public class LeapData
|
||||
{
|
||||
// Fill as default
|
||||
for(int i = 0; i < GesturesData.ms_handsCount; i++)
|
||||
p_data.m_handsPresenses[i] = false;
|
||||
for(int i = 0; i < GesturesData.ms_fingersCount; i++)
|
||||
public readonly HandData m_leftHand = null;
|
||||
public readonly HandData m_rightHand = null;
|
||||
|
||||
public LeapData()
|
||||
{
|
||||
p_data.m_leftFingersBends[i] = 0f;
|
||||
p_data.m_leftFingersSpreads[i] = 0f;
|
||||
p_data.m_rightFingersBends[i] = 0f;
|
||||
p_data.m_leftFingersSpreads[i] = 0f;
|
||||
m_leftHand = new HandData();
|
||||
m_rightHand = new HandData();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
m_leftHand.Reset();
|
||||
m_rightHand.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetFrameData(Leap.Frame p_frame, LeapData p_data)
|
||||
{
|
||||
p_data.Reset();
|
||||
|
||||
// Fill hands data
|
||||
foreach(Leap.Hand l_hand in p_frame.Hands)
|
||||
{
|
||||
int l_sideID = (l_hand.IsLeft ? 0 : 1);
|
||||
if(!p_data.m_handsPresenses[l_sideID])
|
||||
{
|
||||
p_data.m_handsPresenses[l_sideID] = true;
|
||||
FillHandPosition(l_hand, ref p_data.m_handsPositons[l_sideID]);
|
||||
FillHandRotation(l_hand, ref p_data.m_handsRotations[l_sideID]);
|
||||
FillElbowPosition(l_hand, ref p_data.m_elbowsPositions[l_sideID]);
|
||||
switch(l_sideID)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
FillFingerBends(l_hand, ref p_data.m_leftFingersBends);
|
||||
FilFingerSpreads(l_hand, ref p_data.m_leftFingersSpreads);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
FillFingerBends(l_hand, ref p_data.m_rightFingersBends);
|
||||
FilFingerSpreads(l_hand, ref p_data.m_rightFingersSpreads);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(l_hand.IsLeft && !p_data.m_leftHand.m_present)
|
||||
FillHandData(l_hand, p_data.m_leftHand);
|
||||
if(l_hand.IsRight && !p_data.m_rightHand.m_present)
|
||||
FillHandData(l_hand, p_data.m_rightHand);
|
||||
}
|
||||
}
|
||||
|
||||
static void FillHandPosition(Leap.Hand p_hand, ref Vector3 p_pos)
|
||||
static void FillHandData(Leap.Hand p_hand, HandData p_data)
|
||||
{
|
||||
// Unity's IK and FinalIK move hand bones to target, therefore - wrist
|
||||
p_pos.x = p_hand.WristPosition.x;
|
||||
p_pos.y = p_hand.WristPosition.y;
|
||||
p_pos.z = p_hand.WristPosition.z;
|
||||
}
|
||||
p_data.m_present = true;
|
||||
p_data.m_position.Set(p_hand.WristPosition.x, p_hand.WristPosition.y, p_hand.WristPosition.z);
|
||||
p_data.m_rotation.Set(p_hand.Rotation.x, p_hand.Rotation.y, p_hand.Rotation.z, p_hand.Rotation.w);
|
||||
p_data.m_elbowPosition.Set(p_hand.Arm.ElbowPosition.x, p_hand.Arm.ElbowPosition.y, p_hand.Arm.ElbowPosition.z);
|
||||
|
||||
static void FillHandRotation(Leap.Hand p_hand, ref Quaternion p_rot)
|
||||
{
|
||||
p_rot.x = p_hand.Rotation.x;
|
||||
p_rot.y = p_hand.Rotation.y;
|
||||
p_rot.z = p_hand.Rotation.z;
|
||||
p_rot.w = p_hand.Rotation.w;
|
||||
}
|
||||
|
||||
static void FillElbowPosition(Leap.Hand p_hand, ref Vector3 p_pos)
|
||||
{
|
||||
p_pos.x = p_hand.Arm.ElbowPosition.x;
|
||||
p_pos.y = p_hand.Arm.ElbowPosition.y;
|
||||
p_pos.z = p_hand.Arm.ElbowPosition.z;
|
||||
}
|
||||
|
||||
static void FillFingerBends(Leap.Hand p_hand, ref float[] p_bends)
|
||||
{
|
||||
// Bends
|
||||
foreach(Leap.Finger l_finger in p_hand.Fingers)
|
||||
{
|
||||
Quaternion l_prevSegment = Quaternion.identity;
|
||||
|
@ -132,12 +107,10 @@ namespace ml_lme
|
|||
l_angle += l_curAngle;
|
||||
}
|
||||
|
||||
p_bends[(int)l_finger.Type] = Mathf.InverseLerp(0f, (l_finger.Type == Leap.Finger.FingerType.TYPE_THUMB) ? 90f : 180f, l_angle);
|
||||
p_data.m_bends[(int)l_finger.Type] = Mathf.InverseLerp(0f, (l_finger.Type == Leap.Finger.FingerType.TYPE_THUMB) ? 90f : 180f, l_angle);
|
||||
}
|
||||
}
|
||||
|
||||
static void FilFingerSpreads(Leap.Hand p_hand, ref float[] p_spreads)
|
||||
{
|
||||
// Spreads
|
||||
foreach(Leap.Finger l_finger in p_hand.Fingers)
|
||||
{
|
||||
float l_angle = 0f;
|
||||
|
@ -162,13 +135,15 @@ namespace ml_lme
|
|||
if(l_finger.Type != Leap.Finger.FingerType.TYPE_THUMB)
|
||||
{
|
||||
if(l_angle < 0f)
|
||||
p_spreads[(int)l_finger.Type] = 0.5f * Mathf.InverseLerp(ms_fingerLimits[(int)l_finger.Type].x, 0f, l_angle);
|
||||
p_data.m_spreads[(int)l_finger.Type] = 0.5f * Mathf.InverseLerp(ms_fingerLimits[(int)l_finger.Type].x, 0f, l_angle);
|
||||
else
|
||||
p_spreads[(int)l_finger.Type] = 0.5f + 0.5f * Mathf.InverseLerp(0f, ms_fingerLimits[(int)l_finger.Type].y, l_angle);
|
||||
p_data.m_spreads[(int)l_finger.Type] = 0.5f + 0.5f * Mathf.InverseLerp(0f, ms_fingerLimits[(int)l_finger.Type].y, l_angle);
|
||||
}
|
||||
else
|
||||
p_spreads[(int)l_finger.Type] = Mathf.InverseLerp(ms_fingerLimits[(int)l_finger.Type].x, ms_fingerLimits[(int)l_finger.Type].y, l_angle);
|
||||
p_data.m_spreads[(int)l_finger.Type] = Mathf.InverseLerp(ms_fingerLimits[(int)l_finger.Type].x, ms_fingerLimits[(int)l_finger.Type].y, l_angle);
|
||||
}
|
||||
|
||||
p_data.m_grabStrength = (p_data.m_bends[1] + p_data.m_bends[2] + p_data.m_bends[3] + p_data.m_bends[4]) * 0.25f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
247
ml_lme/LeapInput.cs
Normal file
247
ml_lme/LeapInput.cs
Normal file
|
@ -0,0 +1,247 @@
|
|||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Savior;
|
||||
using ABI_RC.Systems.IK;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_lme
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
class LeapInput : CVRInputModule
|
||||
{
|
||||
static readonly FieldInfo ms_indexGestureToggle = typeof(InputModuleSteamVR).GetField("_steamVrIndexGestureToggleValue", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
CVRInputManager m_inputManager = null;
|
||||
InputModuleSteamVR m_steamVrModule = null;
|
||||
bool m_inVR = false;
|
||||
|
||||
ControllerRay m_handRayLeft = null;
|
||||
ControllerRay m_handRayRight = null;
|
||||
LineRenderer m_lineLeft = null;
|
||||
LineRenderer m_lineRight = null;
|
||||
bool m_interactLeft = false;
|
||||
bool m_interactRight = false;
|
||||
bool m_gripLeft = false;
|
||||
bool m_gripRight = false;
|
||||
|
||||
public new void Start()
|
||||
{
|
||||
base.Start();
|
||||
|
||||
m_inputManager = CVRInputManager.Instance; // _inputManager is stripped out, cool beans
|
||||
m_steamVrModule = this.GetComponent<InputModuleSteamVR>();
|
||||
m_inVR = Utils.IsInVR();
|
||||
|
||||
m_handRayLeft = LeapTracking.GetInstance().GetLeftHand().gameObject.AddComponent<ControllerRay>();
|
||||
m_handRayLeft.hand = true;
|
||||
m_handRayLeft.generalMask = -1485;
|
||||
m_handRayLeft.isInteractionRay = true;
|
||||
m_handRayLeft.triggerGazeEvents = false;
|
||||
m_handRayLeft.holderRoot = m_handRayLeft.gameObject;
|
||||
|
||||
m_handRayRight = LeapTracking.GetInstance().GetRightHand().gameObject.AddComponent<ControllerRay>();
|
||||
m_handRayRight.hand = false;
|
||||
m_handRayRight.generalMask = -1485;
|
||||
m_handRayRight.isInteractionRay = true;
|
||||
m_handRayRight.triggerGazeEvents = false;
|
||||
m_handRayRight.holderRoot = m_handRayRight.gameObject;
|
||||
|
||||
m_lineLeft = m_handRayLeft.gameObject.AddComponent<LineRenderer>();
|
||||
m_lineLeft.endWidth = 1f;
|
||||
m_lineLeft.startWidth = 1f;
|
||||
m_lineLeft.textureMode = LineTextureMode.Tile;
|
||||
m_lineLeft.useWorldSpace = false;
|
||||
m_lineLeft.widthMultiplier = 1f;
|
||||
m_lineLeft.allowOcclusionWhenDynamic = false;
|
||||
m_lineLeft.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
|
||||
m_lineLeft.enabled = false;
|
||||
m_lineLeft.receiveShadows = false;
|
||||
m_handRayLeft.lineRenderer = m_lineLeft;
|
||||
|
||||
m_lineRight = m_handRayRight.gameObject.AddComponent<LineRenderer>();
|
||||
m_lineRight.endWidth = 1f;
|
||||
m_lineRight.startWidth = 1f;
|
||||
m_lineRight.textureMode = LineTextureMode.Tile;
|
||||
m_lineRight.useWorldSpace = false;
|
||||
m_lineRight.widthMultiplier = 1f;
|
||||
m_lineRight.allowOcclusionWhenDynamic = false;
|
||||
m_lineRight.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
|
||||
m_lineRight.enabled = false;
|
||||
m_lineRight.receiveShadows = false;
|
||||
m_handRayRight.lineRenderer = m_lineRight;
|
||||
|
||||
Settings.EnabledChange += this.OnEnableChange;
|
||||
Settings.InputChange += this.OnInputChange;
|
||||
|
||||
OnEnableChange(Settings.Enabled);
|
||||
OnInputChange(Settings.Input);
|
||||
|
||||
MelonLoader.MelonCoroutines.Start(WaitForMaterial());
|
||||
}
|
||||
|
||||
IEnumerator WaitForMaterial()
|
||||
{
|
||||
while(PlayerSetup.Instance == null)
|
||||
yield return null;
|
||||
while(PlayerSetup.Instance.leftRay == null)
|
||||
yield return null;
|
||||
while(PlayerSetup.Instance.leftRay.lineRenderer == null)
|
||||
yield return null;
|
||||
|
||||
m_lineLeft.material = PlayerSetup.Instance.leftRay.lineRenderer.material;
|
||||
m_lineRight.material = PlayerSetup.Instance.leftRay.lineRenderer.material;
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
Settings.EnabledChange -= this.OnEnableChange;
|
||||
Settings.InputChange -= this.OnInputChange;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
GestureMatcher.LeapData l_data = LeapManager.GetInstance().GetLatestData();
|
||||
|
||||
if(Settings.Enabled)
|
||||
{
|
||||
if(l_data.m_leftHand.m_present)
|
||||
SetFingersInput(l_data.m_leftHand, true);
|
||||
if(l_data.m_rightHand.m_present)
|
||||
SetFingersInput(l_data.m_rightHand, false);
|
||||
}
|
||||
|
||||
m_handRayLeft.enabled = (l_data.m_leftHand.m_present && (!m_inVR || (VRTrackerManager.Instance.leftHand == null) || !VRTrackerManager.Instance.leftHand.active || !Settings.FingersOnly));
|
||||
m_handRayRight.enabled = (l_data.m_rightHand.m_present && (!m_inVR || (VRTrackerManager.Instance.rightHand == null) || !VRTrackerManager.Instance.rightHand.active || !Settings.FingersOnly));
|
||||
}
|
||||
|
||||
public override void UpdateInput()
|
||||
{
|
||||
if(Settings.Enabled && Settings.Input)
|
||||
{
|
||||
GestureMatcher.LeapData l_data = LeapManager.GetInstance().GetLatestData();
|
||||
|
||||
if(l_data.m_leftHand.m_present && (!m_inVR || (VRTrackerManager.Instance.leftHand == null) || !VRTrackerManager.Instance.leftHand.active || !Settings.FingersOnly))
|
||||
{
|
||||
float l_strength = l_data.m_leftHand.m_grabStrength;
|
||||
m_inputManager.interactLeftValue = l_strength;
|
||||
if(m_interactLeft != (l_strength > Settings.HoldThreadhold))
|
||||
{
|
||||
m_interactLeft = (l_strength > Settings.HoldThreadhold);
|
||||
m_inputManager.interactLeftUp |= m_interactLeft;
|
||||
m_inputManager.interactLeftDown |= m_interactLeft;
|
||||
}
|
||||
m_inputManager.gripLeftValue = 1f - l_strength; // Inversed
|
||||
if(m_gripLeft != (l_strength < Settings.ReleaseThreadhold))
|
||||
{
|
||||
m_gripLeft = (l_strength < Settings.ReleaseThreadhold);
|
||||
m_inputManager.gripLeftUp |= m_gripLeft;
|
||||
m_inputManager.gripLeftDown |= m_gripLeft;
|
||||
}
|
||||
}
|
||||
|
||||
if(l_data.m_rightHand.m_present && (!m_inVR || (VRTrackerManager.Instance.rightHand == null) || !VRTrackerManager.Instance.rightHand.active || !Settings.FingersOnly))
|
||||
{
|
||||
float l_strength = l_data.m_rightHand.m_grabStrength;
|
||||
m_inputManager.interactRightValue = l_strength;
|
||||
if(m_interactRight != (l_strength > Settings.HoldThreadhold))
|
||||
{
|
||||
m_interactRight = (l_strength > Settings.HoldThreadhold);
|
||||
m_inputManager.interactRightUp |= m_interactRight;
|
||||
m_inputManager.interactRightDown |= m_interactRight;
|
||||
}
|
||||
m_inputManager.gripRightValue = 1f - l_strength;
|
||||
if(m_gripRight != (l_strength < Settings.HoldThreadhold))
|
||||
{
|
||||
m_gripRight = (l_strength < Settings.HoldThreadhold);
|
||||
m_inputManager.gripRightUp |= m_gripRight;
|
||||
m_inputManager.gripRightDown |= m_gripRight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Settings changes
|
||||
void OnEnableChange(bool p_state)
|
||||
{
|
||||
OnInputChange(p_state && Settings.Input);
|
||||
UpdateFingerTracking();
|
||||
}
|
||||
|
||||
void OnInputChange(bool p_state)
|
||||
{
|
||||
(m_handRayLeft as MonoBehaviour).enabled = (p_state && Settings.Enabled);
|
||||
(m_handRayRight as MonoBehaviour).enabled = (p_state && Settings.Enabled);
|
||||
m_lineLeft.enabled = (p_state && Settings.Enabled);
|
||||
m_lineRight.enabled = (p_state && Settings.Enabled);
|
||||
|
||||
if(!p_state)
|
||||
{
|
||||
m_handRayLeft.DropObject(true);
|
||||
m_handRayLeft.ClearGrabbedObject();
|
||||
|
||||
m_handRayRight.DropObject(true);
|
||||
m_handRayRight.ClearGrabbedObject();
|
||||
|
||||
m_interactLeft = false;
|
||||
m_interactRight = false;
|
||||
m_gripLeft = false;
|
||||
m_gripRight = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Game events
|
||||
internal void OnAvatarSetup()
|
||||
{
|
||||
m_inVR = Utils.IsInVR();
|
||||
UpdateFingerTracking();
|
||||
}
|
||||
|
||||
internal void OnRayScale(float p_scale)
|
||||
{
|
||||
m_handRayLeft.SetRayScale(p_scale);
|
||||
m_handRayRight.SetRayScale(p_scale);
|
||||
}
|
||||
|
||||
// Arbitrary
|
||||
void UpdateFingerTracking()
|
||||
{
|
||||
m_inputManager.individualFingerTracking = (Settings.Enabled || (m_inVR && Utils.AreKnucklesInUse() && !(bool)ms_indexGestureToggle.GetValue(m_steamVrModule)));
|
||||
IKSystem.Instance.FingerSystem.controlActive = m_inputManager.individualFingerTracking;
|
||||
}
|
||||
|
||||
void SetFingersInput(GestureMatcher.HandData p_hand, bool p_left)
|
||||
{
|
||||
m_inputManager.individualFingerTracking = true;
|
||||
IKSystem.Instance.FingerSystem.controlActive = true;
|
||||
|
||||
if(p_left)
|
||||
{
|
||||
m_inputManager.fingerCurlLeftThumb = p_hand.m_bends[0];
|
||||
m_inputManager.fingerCurlLeftIndex = p_hand.m_bends[1];
|
||||
m_inputManager.fingerCurlLeftMiddle = p_hand.m_bends[2];
|
||||
m_inputManager.fingerCurlLeftRing = p_hand.m_bends[3];
|
||||
m_inputManager.fingerCurlLeftPinky = p_hand.m_bends[4];
|
||||
IKSystem.Instance.FingerSystem.leftThumbCurl = p_hand.m_bends[0];
|
||||
IKSystem.Instance.FingerSystem.leftIndexCurl = p_hand.m_bends[1];
|
||||
IKSystem.Instance.FingerSystem.leftMiddleCurl = p_hand.m_bends[2];
|
||||
IKSystem.Instance.FingerSystem.leftRingCurl = p_hand.m_bends[3];
|
||||
IKSystem.Instance.FingerSystem.leftPinkyCurl = p_hand.m_bends[4];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_inputManager.fingerCurlRightThumb = p_hand.m_bends[0];
|
||||
m_inputManager.fingerCurlRightIndex = p_hand.m_bends[1];
|
||||
m_inputManager.fingerCurlRightMiddle = p_hand.m_bends[2];
|
||||
m_inputManager.fingerCurlRightRing = p_hand.m_bends[3];
|
||||
m_inputManager.fingerCurlRightPinky = p_hand.m_bends[4];
|
||||
IKSystem.Instance.FingerSystem.rightThumbCurl = p_hand.m_bends[0];
|
||||
IKSystem.Instance.FingerSystem.rightIndexCurl = p_hand.m_bends[1];
|
||||
IKSystem.Instance.FingerSystem.rightMiddleCurl = p_hand.m_bends[2];
|
||||
IKSystem.Instance.FingerSystem.rightRingCurl = p_hand.m_bends[3];
|
||||
IKSystem.Instance.FingerSystem.rightPinkyCurl = p_hand.m_bends[4];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
204
ml_lme/LeapManager.cs
Normal file
204
ml_lme/LeapManager.cs
Normal file
|
@ -0,0 +1,204 @@
|
|||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Savior;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_lme
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
class LeapManager : MonoBehaviour
|
||||
{
|
||||
static LeapManager ms_instance = null;
|
||||
|
||||
readonly Leap.Controller m_leapController = null;
|
||||
readonly GestureMatcher.LeapData m_leapData = null;
|
||||
|
||||
LeapTracking m_leapTracking = null;
|
||||
LeapTracked m_leapTracked = null;
|
||||
LeapInput m_leapInput = null;
|
||||
|
||||
public static LeapManager GetInstance() => ms_instance;
|
||||
|
||||
internal LeapManager()
|
||||
{
|
||||
m_leapController = new Leap.Controller();
|
||||
m_leapData = new GestureMatcher.LeapData();
|
||||
}
|
||||
~LeapManager()
|
||||
{
|
||||
m_leapController.StopConnection();
|
||||
m_leapController.Dispose();
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
if(ms_instance == null)
|
||||
ms_instance = this;
|
||||
|
||||
DontDestroyOnLoad(this);
|
||||
|
||||
m_leapController.Device += this.OnLeapDeviceInitialized;
|
||||
m_leapController.DeviceFailure += this.OnLeapDeviceFailure;
|
||||
m_leapController.DeviceLost += this.OnLeapDeviceLost;
|
||||
m_leapController.Connect += this.OnLeapServiceConnect;
|
||||
m_leapController.Disconnect += this.OnLeapServiceDisconnect;
|
||||
|
||||
Settings.EnabledChange += this.OnEnableChange;
|
||||
Settings.TrackingModeChange += this.OnTrackingModeChange;
|
||||
|
||||
m_leapTracking = new GameObject("[LeapTrackingRoot]").AddComponent<LeapTracking>();
|
||||
m_leapTracking.transform.parent = this.transform;
|
||||
|
||||
MelonLoader.MelonCoroutines.Start(WaitForInputManager());
|
||||
MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer());
|
||||
|
||||
OnEnableChange(Settings.Enabled);
|
||||
OnTrackingModeChange(Settings.TrackingMode);
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
if(ms_instance == this)
|
||||
ms_instance = null;
|
||||
|
||||
m_leapController.Device -= this.OnLeapDeviceInitialized;
|
||||
m_leapController.DeviceFailure -= this.OnLeapDeviceFailure;
|
||||
m_leapController.DeviceLost -= this.OnLeapDeviceLost;
|
||||
m_leapController.Connect -= this.OnLeapServiceConnect;
|
||||
m_leapController.Disconnect -= this.OnLeapServiceDisconnect;
|
||||
|
||||
Settings.EnabledChange -= this.OnEnableChange;
|
||||
Settings.TrackingModeChange -= this.OnTrackingModeChange;
|
||||
}
|
||||
|
||||
IEnumerator WaitForInputManager()
|
||||
{
|
||||
while(CVRInputManager.Instance == null)
|
||||
yield return null;
|
||||
|
||||
m_leapInput = CVRInputManager.Instance.gameObject.AddComponent<LeapInput>();
|
||||
}
|
||||
|
||||
IEnumerator WaitForLocalPlayer()
|
||||
{
|
||||
while(PlayerSetup.Instance == null)
|
||||
yield return null;
|
||||
|
||||
m_leapTracked = PlayerSetup.Instance.gameObject.AddComponent<LeapTracked>();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if(Settings.Enabled)
|
||||
{
|
||||
m_leapData.Reset();
|
||||
|
||||
if(m_leapController.IsConnected)
|
||||
{
|
||||
Leap.Frame l_frame = m_leapController.Frame();
|
||||
GestureMatcher.GetFrameData(l_frame, m_leapData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GestureMatcher.LeapData GetLatestData() => m_leapData;
|
||||
|
||||
// Device events
|
||||
void OnLeapDeviceInitialized(object p_sender, Leap.DeviceEventArgs p_args)
|
||||
{
|
||||
if(Settings.Enabled)
|
||||
{
|
||||
m_leapController.SubscribeToDeviceEvents(p_args.Device);
|
||||
UpdateDeviceTrackingMode();
|
||||
}
|
||||
|
||||
Utils.ShowHUDNotification("Leap Motion Extension", "Device initialized");
|
||||
}
|
||||
|
||||
void OnLeapDeviceFailure(object p_sender, Leap.DeviceFailureEventArgs p_args)
|
||||
{
|
||||
Utils.ShowHUDNotification("Leap Motion Extension", "Device failure", "Code " + p_args.ErrorCode + ": " + p_args.ErrorMessage);
|
||||
}
|
||||
|
||||
void OnLeapDeviceLost(object p_sender, Leap.DeviceEventArgs p_args)
|
||||
{
|
||||
m_leapController.UnsubscribeFromDeviceEvents(p_args.Device);
|
||||
|
||||
Utils.ShowHUDNotification("Leap Motion Extension", "Device lost");
|
||||
}
|
||||
|
||||
void OnLeapServiceConnect(object p_sender, Leap.ConnectionEventArgs p_args)
|
||||
{
|
||||
Utils.ShowHUDNotification("Leap Motion Extension", "Service connected");
|
||||
}
|
||||
|
||||
void OnLeapServiceDisconnect(object p_sender, Leap.ConnectionLostEventArgs p_args)
|
||||
{
|
||||
Utils.ShowHUDNotification("Leap Motion Extension", "Service disconnected");
|
||||
}
|
||||
|
||||
// Settings
|
||||
void OnEnableChange(bool p_state)
|
||||
{
|
||||
if(p_state)
|
||||
{
|
||||
m_leapController.StartConnection();
|
||||
UpdateDeviceTrackingMode();
|
||||
}
|
||||
else
|
||||
m_leapController.StopConnection();
|
||||
}
|
||||
|
||||
void OnTrackingModeChange(Settings.LeapTrackingMode p_mode)
|
||||
{
|
||||
if(Settings.Enabled)
|
||||
UpdateDeviceTrackingMode();
|
||||
}
|
||||
|
||||
// Game events
|
||||
internal void OnAvatarClear()
|
||||
{
|
||||
if(m_leapTracked != null)
|
||||
m_leapTracked.OnAvatarClear();
|
||||
}
|
||||
|
||||
internal void OnAvatarSetup()
|
||||
{
|
||||
if(m_leapTracking != null)
|
||||
m_leapTracking.OnAvatarSetup();
|
||||
if(m_leapInput != null)
|
||||
m_leapInput.OnAvatarSetup();
|
||||
if(m_leapTracked != null)
|
||||
m_leapTracked.OnAvatarSetup();
|
||||
}
|
||||
|
||||
internal void OnCalibrate()
|
||||
{
|
||||
if(m_leapTracked != null)
|
||||
m_leapTracked.OnCalibrate();
|
||||
}
|
||||
|
||||
internal void OnRayScale(float p_scale)
|
||||
{
|
||||
if(m_leapInput != null)
|
||||
m_leapInput.OnRayScale(p_scale);
|
||||
}
|
||||
|
||||
// Arbitrary
|
||||
void UpdateDeviceTrackingMode()
|
||||
{
|
||||
m_leapController.ClearPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_SCREENTOP, null);
|
||||
m_leapController.ClearPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD, null);
|
||||
|
||||
switch(Settings.TrackingMode)
|
||||
{
|
||||
case Settings.LeapTrackingMode.Screentop:
|
||||
m_leapController.SetPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_SCREENTOP, null);
|
||||
break;
|
||||
case Settings.LeapTrackingMode.HMD:
|
||||
m_leapController.SetPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Savior;
|
||||
using ABI_RC.Systems.IK;
|
||||
using RootMotion.FinalIK;
|
||||
using System.Reflection;
|
||||
|
@ -11,20 +10,17 @@ namespace ml_lme
|
|||
class LeapTracked : MonoBehaviour
|
||||
{
|
||||
static readonly float[] ms_tposeMuscles = typeof(ABI_RC.Systems.IK.SubSystems.BodySystem).GetField("TPoseMuscles", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null) as float[];
|
||||
static readonly FieldInfo ms_indexGestureToggle = typeof(InputModuleSteamVR).GetField("_steamVrIndexGestureToggleValue", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
static readonly Quaternion ms_offsetLeft = Quaternion.Euler(0f, 0f, 270f);
|
||||
static readonly Quaternion ms_offsetRight = Quaternion.Euler(0f, 0f, 90f);
|
||||
static readonly Quaternion ms_offsetLeftDesktop = Quaternion.Euler(0f, 90f, 0f);
|
||||
static readonly Quaternion ms_offsetRightDesktop = Quaternion.Euler(0f, 270f, 0f);
|
||||
|
||||
InputModuleSteamVR m_steamVrModule = null;
|
||||
VRIK m_vrIK = null;
|
||||
Vector2 m_armsWeights = Vector2.zero;
|
||||
bool m_isInVR = false;
|
||||
bool m_inVR = false;
|
||||
Transform m_origElbowLeft = null;
|
||||
Transform m_origElbowRight = null;
|
||||
Transform m_hips = null;
|
||||
Vector3 m_hipsLocal = Vector3.zero;
|
||||
|
||||
bool m_enabled = true;
|
||||
bool m_fingersOnly = false;
|
||||
|
@ -34,38 +30,32 @@ namespace ml_lme
|
|||
ArmIK m_rightIK = null;
|
||||
HumanPoseHandler m_poseHandler = null;
|
||||
HumanPose m_pose;
|
||||
Transform m_leftHand = null;
|
||||
Transform m_rightHand = null;
|
||||
Transform m_leftHandTarget = null;
|
||||
Transform m_rightHandTarget = null;
|
||||
Transform m_leftElbow = null;
|
||||
Transform m_rightElbow = null;
|
||||
bool m_leftTargetActive = false;
|
||||
bool m_rightTargetActive = false;
|
||||
|
||||
void Start()
|
||||
{
|
||||
m_steamVrModule = CVRInputManager.Instance.GetComponent<InputModuleSteamVR>();
|
||||
m_isInVR = Utils.IsInVR();
|
||||
m_inVR = Utils.IsInVR();
|
||||
|
||||
if(m_leftHand != null)
|
||||
{
|
||||
m_leftHandTarget = new GameObject("RotationTarget").transform;
|
||||
m_leftHandTarget.parent = m_leftHand;
|
||||
m_leftHandTarget.localPosition = Vector3.zero;
|
||||
m_leftHandTarget.localRotation = Quaternion.identity;
|
||||
}
|
||||
if(m_rightHand != null)
|
||||
{
|
||||
m_rightHandTarget = new GameObject("RotationTarget").transform;
|
||||
m_rightHandTarget.parent = m_rightHand;
|
||||
m_rightHandTarget.localPosition = Vector3.zero;
|
||||
m_rightHandTarget.localRotation = Quaternion.identity;
|
||||
}
|
||||
m_leftHandTarget = new GameObject("RotationTarget").transform;
|
||||
m_leftHandTarget.parent = LeapTracking.GetInstance().GetLeftHand();
|
||||
m_leftHandTarget.localPosition = Vector3.zero;
|
||||
m_leftHandTarget.localRotation = Quaternion.identity;
|
||||
|
||||
m_rightHandTarget = new GameObject("RotationTarget").transform;
|
||||
m_rightHandTarget.parent = LeapTracking.GetInstance().GetRightHand();
|
||||
m_rightHandTarget.localPosition = Vector3.zero;
|
||||
m_rightHandTarget.localRotation = Quaternion.identity;
|
||||
|
||||
Settings.EnabledChange += this.SetEnabled;
|
||||
Settings.FingersOnlyChange += this.SetFingersOnly;
|
||||
Settings.TrackElbowsChange += this.SetTrackElbows;
|
||||
|
||||
SetEnabled(Settings.Enabled);
|
||||
SetFingersOnly(Settings.FingersOnly);
|
||||
SetTrackElbows(Settings.TrackElbows);
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
|
@ -75,17 +65,16 @@ namespace ml_lme
|
|||
Settings.TrackElbowsChange -= this.SetTrackElbows;
|
||||
}
|
||||
|
||||
public void SetEnabled(bool p_state)
|
||||
void SetEnabled(bool p_state)
|
||||
{
|
||||
m_enabled = p_state;
|
||||
|
||||
RefreshFingersTracking();
|
||||
RefreshArmIK();
|
||||
if(!m_enabled || m_fingersOnly)
|
||||
RestoreVRIK();
|
||||
}
|
||||
|
||||
public void SetFingersOnly(bool p_state)
|
||||
void SetFingersOnly(bool p_state)
|
||||
{
|
||||
m_fingersOnly = p_state;
|
||||
|
||||
|
@ -94,7 +83,7 @@ namespace ml_lme
|
|||
RestoreVRIK();
|
||||
}
|
||||
|
||||
public void SetTrackElbows(bool p_state)
|
||||
void SetTrackElbows(bool p_state)
|
||||
{
|
||||
m_trackElbows = p_state;
|
||||
|
||||
|
@ -107,190 +96,148 @@ namespace ml_lme
|
|||
RestoreVRIK();
|
||||
}
|
||||
|
||||
public void SetTransforms(Transform p_left, Transform p_right, Transform p_leftElbow, Transform p_rightElbow)
|
||||
{
|
||||
m_leftHand = p_left;
|
||||
m_rightHand = p_right;
|
||||
|
||||
m_leftElbow = p_leftElbow;
|
||||
m_rightElbow = p_rightElbow;
|
||||
}
|
||||
|
||||
public void UpdateTracking(GestureMatcher.GesturesData p_data)
|
||||
void Update()
|
||||
{
|
||||
if(m_enabled)
|
||||
{
|
||||
GestureMatcher.LeapData l_data = LeapManager.GetInstance().GetLatestData();
|
||||
|
||||
if((m_leftIK != null) && (m_rightIK != null))
|
||||
{
|
||||
m_leftIK.solver.IKPositionWeight = Mathf.Lerp(m_leftIK.solver.IKPositionWeight, (p_data.m_handsPresenses[0] && !m_fingersOnly) ? 1f : 0f, 0.25f);
|
||||
m_leftIK.solver.IKRotationWeight = Mathf.Lerp(m_leftIK.solver.IKRotationWeight, (p_data.m_handsPresenses[0] && !m_fingersOnly) ? 1f : 0f, 0.25f);
|
||||
m_leftIK.solver.IKPositionWeight = Mathf.Lerp(m_leftIK.solver.IKPositionWeight, (l_data.m_leftHand.m_present && !m_fingersOnly) ? 1f : 0f, 0.25f);
|
||||
m_leftIK.solver.IKRotationWeight = Mathf.Lerp(m_leftIK.solver.IKRotationWeight, (l_data.m_leftHand.m_present && !m_fingersOnly) ? 1f : 0f, 0.25f);
|
||||
if(m_trackElbows)
|
||||
m_leftIK.solver.arm.bendGoalWeight = Mathf.Lerp(m_leftIK.solver.arm.bendGoalWeight, (p_data.m_handsPresenses[0] && !m_fingersOnly) ? 1f : 0f, 0.25f);
|
||||
m_leftIK.solver.arm.bendGoalWeight = Mathf.Lerp(m_leftIK.solver.arm.bendGoalWeight, (l_data.m_leftHand.m_present && !m_fingersOnly) ? 1f : 0f, 0.25f);
|
||||
|
||||
m_rightIK.solver.IKPositionWeight = Mathf.Lerp(m_rightIK.solver.IKPositionWeight, (p_data.m_handsPresenses[1] && !m_fingersOnly) ? 1f : 0f, 0.25f);
|
||||
m_rightIK.solver.IKRotationWeight = Mathf.Lerp(m_rightIK.solver.IKRotationWeight, (p_data.m_handsPresenses[1] && !m_fingersOnly) ? 1f : 0f, 0.25f);
|
||||
m_rightIK.solver.IKPositionWeight = Mathf.Lerp(m_rightIK.solver.IKPositionWeight, (l_data.m_rightHand.m_present && !m_fingersOnly) ? 1f : 0f, 0.25f);
|
||||
m_rightIK.solver.IKRotationWeight = Mathf.Lerp(m_rightIK.solver.IKRotationWeight, (l_data.m_rightHand.m_present && !m_fingersOnly) ? 1f : 0f, 0.25f);
|
||||
if(m_trackElbows)
|
||||
m_rightIK.solver.arm.bendGoalWeight = Mathf.Lerp(m_rightIK.solver.arm.bendGoalWeight, (p_data.m_handsPresenses[1] && !m_fingersOnly) ? 1f : 0f, 0.25f);
|
||||
m_rightIK.solver.arm.bendGoalWeight = Mathf.Lerp(m_rightIK.solver.arm.bendGoalWeight, (l_data.m_rightHand.m_present && !m_fingersOnly) ? 1f : 0f, 0.25f);
|
||||
}
|
||||
|
||||
if((m_vrIK != null) && !m_fingersOnly)
|
||||
{
|
||||
if(p_data.m_handsPresenses[0] && !m_leftTargetActive)
|
||||
if(l_data.m_leftHand.m_present && !m_leftTargetActive)
|
||||
{
|
||||
m_vrIK.solver.leftArm.target = m_leftHandTarget;
|
||||
m_vrIK.solver.leftArm.bendGoal = m_leftElbow;
|
||||
m_vrIK.solver.leftArm.bendGoal = LeapTracking.GetInstance().GetLeftElbow();
|
||||
m_vrIK.solver.leftArm.bendGoalWeight = (m_trackElbows ? 1f : 0f);
|
||||
m_leftTargetActive = true;
|
||||
}
|
||||
if(!p_data.m_handsPresenses[0] && m_leftTargetActive)
|
||||
if(!l_data.m_leftHand.m_present && m_leftTargetActive)
|
||||
{
|
||||
m_vrIK.solver.leftArm.target = IKSystem.Instance.leftHandAnchor;
|
||||
m_vrIK.solver.leftArm.target = (m_inVR ? IKSystem.Instance.leftHandAnchor : null);
|
||||
m_vrIK.solver.leftArm.bendGoal = m_origElbowLeft;
|
||||
m_vrIK.solver.leftArm.bendGoalWeight = ((m_origElbowLeft != null) ? 1f : 0f);
|
||||
m_leftTargetActive = false;
|
||||
}
|
||||
|
||||
if(p_data.m_handsPresenses[1] && !m_rightTargetActive)
|
||||
if(l_data.m_rightHand.m_present && !m_rightTargetActive)
|
||||
{
|
||||
m_vrIK.solver.rightArm.target = m_rightHandTarget;
|
||||
m_vrIK.solver.rightArm.bendGoal = m_rightElbow;
|
||||
m_vrIK.solver.rightArm.bendGoal = LeapTracking.GetInstance().GetRightElbow();
|
||||
m_vrIK.solver.rightArm.bendGoalWeight = (m_trackElbows ? 1f : 0f);
|
||||
m_rightTargetActive = true;
|
||||
}
|
||||
if(!p_data.m_handsPresenses[1] && m_rightTargetActive)
|
||||
if(!l_data.m_rightHand.m_present && m_rightTargetActive)
|
||||
{
|
||||
m_vrIK.solver.rightArm.target = IKSystem.Instance.rightHandAnchor;
|
||||
m_vrIK.solver.rightArm.target = (m_inVR ? IKSystem.Instance.rightHandAnchor : null);
|
||||
m_vrIK.solver.rightArm.bendGoal = m_origElbowRight;
|
||||
m_vrIK.solver.rightArm.bendGoalWeight = ((m_origElbowRight != null) ? 1f : 0f);
|
||||
m_rightTargetActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(p_data.m_handsPresenses[0])
|
||||
{
|
||||
CVRInputManager.Instance.individualFingerTracking = true;
|
||||
CVRInputManager.Instance.fingerCurlLeftThumb = p_data.m_leftFingersBends[0];
|
||||
CVRInputManager.Instance.fingerCurlLeftIndex = p_data.m_leftFingersBends[1];
|
||||
CVRInputManager.Instance.fingerCurlLeftMiddle = p_data.m_leftFingersBends[2];
|
||||
CVRInputManager.Instance.fingerCurlLeftRing = p_data.m_leftFingersBends[3];
|
||||
CVRInputManager.Instance.fingerCurlLeftPinky = p_data.m_leftFingersBends[4];
|
||||
|
||||
IKSystem.Instance.FingerSystem.controlActive = true;
|
||||
IKSystem.Instance.FingerSystem.leftThumbCurl = p_data.m_leftFingersBends[0];
|
||||
IKSystem.Instance.FingerSystem.leftIndexCurl = p_data.m_leftFingersBends[1];
|
||||
IKSystem.Instance.FingerSystem.leftMiddleCurl = p_data.m_leftFingersBends[2];
|
||||
IKSystem.Instance.FingerSystem.leftRingCurl = p_data.m_leftFingersBends[3];
|
||||
IKSystem.Instance.FingerSystem.leftPinkyCurl = p_data.m_leftFingersBends[4];
|
||||
}
|
||||
|
||||
if(p_data.m_handsPresenses[1])
|
||||
{
|
||||
CVRInputManager.Instance.individualFingerTracking = true;
|
||||
CVRInputManager.Instance.fingerCurlRightThumb = p_data.m_rightFingersBends[0];
|
||||
CVRInputManager.Instance.fingerCurlRightIndex = p_data.m_rightFingersBends[1];
|
||||
CVRInputManager.Instance.fingerCurlRightMiddle = p_data.m_rightFingersBends[2];
|
||||
CVRInputManager.Instance.fingerCurlRightRing = p_data.m_rightFingersBends[3];
|
||||
CVRInputManager.Instance.fingerCurlRightPinky = p_data.m_rightFingersBends[4];
|
||||
|
||||
IKSystem.Instance.FingerSystem.controlActive = true;
|
||||
IKSystem.Instance.FingerSystem.rightThumbCurl = p_data.m_rightFingersBends[0];
|
||||
IKSystem.Instance.FingerSystem.rightIndexCurl = p_data.m_rightFingersBends[1];
|
||||
IKSystem.Instance.FingerSystem.rightMiddleCurl = p_data.m_rightFingersBends[2];
|
||||
IKSystem.Instance.FingerSystem.rightRingCurl = p_data.m_rightFingersBends[3];
|
||||
IKSystem.Instance.FingerSystem.rightPinkyCurl = p_data.m_rightFingersBends[4];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateTrackingLate(GestureMatcher.GesturesData p_data)
|
||||
void LateUpdate()
|
||||
{
|
||||
if(m_enabled && !m_isInVR && (m_poseHandler != null))
|
||||
if(m_enabled && !m_inVR && (m_poseHandler != null))
|
||||
{
|
||||
if(m_hips != null)
|
||||
m_hipsLocal = m_hips.localPosition;
|
||||
GestureMatcher.LeapData l_data = LeapManager.GetInstance().GetLatestData();
|
||||
|
||||
Vector3 l_hipsLocalPos = m_hips.localPosition;
|
||||
|
||||
m_poseHandler.GetHumanPose(ref m_pose);
|
||||
UpdateFingers(p_data);
|
||||
UpdateFingers(l_data);
|
||||
m_poseHandler.SetHumanPose(ref m_pose);
|
||||
|
||||
if(m_hips != null)
|
||||
m_hips.localPosition = m_hipsLocal;
|
||||
m_hips.localPosition = l_hipsLocalPos;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateFingers(GestureMatcher.GesturesData p_data)
|
||||
void UpdateFingers(GestureMatcher.LeapData p_data)
|
||||
{
|
||||
if(p_data.m_handsPresenses[0])
|
||||
if(p_data.m_leftHand.m_present)
|
||||
{
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftThumb1Stretched, Mathf.Lerp(0.85f, -0.85f, p_data.m_leftFingersBends[0]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftThumb2Stretched, Mathf.Lerp(0.85f, -0.85f, p_data.m_leftFingersBends[0]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftThumb3Stretched, Mathf.Lerp(0.85f, -0.85f, p_data.m_leftFingersBends[0]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftThumbSpread, Mathf.Lerp(-1.5f, 1.0f, p_data.m_leftFingersSpreads[0])); // Ok
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftThumb1Stretched, Mathf.Lerp(0.85f, -0.85f, p_data.m_leftHand.m_bends[0]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftThumb2Stretched, Mathf.Lerp(0.85f, -0.85f, p_data.m_leftHand.m_bends[0]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftThumb3Stretched, Mathf.Lerp(0.85f, -0.85f, p_data.m_leftHand.m_bends[0]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftThumbSpread, Mathf.Lerp(-1.5f, 1.0f, p_data.m_leftHand.m_spreads[0])); // Ok
|
||||
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftIndex1Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftFingersBends[1]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftIndex2Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftFingersBends[1]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftIndex3Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftFingersBends[1]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftIndexSpread, Mathf.Lerp(1f, -1f, p_data.m_leftFingersSpreads[1])); // Ok
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftIndex1Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftHand.m_bends[1]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftIndex2Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftHand.m_bends[1]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftIndex3Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftHand.m_bends[1]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftIndexSpread, Mathf.Lerp(1f, -1f, p_data.m_leftHand.m_spreads[1])); // Ok
|
||||
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftMiddle1Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftFingersBends[2]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftMiddle2Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftFingersBends[2]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftMiddle3Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftFingersBends[2]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftMiddleSpread, Mathf.Lerp(2f, -2f, p_data.m_leftFingersSpreads[2]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftMiddle1Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftHand.m_bends[2]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftMiddle2Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftHand.m_bends[2]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftMiddle3Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftHand.m_bends[2]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftMiddleSpread, Mathf.Lerp(2f, -2f, p_data.m_leftHand.m_spreads[2]));
|
||||
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftRing1Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftFingersBends[3]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftRing2Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftFingersBends[3]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftRing3Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftFingersBends[3]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftRingSpread, Mathf.Lerp(-2f, 2f, p_data.m_leftFingersSpreads[3]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftRing1Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftHand.m_bends[3]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftRing2Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftHand.m_bends[3]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftRing3Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftHand.m_bends[3]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftRingSpread, Mathf.Lerp(-2f, 2f, p_data.m_leftHand.m_spreads[3]));
|
||||
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftLittle1Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftFingersBends[4]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftLittle2Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftFingersBends[4]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftLittle3Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftFingersBends[4]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftLittleSpread, Mathf.Lerp(-0.5f, 1f, p_data.m_leftFingersSpreads[4]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftLittle1Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftHand.m_bends[4]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftLittle2Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftHand.m_bends[4]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftLittle3Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_leftHand.m_bends[4]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.LeftLittleSpread, Mathf.Lerp(-0.5f, 1f, p_data.m_leftHand.m_spreads[4]));
|
||||
}
|
||||
|
||||
if(p_data.m_handsPresenses[1])
|
||||
if(p_data.m_rightHand.m_present)
|
||||
{
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightThumb1Stretched, Mathf.Lerp(0.85f, -0.85f, p_data.m_rightFingersBends[0]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightThumb2Stretched, Mathf.Lerp(0.85f, -0.85f, p_data.m_rightFingersBends[0]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightThumb3Stretched, Mathf.Lerp(0.85f, -0.85f, p_data.m_rightFingersBends[0]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightThumbSpread, Mathf.Lerp(-1.5f, 1.0f, p_data.m_rightFingersSpreads[0])); // Ok
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightThumb1Stretched, Mathf.Lerp(0.85f, -0.85f, p_data.m_rightHand.m_bends[0]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightThumb2Stretched, Mathf.Lerp(0.85f, -0.85f, p_data.m_rightHand.m_bends[0]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightThumb3Stretched, Mathf.Lerp(0.85f, -0.85f, p_data.m_rightHand.m_bends[0]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightThumbSpread, Mathf.Lerp(-1.5f, 1.0f, p_data.m_rightHand.m_spreads[0])); // Ok
|
||||
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightIndex1Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightFingersBends[1]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightIndex2Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightFingersBends[1]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightIndex3Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightFingersBends[1]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightIndexSpread, Mathf.Lerp(1f, -1f, p_data.m_rightFingersSpreads[1])); // Ok
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightIndex1Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightHand.m_bends[1]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightIndex2Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightHand.m_bends[1]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightIndex3Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightHand.m_bends[1]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightIndexSpread, Mathf.Lerp(1f, -1f, p_data.m_rightHand.m_spreads[1])); // Ok
|
||||
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightMiddle1Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightFingersBends[2]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightMiddle2Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightFingersBends[2]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightMiddle3Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightFingersBends[2]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightMiddleSpread, Mathf.Lerp(2f, -2f, p_data.m_rightFingersSpreads[2]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightMiddle1Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightHand.m_bends[2]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightMiddle2Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightHand.m_bends[2]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightMiddle3Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightHand.m_bends[2]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightMiddleSpread, Mathf.Lerp(2f, -2f, p_data.m_rightHand.m_spreads[2]));
|
||||
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightRing1Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightFingersBends[3]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightRing2Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightFingersBends[3]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightRing3Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightFingersBends[3]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightRingSpread, Mathf.Lerp(-2f, 2f, p_data.m_rightFingersSpreads[3]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightRing1Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightHand.m_bends[3]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightRing2Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightHand.m_bends[3]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightRing3Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightHand.m_bends[3]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightRingSpread, Mathf.Lerp(-2f, 2f, p_data.m_rightHand.m_spreads[3]));
|
||||
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightLittle1Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightFingersBends[4]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightLittle2Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightFingersBends[4]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightLittle3Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightFingersBends[4]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightLittleSpread, Mathf.Lerp(-0.5f, 1f, p_data.m_rightFingersSpreads[4]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightLittle1Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightHand.m_bends[4]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightLittle2Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightHand.m_bends[4]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightLittle3Stretched, Mathf.Lerp(0.7f, -1f, p_data.m_rightHand.m_bends[4]));
|
||||
UpdatePoseMuscle(ref m_pose, (int)MuscleIndex.RightLittleSpread, Mathf.Lerp(-0.5f, 1f, p_data.m_rightHand.m_spreads[4]));
|
||||
}
|
||||
}
|
||||
|
||||
public void OnAvatarClear()
|
||||
internal void OnAvatarClear()
|
||||
{
|
||||
m_vrIK = null;
|
||||
m_origElbowLeft = null;
|
||||
m_origElbowRight = null;
|
||||
m_hips = null;
|
||||
m_hipsLocal = Vector3.zero;
|
||||
m_armsWeights = Vector2.zero;
|
||||
m_leftIK = null;
|
||||
m_rightIK = null;
|
||||
m_leftTargetActive = false;
|
||||
m_rightTargetActive = false;
|
||||
|
||||
if(!m_isInVR)
|
||||
if(!m_inVR)
|
||||
m_poseHandler?.Dispose();
|
||||
m_poseHandler = null;
|
||||
|
||||
|
@ -300,27 +247,27 @@ namespace ml_lme
|
|||
m_rightHandTarget.localRotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
public void OnSetupAvatar()
|
||||
internal void OnAvatarSetup()
|
||||
{
|
||||
m_isInVR = Utils.IsInVR();
|
||||
m_inVR = Utils.IsInVR();
|
||||
m_vrIK = PlayerSetup.Instance._animator.GetComponent<VRIK>();
|
||||
|
||||
RefreshFingersTracking();
|
||||
|
||||
if(PlayerSetup.Instance._animator.isHuman)
|
||||
{
|
||||
m_hips = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.Hips);
|
||||
|
||||
if(!m_isInVR)
|
||||
if(!m_inVR)
|
||||
{
|
||||
// Force desktop avatar into T-Pose
|
||||
m_poseHandler = new HumanPoseHandler(PlayerSetup.Instance._animator.avatar, PlayerSetup.Instance._avatar.transform);
|
||||
m_poseHandler.GetHumanPose(ref m_pose);
|
||||
|
||||
HumanPose l_tPose = new HumanPose();
|
||||
l_tPose.bodyPosition = m_pose.bodyPosition;
|
||||
l_tPose.bodyRotation = m_pose.bodyRotation;
|
||||
l_tPose.muscles = new float[m_pose.muscles.Length];
|
||||
HumanPose l_tPose = new HumanPose
|
||||
{
|
||||
bodyPosition = m_pose.bodyPosition,
|
||||
bodyRotation = m_pose.bodyRotation,
|
||||
muscles = new float[m_pose.muscles.Length]
|
||||
};
|
||||
for(int i = 0; i < l_tPose.muscles.Length; i++)
|
||||
l_tPose.muscles[i] = ms_tposeMuscles[i];
|
||||
m_poseHandler.SetHumanPose(ref l_tPose);
|
||||
|
@ -353,7 +300,7 @@ namespace ml_lme
|
|||
PlayerSetup.Instance._animator.transform
|
||||
);
|
||||
m_leftIK.solver.arm.target = m_leftHandTarget;
|
||||
m_leftIK.solver.arm.bendGoal = m_leftElbow;
|
||||
m_leftIK.solver.arm.bendGoal = LeapTracking.GetInstance().GetLeftElbow();
|
||||
m_leftIK.solver.arm.bendGoalWeight = (m_trackElbows ? 1f : 0f);
|
||||
m_leftIK.enabled = (m_enabled && !m_fingersOnly);
|
||||
|
||||
|
@ -368,7 +315,7 @@ namespace ml_lme
|
|||
PlayerSetup.Instance._animator.transform
|
||||
);
|
||||
m_rightIK.solver.arm.target = m_rightHandTarget;
|
||||
m_rightIK.solver.arm.bendGoal = m_rightElbow;
|
||||
m_rightIK.solver.arm.bendGoal = LeapTracking.GetInstance().GetRightElbow();
|
||||
m_rightIK.solver.arm.bendGoalWeight = (m_trackElbows ? 1f : 0f);
|
||||
m_rightIK.enabled = (m_enabled && !m_fingersOnly);
|
||||
|
||||
|
@ -382,7 +329,7 @@ namespace ml_lme
|
|||
}
|
||||
}
|
||||
|
||||
public void OnCalibrate()
|
||||
internal void OnCalibrate()
|
||||
{
|
||||
if(m_vrIK != null)
|
||||
{
|
||||
|
@ -421,14 +368,14 @@ namespace ml_lme
|
|||
{
|
||||
if(m_leftTargetActive)
|
||||
{
|
||||
m_vrIK.solver.leftArm.target = IKSystem.Instance.leftHandAnchor;
|
||||
m_vrIK.solver.leftArm.target = (m_inVR ? IKSystem.Instance.leftHandAnchor : null);
|
||||
m_vrIK.solver.leftArm.bendGoal = m_origElbowLeft;
|
||||
m_vrIK.solver.leftArm.bendGoalWeight = ((m_origElbowLeft != null) ? 1f : 0f);
|
||||
m_leftTargetActive = false;
|
||||
}
|
||||
if(m_rightTargetActive)
|
||||
{
|
||||
m_vrIK.solver.rightArm.target = IKSystem.Instance.rightHandAnchor;
|
||||
m_vrIK.solver.rightArm.target = (m_inVR ? IKSystem.Instance.rightHandAnchor : null);
|
||||
m_vrIK.solver.rightArm.bendGoal = m_origElbowRight;
|
||||
m_vrIK.solver.rightArm.bendGoalWeight = ((m_origElbowRight != null) ? 1f : 0f);
|
||||
m_rightTargetActive = false;
|
||||
|
@ -445,12 +392,6 @@ namespace ml_lme
|
|||
}
|
||||
}
|
||||
|
||||
void RefreshFingersTracking()
|
||||
{
|
||||
CVRInputManager.Instance.individualFingerTracking = (m_enabled || (m_isInVR && Utils.AreKnucklesInUse() && !(bool)ms_indexGestureToggle.GetValue(m_steamVrModule)));
|
||||
IKSystem.Instance.FingerSystem.controlActive = CVRInputManager.Instance.individualFingerTracking;
|
||||
}
|
||||
|
||||
static void UpdatePoseMuscle(ref HumanPose p_pose, int p_index, float p_value)
|
||||
{
|
||||
if(p_pose.muscles.Length > p_index)
|
||||
|
|
221
ml_lme/LeapTracking.cs
Normal file
221
ml_lme/LeapTracking.cs
Normal file
|
@ -0,0 +1,221 @@
|
|||
using ABI_RC.Core.Player;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_lme
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
class LeapTracking : MonoBehaviour
|
||||
{
|
||||
static LeapTracking ms_instance = null;
|
||||
static Quaternion ms_identityRotation = Quaternion.identity;
|
||||
|
||||
bool m_inVR = false;
|
||||
|
||||
GameObject m_leapHandLeft = null;
|
||||
GameObject m_leapHandRight = null;
|
||||
GameObject m_leapElbowLeft = null;
|
||||
GameObject m_leapElbowRight = null;
|
||||
GameObject m_leapControllerModel = null;
|
||||
|
||||
public static LeapTracking GetInstance() => ms_instance;
|
||||
|
||||
void Start()
|
||||
{
|
||||
if(ms_instance == null)
|
||||
ms_instance = this;
|
||||
|
||||
m_inVR = Utils.IsInVR();
|
||||
|
||||
m_leapHandLeft = new GameObject("LeapHandLeft");
|
||||
m_leapHandLeft.transform.parent = this.transform;
|
||||
m_leapHandLeft.transform.localPosition = Vector3.zero;
|
||||
m_leapHandLeft.transform.localRotation = Quaternion.identity;
|
||||
|
||||
m_leapHandRight = new GameObject("LeapHandRight");
|
||||
m_leapHandRight.transform.parent = this.transform;
|
||||
m_leapHandRight.transform.localPosition = Vector3.zero;
|
||||
m_leapHandRight.transform.localRotation = Quaternion.identity;
|
||||
|
||||
m_leapElbowLeft = new GameObject("LeapElbowLeft");
|
||||
m_leapElbowLeft.transform.parent = this.transform;
|
||||
m_leapElbowLeft.transform.localPosition = Vector3.zero;
|
||||
m_leapElbowLeft.transform.localRotation = Quaternion.identity;
|
||||
|
||||
m_leapElbowRight = new GameObject("LeapElbowRight");
|
||||
m_leapElbowRight.transform.parent = this.transform;
|
||||
m_leapElbowRight.transform.localPosition = Vector3.zero;
|
||||
m_leapElbowRight.transform.localRotation = Quaternion.identity;
|
||||
|
||||
m_leapControllerModel = AssetsHandler.GetAsset("assets/models/leapmotion/leap_motion_1_0.obj");
|
||||
if(m_leapControllerModel != null)
|
||||
{
|
||||
m_leapControllerModel.name = "LeapModel";
|
||||
m_leapControllerModel.transform.parent = this.transform;
|
||||
m_leapControllerModel.transform.localPosition = Vector3.zero;
|
||||
m_leapControllerModel.transform.localRotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
Settings.DesktopOffsetChange += this.OnDesktopOffsetChange;
|
||||
Settings.ModelVisibilityChange += this.OnModelVisibilityChange;
|
||||
Settings.TrackingModeChange += this.OnTrackingModeChange;
|
||||
Settings.RootAngleChange += this.OnRootAngleChange;
|
||||
Settings.HeadAttachChange += this.OnHeadAttachChange;
|
||||
Settings.HeadOffsetChange += this.OnHeadOffsetChange;
|
||||
|
||||
MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer());
|
||||
|
||||
OnModelVisibilityChange(Settings.ModelVisibility);
|
||||
OnTrackingModeChange(Settings.TrackingMode);
|
||||
OnRootAngleChange(Settings.RootAngle);
|
||||
}
|
||||
|
||||
IEnumerator WaitForLocalPlayer()
|
||||
{
|
||||
while(PlayerSetup.Instance == null)
|
||||
yield return null;
|
||||
|
||||
OnDesktopOffsetChange(Settings.DesktopOffset);
|
||||
OnHeadAttachChange(Settings.HeadAttach);
|
||||
OnHeadOffsetChange(Settings.HeadOffset);
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
if(ms_instance == this)
|
||||
ms_instance = null;
|
||||
|
||||
Settings.DesktopOffsetChange -= this.OnDesktopOffsetChange;
|
||||
Settings.ModelVisibilityChange -= this.OnModelVisibilityChange;
|
||||
Settings.TrackingModeChange -= this.OnTrackingModeChange;
|
||||
Settings.RootAngleChange -= this.OnRootAngleChange;
|
||||
Settings.HeadAttachChange -= this.OnHeadAttachChange;
|
||||
Settings.HeadOffsetChange -= this.OnHeadOffsetChange;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if(Settings.Enabled)
|
||||
{
|
||||
GestureMatcher.LeapData l_data = LeapManager.GetInstance().GetLatestData();
|
||||
|
||||
if(l_data.m_leftHand.m_present)
|
||||
{
|
||||
Utils.LeapToUnity(ref l_data.m_leftHand.m_position, ref l_data.m_leftHand.m_rotation, Settings.TrackingMode);
|
||||
m_leapHandLeft.transform.localPosition = l_data.m_leftHand.m_position;
|
||||
m_leapHandLeft.transform.localRotation = l_data.m_leftHand.m_rotation;
|
||||
|
||||
Utils.LeapToUnity(ref l_data.m_leftHand.m_elbowPosition, ref ms_identityRotation, Settings.TrackingMode);
|
||||
m_leapElbowLeft.transform.localPosition = l_data.m_leftHand.m_elbowPosition;
|
||||
}
|
||||
|
||||
if(l_data.m_rightHand.m_present)
|
||||
{
|
||||
Utils.LeapToUnity(ref l_data.m_rightHand.m_position, ref l_data.m_rightHand.m_rotation, Settings.TrackingMode);
|
||||
m_leapHandRight.transform.localPosition = l_data.m_rightHand.m_position;
|
||||
m_leapHandRight.transform.localRotation = l_data.m_rightHand.m_rotation;
|
||||
|
||||
Utils.LeapToUnity(ref l_data.m_rightHand.m_elbowPosition, ref ms_identityRotation, Settings.TrackingMode);
|
||||
m_leapElbowRight.transform.localPosition = l_data.m_rightHand.m_elbowPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Transform GetLeftHand() => m_leapHandLeft.transform;
|
||||
public Transform GetRightHand() => m_leapHandRight.transform;
|
||||
public Transform GetLeftElbow() => m_leapElbowLeft.transform;
|
||||
public Transform GetRightElbow() => m_leapElbowRight.transform;
|
||||
|
||||
// Settings
|
||||
void OnDesktopOffsetChange(Vector3 p_offset)
|
||||
{
|
||||
if(!Settings.HeadAttach)
|
||||
{
|
||||
if(!m_inVR)
|
||||
this.transform.localPosition = p_offset * PlayerSetup.Instance.vrCameraRig.transform.localScale.x;
|
||||
else
|
||||
this.transform.localPosition = p_offset;
|
||||
}
|
||||
}
|
||||
|
||||
void OnModelVisibilityChange(bool p_state)
|
||||
{
|
||||
m_leapControllerModel.SetActive(p_state);
|
||||
}
|
||||
|
||||
void OnTrackingModeChange(Settings.LeapTrackingMode p_mode)
|
||||
{
|
||||
switch(p_mode)
|
||||
{
|
||||
case Settings.LeapTrackingMode.Screentop:
|
||||
m_leapControllerModel.transform.localRotation = Quaternion.Euler(0f, 0f, 180f);
|
||||
break;
|
||||
case Settings.LeapTrackingMode.Desktop:
|
||||
m_leapControllerModel.transform.localRotation = Quaternion.identity;
|
||||
break;
|
||||
case Settings.LeapTrackingMode.HMD:
|
||||
m_leapControllerModel.transform.localRotation = Quaternion.Euler(270f, 180f, 0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnRootAngleChange(Vector3 p_angle)
|
||||
{
|
||||
this.transform.localRotation = Quaternion.Euler(p_angle);
|
||||
}
|
||||
|
||||
void OnHeadAttachChange(bool p_state)
|
||||
{
|
||||
if(p_state)
|
||||
{
|
||||
if(!m_inVR)
|
||||
{
|
||||
this.transform.parent = PlayerSetup.Instance.desktopCamera.transform;
|
||||
this.transform.localPosition = Settings.HeadOffset * PlayerSetup.Instance.vrCameraRig.transform.localScale.x;
|
||||
this.transform.localScale = PlayerSetup.Instance.vrCameraRig.transform.localScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.transform.parent = PlayerSetup.Instance.vrCamera.transform;
|
||||
this.transform.localPosition = Settings.HeadOffset;
|
||||
this.transform.localScale = Vector3.one;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!m_inVR)
|
||||
{
|
||||
this.transform.parent = PlayerSetup.Instance.desktopCameraRig.transform;
|
||||
this.transform.localPosition = Settings.DesktopOffset * PlayerSetup.Instance.vrCameraRig.transform.localScale.x;
|
||||
this.transform.localScale = PlayerSetup.Instance.vrCameraRig.transform.localScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.transform.parent = PlayerSetup.Instance.vrCameraRig.transform;
|
||||
this.transform.localPosition = Settings.DesktopOffset;
|
||||
this.transform.localScale = Vector3.one;
|
||||
}
|
||||
}
|
||||
|
||||
this.transform.localRotation = Quaternion.Euler(Settings.RootAngle);
|
||||
}
|
||||
|
||||
void OnHeadOffsetChange(Vector3 p_offset)
|
||||
{
|
||||
if(Settings.HeadAttach)
|
||||
{
|
||||
if(!m_inVR)
|
||||
this.transform.localPosition = p_offset * PlayerSetup.Instance.vrCameraRig.transform.localScale.x;
|
||||
else
|
||||
this.transform.localPosition = p_offset;
|
||||
}
|
||||
}
|
||||
|
||||
// Game events
|
||||
internal void OnAvatarSetup()
|
||||
{
|
||||
m_inVR = Utils.IsInVR();
|
||||
OnHeadAttachChange(Settings.HeadAttach);
|
||||
}
|
||||
}
|
||||
}
|
336
ml_lme/Main.cs
336
ml_lme/Main.cs
|
@ -1,6 +1,6 @@
|
|||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.UI;
|
||||
using ABI_RC.Systems.IK.SubSystems;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
|
@ -11,16 +11,7 @@ namespace ml_lme
|
|||
{
|
||||
static LeapMotionExtension ms_instance = null;
|
||||
|
||||
Leap.Controller m_leapController = null;
|
||||
GestureMatcher.GesturesData m_gesturesData = null;
|
||||
|
||||
GameObject m_leapTrackingRoot = null;
|
||||
GameObject[] m_leapHands = null;
|
||||
GameObject[] m_leapElbows = null;
|
||||
GameObject m_leapControllerModel = null;
|
||||
LeapTracked m_leapTracked = null;
|
||||
|
||||
bool m_isInVR = false;
|
||||
LeapManager m_leapManager = null;
|
||||
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
|
@ -28,26 +19,8 @@ namespace ml_lme
|
|||
ms_instance = this;
|
||||
|
||||
DependenciesHandler.ExtractDependencies();
|
||||
|
||||
Settings.Init();
|
||||
Settings.EnabledChange += this.OnEnableChange;
|
||||
Settings.DesktopOffsetChange += this.OnDesktopOffsetChange;
|
||||
Settings.ModelVisibilityChange += this.OnModelVisibilityChange;
|
||||
Settings.TrackingModeChange += this.OnTrackingModeChange;
|
||||
Settings.RootAngleChange += this.OnRootAngleChange;
|
||||
Settings.HeadAttachChange += this.OnHeadAttachChange;
|
||||
Settings.HeadOffsetChange += this.OnHeadOffsetChange;
|
||||
|
||||
m_leapController = new Leap.Controller();
|
||||
m_leapController.Device += this.OnLeapDeviceInitialized;
|
||||
m_leapController.DeviceFailure += this.OnLeapDeviceFailure;
|
||||
m_leapController.DeviceLost += this.OnLeapDeviceLost;
|
||||
m_leapController.Connect += this.OnLeapServiceConnect;
|
||||
m_leapController.Disconnect += this.OnLeapServiceDisconnect;
|
||||
|
||||
m_gesturesData = new GestureMatcher.GesturesData();
|
||||
m_leapHands = new GameObject[GestureMatcher.GesturesData.ms_handsCount];
|
||||
m_leapElbows = new GameObject[GestureMatcher.GesturesData.ms_handsCount];
|
||||
AssetsHandler.Load();
|
||||
|
||||
// Patches
|
||||
HarmonyInstance.Patch(
|
||||
|
@ -65,280 +38,27 @@ namespace ml_lme
|
|||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(LeapMotionExtension).GetMethod(nameof(OnCalibrate_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
HarmonyInstance.Patch(
|
||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.SetControllerRayScale)),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(LeapMotionExtension).GetMethod(nameof(OnRayScale_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
|
||||
MelonLoader.MelonCoroutines.Start(CreateTrackingObjects());
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator CreateTrackingObjects()
|
||||
{
|
||||
AssetsHandler.Load();
|
||||
|
||||
while(PlayerSetup.Instance == null)
|
||||
yield return null;
|
||||
while(PlayerSetup.Instance.desktopCameraRig == null)
|
||||
yield return null;
|
||||
while(PlayerSetup.Instance.desktopCamera == null)
|
||||
yield return null;
|
||||
while(PlayerSetup.Instance.vrCameraRig == null)
|
||||
yield return null;
|
||||
while(PlayerSetup.Instance.vrCamera == null)
|
||||
yield return null;
|
||||
|
||||
m_isInVR = Utils.IsInVR();
|
||||
|
||||
m_leapTrackingRoot = new GameObject("[LeapRoot]");
|
||||
|
||||
for(int i = 0; i < GestureMatcher.GesturesData.ms_handsCount; i++)
|
||||
{
|
||||
m_leapHands[i] = new GameObject("LeapHand" + i);
|
||||
m_leapHands[i].transform.parent = m_leapTrackingRoot.transform;
|
||||
m_leapHands[i].transform.localPosition = Vector3.zero;
|
||||
m_leapHands[i].transform.localRotation = Quaternion.identity;
|
||||
|
||||
m_leapElbows[i] = new GameObject("LeapElbow" + i);
|
||||
m_leapElbows[i].transform.parent = m_leapTrackingRoot.transform;
|
||||
m_leapElbows[i].transform.localPosition = Vector3.zero;
|
||||
m_leapElbows[i].transform.localRotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
m_leapControllerModel = AssetsHandler.GetAsset("assets/models/leapmotion/leap_motion_1_0.obj");
|
||||
if(m_leapControllerModel != null)
|
||||
{
|
||||
m_leapControllerModel.name = "LeapModel";
|
||||
m_leapControllerModel.transform.parent = m_leapTrackingRoot.transform;
|
||||
m_leapControllerModel.transform.localPosition = Vector3.zero;
|
||||
m_leapControllerModel.transform.localRotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
// Player setup
|
||||
m_leapTracked = PlayerSetup.Instance.gameObject.AddComponent<LeapTracked>();
|
||||
m_leapTracked.SetTransforms(m_leapHands[0].transform, m_leapHands[1].transform, m_leapElbows[0].transform, m_leapElbows[1].transform);
|
||||
m_leapTracked.SetEnabled(Settings.Enabled);
|
||||
m_leapTracked.SetTrackElbows(Settings.TrackElbows);
|
||||
m_leapTracked.SetFingersOnly(Settings.FingersOnly);
|
||||
|
||||
OnEnableChange(Settings.Enabled);
|
||||
OnModelVisibilityChange(Settings.ModelVisibility);
|
||||
OnTrackingModeChange(Settings.TrackingMode);
|
||||
OnHeadAttachChange(Settings.HeadAttach); // Includes offsets and parenting
|
||||
MelonLoader.MelonCoroutines.Start(WaitForRootLogic());
|
||||
}
|
||||
|
||||
public override void OnDeinitializeMelon()
|
||||
{
|
||||
if(ms_instance == this)
|
||||
ms_instance = null;
|
||||
|
||||
m_leapController?.StopConnection();
|
||||
m_leapController?.Dispose();
|
||||
m_leapController = null;
|
||||
|
||||
m_gesturesData = null;
|
||||
}
|
||||
|
||||
public override void OnUpdate()
|
||||
IEnumerator WaitForRootLogic()
|
||||
{
|
||||
if(Settings.Enabled)
|
||||
{
|
||||
for(int i = 0; i < GestureMatcher.GesturesData.ms_handsCount; i++)
|
||||
m_gesturesData.m_handsPresenses[i] = false;
|
||||
while(ABI_RC.Core.RootLogic.Instance == null)
|
||||
yield return null;
|
||||
|
||||
if((m_leapController != null) && m_leapController.IsConnected)
|
||||
{
|
||||
Leap.Frame l_frame = m_leapController.Frame();
|
||||
if(l_frame != null)
|
||||
{
|
||||
GestureMatcher.GetGestures(l_frame, ref m_gesturesData);
|
||||
|
||||
for(int i = 0; i < GestureMatcher.GesturesData.ms_handsCount; i++)
|
||||
{
|
||||
if((m_leapHands[i] != null) && m_gesturesData.m_handsPresenses[i])
|
||||
{
|
||||
Vector3 l_pos = m_gesturesData.m_handsPositons[i];
|
||||
Quaternion l_rot = m_gesturesData.m_handsRotations[i];
|
||||
Utils.LeapToUnity(ref l_pos, ref l_rot, Settings.TrackingMode);
|
||||
m_leapHands[i].transform.localPosition = l_pos;
|
||||
m_leapHands[i].transform.localRotation = l_rot;
|
||||
|
||||
l_pos = m_gesturesData.m_elbowsPositions[i];
|
||||
Utils.LeapToUnity(ref l_pos, ref l_rot, Settings.TrackingMode);
|
||||
m_leapElbows[i].transform.localPosition = l_pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(m_leapTracked != null)
|
||||
m_leapTracked.UpdateTracking(m_gesturesData);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnLateUpdate()
|
||||
{
|
||||
if(Settings.Enabled && !m_isInVR && (m_leapTracked != null))
|
||||
m_leapTracked.UpdateTrackingLate(m_gesturesData);
|
||||
}
|
||||
|
||||
// Settings changes
|
||||
void OnEnableChange(bool p_state)
|
||||
{
|
||||
if(p_state)
|
||||
{
|
||||
m_leapController?.StartConnection();
|
||||
UpdateDeviceTrackingMode();
|
||||
}
|
||||
else
|
||||
m_leapController?.StopConnection();
|
||||
}
|
||||
|
||||
void OnDesktopOffsetChange(Vector3 p_offset)
|
||||
{
|
||||
if((m_leapTrackingRoot != null) && !Settings.HeadAttach)
|
||||
{
|
||||
if(!m_isInVR)
|
||||
m_leapTrackingRoot.transform.localPosition = p_offset * PlayerSetup.Instance.vrCameraRig.transform.localScale.x;
|
||||
else
|
||||
m_leapTrackingRoot.transform.localPosition = p_offset;
|
||||
}
|
||||
}
|
||||
|
||||
void OnModelVisibilityChange(bool p_state)
|
||||
{
|
||||
if(m_leapControllerModel != null)
|
||||
m_leapControllerModel.SetActive(p_state);
|
||||
}
|
||||
|
||||
void OnTrackingModeChange(Settings.LeapTrackingMode p_mode)
|
||||
{
|
||||
if(Settings.Enabled)
|
||||
UpdateDeviceTrackingMode();
|
||||
|
||||
if(m_leapControllerModel != null)
|
||||
{
|
||||
switch(p_mode)
|
||||
{
|
||||
case Settings.LeapTrackingMode.Screentop:
|
||||
m_leapControllerModel.transform.localRotation = Quaternion.Euler(0f, 0f, 180f);
|
||||
break;
|
||||
case Settings.LeapTrackingMode.Desktop:
|
||||
m_leapControllerModel.transform.localRotation = Quaternion.identity;
|
||||
break;
|
||||
case Settings.LeapTrackingMode.HMD:
|
||||
m_leapControllerModel.transform.localRotation = Quaternion.Euler(270f, 180f, 0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnRootAngleChange(Vector3 p_angle)
|
||||
{
|
||||
if(m_leapTrackingRoot != null)
|
||||
m_leapTrackingRoot.transform.localRotation = Quaternion.Euler(p_angle);
|
||||
}
|
||||
|
||||
void OnHeadAttachChange(bool p_state)
|
||||
{
|
||||
if(m_leapTrackingRoot != null)
|
||||
{
|
||||
if(p_state)
|
||||
{
|
||||
if(!m_isInVR)
|
||||
{
|
||||
m_leapTrackingRoot.transform.parent = PlayerSetup.Instance.desktopCamera.transform;
|
||||
m_leapTrackingRoot.transform.localPosition = Settings.HeadOffset * PlayerSetup.Instance.vrCameraRig.transform.localScale.x;
|
||||
m_leapTrackingRoot.transform.localScale = PlayerSetup.Instance.vrCameraRig.transform.localScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_leapTrackingRoot.transform.parent = PlayerSetup.Instance.vrCamera.transform;
|
||||
m_leapTrackingRoot.transform.localPosition = Settings.HeadOffset;
|
||||
m_leapTrackingRoot.transform.localScale = Vector3.one;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!m_isInVR)
|
||||
{
|
||||
m_leapTrackingRoot.transform.parent = PlayerSetup.Instance.desktopCameraRig.transform;
|
||||
m_leapTrackingRoot.transform.localPosition = Settings.DesktopOffset * PlayerSetup.Instance.vrCameraRig.transform.localScale.x;
|
||||
m_leapTrackingRoot.transform.localScale = PlayerSetup.Instance.vrCameraRig.transform.localScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_leapTrackingRoot.transform.parent = PlayerSetup.Instance.vrCameraRig.transform;
|
||||
m_leapTrackingRoot.transform.localPosition = Settings.DesktopOffset;
|
||||
m_leapTrackingRoot.transform.localScale = Vector3.one;
|
||||
}
|
||||
}
|
||||
|
||||
m_leapTrackingRoot.transform.localRotation = Quaternion.Euler(Settings.RootAngle);
|
||||
}
|
||||
}
|
||||
|
||||
void OnHeadOffsetChange(Vector3 p_offset)
|
||||
{
|
||||
if((m_leapTrackingRoot != null) && Settings.HeadAttach)
|
||||
{
|
||||
if(!m_isInVR)
|
||||
m_leapTrackingRoot.transform.localPosition = p_offset * PlayerSetup.Instance.vrCameraRig.transform.localScale.x;
|
||||
else
|
||||
m_leapTrackingRoot.transform.localPosition = p_offset;
|
||||
}
|
||||
}
|
||||
|
||||
// Internal utility
|
||||
void UpdateDeviceTrackingMode()
|
||||
{
|
||||
m_leapController?.ClearPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_SCREENTOP, null);
|
||||
m_leapController?.ClearPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD, null);
|
||||
|
||||
switch(Settings.TrackingMode)
|
||||
{
|
||||
case Settings.LeapTrackingMode.Screentop:
|
||||
m_leapController?.SetPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_SCREENTOP, null);
|
||||
break;
|
||||
case Settings.LeapTrackingMode.HMD:
|
||||
m_leapController?.SetPolicy(Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Leap events
|
||||
void OnLeapDeviceInitialized(object p_sender, Leap.DeviceEventArgs p_args)
|
||||
{
|
||||
if(Settings.Enabled)
|
||||
{
|
||||
m_leapController?.SubscribeToDeviceEvents(p_args.Device);
|
||||
UpdateDeviceTrackingMode();
|
||||
}
|
||||
|
||||
if(CohtmlHud.Instance != null)
|
||||
CohtmlHud.Instance.ViewDropText("Leap Motion Extension", "Device initialized");
|
||||
}
|
||||
|
||||
void OnLeapDeviceFailure(object p_sender, Leap.DeviceFailureEventArgs p_args)
|
||||
{
|
||||
if(CohtmlHud.Instance != null)
|
||||
CohtmlHud.Instance.ViewDropText("Leap Motion Extension", "Device failure, code " + p_args.ErrorCode + ": " + p_args.ErrorMessage);
|
||||
}
|
||||
|
||||
void OnLeapDeviceLost(object p_sender, Leap.DeviceEventArgs p_args)
|
||||
{
|
||||
m_leapController?.UnsubscribeFromDeviceEvents(p_args.Device);
|
||||
|
||||
if(CohtmlHud.Instance != null)
|
||||
CohtmlHud.Instance.ViewDropText("Leap Motion Extension", "Device lost");
|
||||
}
|
||||
|
||||
void OnLeapServiceConnect(object p_sender, Leap.ConnectionEventArgs p_args)
|
||||
{
|
||||
if(CohtmlHud.Instance != null)
|
||||
CohtmlHud.Instance.ViewDropText("Leap Motion Extension", "Service connected");
|
||||
}
|
||||
|
||||
void OnLeapServiceDisconnect(object p_sender, Leap.ConnectionLostEventArgs p_args)
|
||||
{
|
||||
if(CohtmlHud.Instance != null)
|
||||
CohtmlHud.Instance.ViewDropText("Leap Motion Extension", "Service disconnected");
|
||||
m_leapManager = new GameObject("LeapMotionManager").AddComponent<LeapManager>();
|
||||
}
|
||||
|
||||
// Patches
|
||||
|
@ -347,8 +67,8 @@ namespace ml_lme
|
|||
{
|
||||
try
|
||||
{
|
||||
if(m_leapTracked != null)
|
||||
m_leapTracked.OnAvatarClear();
|
||||
if(m_leapManager != null)
|
||||
m_leapManager.OnAvatarClear();
|
||||
}
|
||||
catch(System.Exception e)
|
||||
{
|
||||
|
@ -361,12 +81,8 @@ namespace ml_lme
|
|||
{
|
||||
try
|
||||
{
|
||||
m_isInVR = Utils.IsInVR();
|
||||
|
||||
if(m_leapTracked != null)
|
||||
m_leapTracked.OnSetupAvatar();
|
||||
|
||||
OnHeadAttachChange(Settings.HeadAttach);
|
||||
if(m_leapManager != null)
|
||||
m_leapManager.OnAvatarSetup();
|
||||
}
|
||||
catch(System.Exception e)
|
||||
{
|
||||
|
@ -379,8 +95,22 @@ namespace ml_lme
|
|||
{
|
||||
try
|
||||
{
|
||||
if(m_leapTracked != null)
|
||||
m_leapTracked.OnCalibrate();
|
||||
if(m_leapManager != null)
|
||||
m_leapManager.OnCalibrate();
|
||||
}
|
||||
catch(System.Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnRayScale_Postfix(float __0) => ms_instance?.OnRayScale(__0);
|
||||
void OnRayScale(float p_scale)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(m_leapManager != null)
|
||||
m_leapManager.OnRayScale(p_scale);
|
||||
}
|
||||
catch(System.Exception e)
|
||||
{
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyTitle("LeapMotionExtension")]
|
||||
[assembly: AssemblyVersion("1.2.9")]
|
||||
[assembly: AssemblyFileVersion("1.2.9")]
|
||||
[assembly: AssemblyVersion("1.3.0")]
|
||||
[assembly: AssemblyFileVersion("1.3.0")]
|
||||
|
||||
[assembly: MelonLoader.MelonInfo(typeof(ml_lme.LeapMotionExtension), "LeapMotionExtension", "1.2.9", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||
[assembly: MelonLoader.MelonInfo(typeof(ml_lme.LeapMotionExtension), "LeapMotionExtension", "1.3.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)]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Leap Motion Extension
|
||||
This mod allows you to use your Leap Motion controller for hands and fingers visual tracking.
|
||||
This mod allows you to use your Leap Motion controller for hands and fingers tracking.
|
||||
|
||||
[](https://youtu.be/nak1C8uibgc)
|
||||
|
||||
|
@ -21,3 +21,6 @@ Available mod's settings in `Settings - Implementation - Leap Motion Tracking`:
|
|||
* **Track elbows:** elbows tracking, works best in `Screentop` and `HMD` tracking modes, `true` by default.
|
||||
* **Fingers tracking only:** apply only fingers tracking, disabled by default.
|
||||
* **Model visibility:** show Leap Motion controller model, useful for tracking visualizing, disabled by default.
|
||||
* **Interaction input:** enables in-game interactions (props, menu and etc.); `true` by default.
|
||||
** Note: Suggested to use with disabled `Settings - Input & Key-Bindings - Use grip to grab`.
|
||||
* **Hold/Release gesture threadhold:** limits for interaction/grip activation based on hand gesture; 50 by default.
|
||||
|
|
|
@ -31,7 +31,10 @@ namespace ml_lme
|
|||
HeadX,
|
||||
HeadY,
|
||||
HeadZ,
|
||||
TrackElbows
|
||||
TrackElbows,
|
||||
Input,
|
||||
HoldThreadhold,
|
||||
ReleaseThreadhold
|
||||
};
|
||||
|
||||
static bool ms_enabled = false;
|
||||
|
@ -43,6 +46,9 @@ namespace ml_lme
|
|||
static bool ms_headAttach = false;
|
||||
static Vector3 ms_headOffset = new Vector3(0f, -0.3f, 0.15f);
|
||||
static bool ms_trackElbows = true;
|
||||
static bool ms_input = true;
|
||||
static float ms_holdThreadhold = 0.5f;
|
||||
static float ms_releaseThreadhold = 0.5f;
|
||||
|
||||
static MelonLoader.MelonPreferences_Category ms_category = null;
|
||||
static List<MelonLoader.MelonPreferences_Entry> ms_entries = null;
|
||||
|
@ -56,27 +62,35 @@ namespace ml_lme
|
|||
static public event Action<bool> HeadAttachChange;
|
||||
static public event Action<Vector3> HeadOffsetChange;
|
||||
static public event Action<bool> TrackElbowsChange;
|
||||
static public event Action<bool> InputChange;
|
||||
static public event Action<float> HoldThreadholdChange;
|
||||
static public event Action<float> ReleaseThreadholdChange;
|
||||
|
||||
public static void Init()
|
||||
internal static void Init()
|
||||
{
|
||||
ms_category = MelonLoader.MelonPreferences.CreateCategory("LME");
|
||||
|
||||
ms_entries = new List<MelonLoader.MelonPreferences_Entry>();
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.Enabled.ToString(), ms_enabled));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.DesktopX.ToString(), 0));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.DesktopY.ToString(), -45));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.DesktopZ.ToString(), 30));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.FingersOnly.ToString(), ms_modelVisibility));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.Model.ToString(), ms_modelVisibility));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.Mode.ToString(), (int)ms_trackingMode));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.AngleX.ToString(), 0));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.AngleY.ToString(), 0));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.AngleZ.ToString(), 0));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.Head.ToString(), ms_headAttach));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.HeadX.ToString(), 0));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.HeadY.ToString(), -30));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.HeadZ.ToString(), 15));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.TrackElbows.ToString(), true));
|
||||
ms_entries = new List<MelonLoader.MelonPreferences_Entry>()
|
||||
{
|
||||
ms_category.CreateEntry(ModSetting.Enabled.ToString(), ms_enabled),
|
||||
ms_category.CreateEntry(ModSetting.DesktopX.ToString(), 0),
|
||||
ms_category.CreateEntry(ModSetting.DesktopY.ToString(), -45),
|
||||
ms_category.CreateEntry(ModSetting.DesktopZ.ToString(), 30),
|
||||
ms_category.CreateEntry(ModSetting.FingersOnly.ToString(), ms_modelVisibility),
|
||||
ms_category.CreateEntry(ModSetting.Model.ToString(), ms_modelVisibility),
|
||||
ms_category.CreateEntry(ModSetting.Mode.ToString(), (int)ms_trackingMode),
|
||||
ms_category.CreateEntry(ModSetting.AngleX.ToString(), 0),
|
||||
ms_category.CreateEntry(ModSetting.AngleY.ToString(), 0),
|
||||
ms_category.CreateEntry(ModSetting.AngleZ.ToString(), 0),
|
||||
ms_category.CreateEntry(ModSetting.Head.ToString(), ms_headAttach),
|
||||
ms_category.CreateEntry(ModSetting.HeadX.ToString(), 0),
|
||||
ms_category.CreateEntry(ModSetting.HeadY.ToString(), -30),
|
||||
ms_category.CreateEntry(ModSetting.HeadZ.ToString(), 15),
|
||||
ms_category.CreateEntry(ModSetting.TrackElbows.ToString(), true),
|
||||
ms_category.CreateEntry(ModSetting.Input.ToString(), true),
|
||||
ms_category.CreateEntry(ModSetting.HoldThreadhold.ToString(), 50),
|
||||
ms_category.CreateEntry(ModSetting.ReleaseThreadhold.ToString(), 50),
|
||||
};
|
||||
|
||||
Load();
|
||||
|
||||
|
@ -129,6 +143,9 @@ namespace ml_lme
|
|||
(int)ms_entries[(int)ModSetting.HeadZ].BoxedValue
|
||||
) * 0.01f;
|
||||
ms_trackElbows = (bool)ms_entries[(int)ModSetting.TrackElbows].BoxedValue;
|
||||
ms_input = (bool)ms_entries[(int)ModSetting.Input].BoxedValue;
|
||||
ms_holdThreadhold = (int)ms_entries[(int)ModSetting.HoldThreadhold].BoxedValue * 0.01f;
|
||||
ms_releaseThreadhold = (int)ms_entries[(int)ModSetting.ReleaseThreadhold].BoxedValue * 0.01f;
|
||||
}
|
||||
|
||||
static void OnToggleUpdate(string p_name, string p_value)
|
||||
|
@ -171,6 +188,13 @@ namespace ml_lme
|
|||
TrackElbowsChange?.Invoke(ms_trackElbows);
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.Input:
|
||||
{
|
||||
ms_input = bool.Parse(p_value);
|
||||
InputChange?.Invoke(ms_input);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ms_entries[(int)l_setting].BoxedValue = bool.Parse(p_value);
|
||||
|
@ -241,6 +265,18 @@ namespace ml_lme
|
|||
HeadOffsetChange?.Invoke(ms_headOffset);
|
||||
}
|
||||
break;
|
||||
case ModSetting.HoldThreadhold:
|
||||
{
|
||||
ms_holdThreadhold = int.Parse(p_value) * 0.01f;
|
||||
HoldThreadholdChange?.Invoke(ms_holdThreadhold);
|
||||
}
|
||||
break;
|
||||
case ModSetting.ReleaseThreadhold:
|
||||
{
|
||||
ms_releaseThreadhold = int.Parse(p_value) * 0.01f;
|
||||
ReleaseThreadholdChange?.Invoke(ms_releaseThreadhold);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ms_entries[(int)l_setting].BoxedValue = int.Parse(p_value);
|
||||
|
@ -301,5 +337,17 @@ namespace ml_lme
|
|||
{
|
||||
get => ms_trackElbows;
|
||||
}
|
||||
public static bool Input
|
||||
{
|
||||
get => ms_input;
|
||||
}
|
||||
public static float HoldThreadhold
|
||||
{
|
||||
get => ms_holdThreadhold;
|
||||
}
|
||||
public static float ReleaseThreadhold
|
||||
{
|
||||
get => ms_releaseThreadhold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.UI;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
|
@ -18,6 +19,17 @@ namespace ml_lme
|
|||
return Matrix4x4.TRS(p_pos ? p_transform.position : Vector3.zero, p_rot ? p_transform.rotation : Quaternion.identity, p_scl ? p_transform.lossyScale : Vector3.one);
|
||||
}
|
||||
|
||||
public static void ShowHUDNotification(string p_title, string p_message, string p_small = "", bool p_immediate = false)
|
||||
{
|
||||
if(CohtmlHud.Instance != null)
|
||||
{
|
||||
if(p_immediate)
|
||||
CohtmlHud.Instance.ViewDropTextImmediate(p_title, p_message, p_small);
|
||||
else
|
||||
CohtmlHud.Instance.ViewDropText(p_title, p_message, p_small);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LeapToUnity(ref Vector3 p_pos, ref Quaternion p_rot, Settings.LeapTrackingMode p_mode)
|
||||
{
|
||||
p_pos *= 0.001f;
|
||||
|
|
|
@ -84,7 +84,10 @@
|
|||
<Compile Include="AssetsHandler.cs" />
|
||||
<Compile Include="DependenciesHandler.cs" />
|
||||
<Compile Include="GestureMatcher.cs" />
|
||||
<Compile Include="LeapInput.cs" />
|
||||
<Compile Include="LeapManager.cs" />
|
||||
<Compile Include="LeapTracked.cs" />
|
||||
<Compile Include="LeapTracking.cs" />
|
||||
<Compile Include="Main.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Scripts.cs" />
|
||||
|
|
|
@ -384,6 +384,27 @@ function inp_dropdown_mod_lme(_obj, _callbackName) {
|
|||
<div id="Model" class ="inp_toggle no-scroll" data-current="false"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class ="row-wrapper">
|
||||
<div class ="option-caption">Interaction input: </div>
|
||||
<div class ="option-input">
|
||||
<div id="Input" class ="inp_toggle no-scroll" data-current="false"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class ="row-wrapper">
|
||||
<div class ="option-caption">Hold gesture threadhold: </div>
|
||||
<div class ="option-input">
|
||||
<div id="HoldThreadhold" class ="inp_slider no-scroll" data-min="0" data-max="100" data-current="50"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class ="row-wrapper">
|
||||
<div class ="option-caption">Release gesture threadhold: </div>
|
||||
<div class ="option-input">
|
||||
<div id="ReleaseThreadhold" class ="inp_slider no-scroll" data-min="0" data-max="100" data-current="50"></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
document.getElementById('settings-implementation').appendChild(l_block);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ using UnityEngine;
|
|||
|
||||
namespace ml_pam
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
class ArmMover : MonoBehaviour
|
||||
{
|
||||
static readonly Vector4 ms_pointVector = new Vector4(0f, 0f, 0f, 1f);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue