mirror of
https://github.com/hanetzer/sdraw_mods_cvr.git
synced 2025-09-03 10:29:22 +00:00
Hands visualization
This commit is contained in:
parent
5d2bc0e6b8
commit
f645650659
10 changed files with 155 additions and 5 deletions
|
@ -9,7 +9,8 @@ namespace ml_lme
|
|||
{
|
||||
static readonly List<string> ms_assets = new List<string>()
|
||||
{
|
||||
"leapmotion_controller.asset"
|
||||
"leapmotion_controller.asset",
|
||||
"leapmotion_hands.asset"
|
||||
};
|
||||
|
||||
static Dictionary<string, AssetBundle> ms_loadedAssets = new Dictionary<string, AssetBundle>();
|
||||
|
|
|
@ -22,11 +22,15 @@ namespace ml_lme
|
|||
public readonly float[] m_spreads = null;
|
||||
public readonly float[] m_bends = null;
|
||||
public float m_grabStrength = 0f;
|
||||
public Vector3[] m_fingerPosition;
|
||||
public Quaternion[] m_fingerRotation;
|
||||
|
||||
public HandData()
|
||||
{
|
||||
m_spreads = new float[5];
|
||||
m_bends = new float[5];
|
||||
m_fingerPosition = new Vector3[20];
|
||||
m_fingerRotation = new Quaternion[20];
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
|
@ -37,6 +41,11 @@ namespace ml_lme
|
|||
m_bends[i] = 0f;
|
||||
m_spreads[i] = 0f;
|
||||
}
|
||||
for(int i = 0; i < 20; i++)
|
||||
{
|
||||
m_fingerPosition[i].Set(0f, 0f, 0f);
|
||||
m_fingerRotation[i].Set(0f, 0f, 0f, 1f);
|
||||
}
|
||||
m_grabStrength = 0f;
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +98,9 @@ namespace ml_lme
|
|||
float l_angle = 0f;
|
||||
foreach(Leap.Bone l_bone in l_finger.bones)
|
||||
{
|
||||
p_data.m_fingerPosition[(int)l_finger.Type * 4 + (int)l_bone.Type].Set(l_bone.PrevJoint.x, l_bone.PrevJoint.y, l_bone.PrevJoint.z);
|
||||
p_data.m_fingerRotation[(int)l_finger.Type * 4 + (int)l_bone.Type].Set(l_bone.Rotation.x, l_bone.Rotation.y, l_bone.Rotation.z, l_bone.Rotation.w);
|
||||
|
||||
if(l_bone.Type == Leap.Bone.BoneType.TYPE_METACARPAL)
|
||||
{
|
||||
l_prevSegment = new Quaternion(l_bone.Rotation.x, l_bone.Rotation.y, l_bone.Rotation.z, l_bone.Rotation.w);
|
||||
|
|
|
@ -17,6 +17,9 @@ namespace ml_lme
|
|||
GameObject m_leapElbowLeft = null;
|
||||
GameObject m_leapElbowRight = null;
|
||||
GameObject m_leapControllerModel = null;
|
||||
GameObject m_visualHands = null;
|
||||
VisualHand m_visualHandLeft = null;
|
||||
VisualHand m_visualHandRight = null;
|
||||
|
||||
float m_scaleRelation = 1f;
|
||||
|
||||
|
@ -58,8 +61,21 @@ namespace ml_lme
|
|||
m_leapControllerModel.transform.localRotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
m_visualHands = AssetsHandler.GetAsset("assets/models/hands/leaphands.prefab");
|
||||
if(m_visualHands != null)
|
||||
{
|
||||
m_visualHands.name = "VisualHands";
|
||||
m_visualHands.transform.parent = this.transform;
|
||||
m_visualHands.transform.localPosition = Vector3.zero;
|
||||
m_visualHands.transform.localRotation = Quaternion.identity;
|
||||
|
||||
m_visualHandLeft = new VisualHand(m_visualHands.transform.Find("HandL"), true);
|
||||
m_visualHandRight = new VisualHand(m_visualHands.transform.Find("HandR"), false);
|
||||
}
|
||||
|
||||
Settings.DesktopOffsetChange += this.OnDesktopOffsetChange;
|
||||
Settings.ModelVisibilityChange += this.OnModelVisibilityChange;
|
||||
Settings.VisualHandsChange += this.OnVisualHandsChange;
|
||||
Settings.TrackingModeChange += this.OnTrackingModeChange;
|
||||
Settings.RootAngleChange += this.OnRootAngleChange;
|
||||
Settings.HeadAttachChange += this.OnHeadAttachChange;
|
||||
|
@ -68,6 +84,7 @@ namespace ml_lme
|
|||
MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer());
|
||||
|
||||
OnModelVisibilityChange(Settings.ModelVisibility);
|
||||
OnVisualHandsChange(Settings.VisualHands);
|
||||
OnTrackingModeChange(Settings.TrackingMode);
|
||||
OnRootAngleChange(Settings.RootAngle);
|
||||
}
|
||||
|
@ -102,21 +119,33 @@ namespace ml_lme
|
|||
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);
|
||||
for(int i = 0; i < 20; i++)
|
||||
Utils.LeapToUnity(ref l_data.m_leftHand.m_fingerPosition[i], ref l_data.m_leftHand.m_fingerRotation[i], 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(Settings.VisualHands)
|
||||
m_visualHandLeft?.Update(l_data.m_leftHand);
|
||||
}
|
||||
|
||||
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);
|
||||
for(int i = 0; i < 20; i++)
|
||||
Utils.LeapToUnity(ref l_data.m_rightHand.m_fingerPosition[i], ref l_data.m_rightHand.m_fingerRotation[i], 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;
|
||||
|
||||
if(Settings.VisualHands)
|
||||
m_visualHandRight?.Update(l_data.m_rightHand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -138,6 +167,11 @@ namespace ml_lme
|
|||
m_leapControllerModel.SetActive(p_state);
|
||||
}
|
||||
|
||||
void OnVisualHandsChange(bool p_state)
|
||||
{
|
||||
m_visualHands.SetActive(p_state);
|
||||
}
|
||||
|
||||
void OnTrackingModeChange(Settings.LeapTrackingMode p_mode)
|
||||
{
|
||||
switch(p_mode)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyTitle("LeapMotionExtension")]
|
||||
[assembly: AssemblyVersion("1.3.7")]
|
||||
[assembly: AssemblyFileVersion("1.3.7")]
|
||||
[assembly: AssemblyVersion("1.3.8")]
|
||||
[assembly: AssemblyFileVersion("1.3.8")]
|
||||
|
||||
[assembly: MelonLoader.MelonInfo(typeof(ml_lme.LeapMotionExtension), "LeapMotionExtension", "1.3.7", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||
[assembly: MelonLoader.MelonInfo(typeof(ml_lme.LeapMotionExtension), "LeapMotionExtension", "1.3.8", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||
[assembly: MelonLoader.MelonOptionalDependencies("ml_pmc")]
|
||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
|
|
|
@ -21,6 +21,7 @@ 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:** applies only fingers tracking, disabled by default.
|
||||
* **Model visibility:** shows Leap Motion controller model, useful for tracking visualizing, disabled by default.
|
||||
* **Visualize hands:** shows overlayed hands model, disabled by default.
|
||||
* **Interaction input:** enables in-game interactions (props, menu and etc.); `true` by default.
|
||||
* **Interact gesture threadhold:** activation limit for interaction based on hand gesture; 80 by default.
|
||||
* **Grip gesture threadhold:** activation limit for grip based on hand gesture; 40 by default.
|
||||
|
|
|
@ -34,7 +34,8 @@ namespace ml_lme
|
|||
TrackElbows,
|
||||
Input,
|
||||
InteractThreadhold,
|
||||
GripThreadhold
|
||||
GripThreadhold,
|
||||
VisualHands
|
||||
};
|
||||
|
||||
public static bool Enabled { get; private set; } = false;
|
||||
|
@ -49,6 +50,7 @@ namespace ml_lme
|
|||
public static bool Input { get; private set; } = true;
|
||||
public static float InteractThreadhold { get; private set; } = 0.8f;
|
||||
public static float GripThreadhold { get; private set; } = 0.4f;
|
||||
public static bool VisualHands { get; private set; } = false;
|
||||
|
||||
static MelonLoader.MelonPreferences_Category ms_category = null;
|
||||
static List<MelonLoader.MelonPreferences_Entry> ms_entries = null;
|
||||
|
@ -65,6 +67,7 @@ namespace ml_lme
|
|||
static public event Action<bool> InputChange;
|
||||
static public event Action<float> InteractThreadholdChange;
|
||||
static public event Action<float> GripThreadholdChange;
|
||||
static public event Action<bool> VisualHandsChange;
|
||||
|
||||
internal static void Init()
|
||||
{
|
||||
|
@ -90,6 +93,7 @@ namespace ml_lme
|
|||
ms_category.CreateEntry(ModSetting.Input.ToString(), Input),
|
||||
ms_category.CreateEntry(ModSetting.InteractThreadhold.ToString(), (int)(InteractThreadhold * 100f)),
|
||||
ms_category.CreateEntry(ModSetting.GripThreadhold.ToString(), (int)(GripThreadhold * 100f)),
|
||||
ms_category.CreateEntry(ModSetting.VisualHands.ToString(), VisualHands)
|
||||
};
|
||||
|
||||
Load();
|
||||
|
@ -146,6 +150,7 @@ namespace ml_lme
|
|||
Input = (bool)ms_entries[(int)ModSetting.Input].BoxedValue;
|
||||
InteractThreadhold = (int)ms_entries[(int)ModSetting.InteractThreadhold].BoxedValue * 0.01f;
|
||||
GripThreadhold = (int)ms_entries[(int)ModSetting.GripThreadhold].BoxedValue * 0.01f;
|
||||
VisualHands = (bool)ms_entries[(int)ModSetting.VisualHands].BoxedValue;
|
||||
}
|
||||
|
||||
static void OnToggleUpdate(string p_name, string p_value)
|
||||
|
@ -195,6 +200,13 @@ namespace ml_lme
|
|||
InputChange?.Invoke(Input);
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.VisualHands:
|
||||
{
|
||||
VisualHands = bool.Parse(p_value);
|
||||
VisualHandsChange?.Invoke(VisualHands);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ms_entries[(int)l_setting].BoxedValue = bool.Parse(p_value);
|
||||
|
|
71
ml_lme/VisualHand.cs
Normal file
71
ml_lme/VisualHand.cs
Normal file
|
@ -0,0 +1,71 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ml_lme
|
||||
{
|
||||
class VisualHand
|
||||
{
|
||||
Transform m_root = null;
|
||||
Transform m_wrist = null;
|
||||
Transform[] m_fingers = null;
|
||||
|
||||
public VisualHand(Transform p_root, bool p_left)
|
||||
{
|
||||
m_root = p_root;
|
||||
|
||||
if(m_root != null)
|
||||
{
|
||||
m_wrist = m_root.Find(p_left ? "LeftHand/Wrist" : "RightHand/Wrist");
|
||||
if(m_wrist != null)
|
||||
{
|
||||
m_fingers = new Transform[20];
|
||||
|
||||
m_fingers[0] = null; // Actual thumb-meta, look at Leap Motion docs, dummy
|
||||
m_fingers[1] = m_wrist.Find("thumb_meta");
|
||||
m_fingers[2] = m_wrist.Find("thumb_meta/thumb_a");
|
||||
m_fingers[3] = m_wrist.Find("thumb_meta/thumb_a/thumb_b");
|
||||
|
||||
m_fingers[4] = m_wrist.Find("index_meta");
|
||||
m_fingers[5] = m_wrist.Find("index_meta/index_a");
|
||||
m_fingers[6] = m_wrist.Find("index_meta/index_a/index_b");
|
||||
m_fingers[7] = m_wrist.Find("index_meta/index_a/index_b/index_c");
|
||||
|
||||
m_fingers[8] = m_wrist.Find("middle_meta");
|
||||
m_fingers[9] = m_wrist.Find("middle_meta/middle_a");
|
||||
m_fingers[10] = m_wrist.Find("middle_meta/middle_a/middle_b");
|
||||
m_fingers[11] = m_wrist.Find("middle_meta/middle_a/middle_b/middle_c");
|
||||
|
||||
m_fingers[12] = m_wrist.Find("ring_meta");
|
||||
m_fingers[13] = m_wrist.Find("ring_meta/ring_a");
|
||||
m_fingers[14] = m_wrist.Find("ring_meta/ring_a/ring_b");
|
||||
m_fingers[15] = m_wrist.Find("ring_meta/ring_a/ring_b/ring_c");
|
||||
|
||||
m_fingers[16] = m_wrist.Find("pinky_meta");
|
||||
m_fingers[17] = m_wrist.Find("pinky_meta/pinky_a");
|
||||
m_fingers[18] = m_wrist.Find("pinky_meta/pinky_a/pinky_b");
|
||||
m_fingers[19] = m_wrist.Find("pinky_meta/pinky_a/pinky_b/pinky_c");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(GestureMatcher.HandData p_data)
|
||||
{
|
||||
if(m_wrist != null)
|
||||
{
|
||||
m_wrist.position = p_data.m_position;
|
||||
m_wrist.rotation = p_data.m_rotation;
|
||||
|
||||
for(int i = 0; i < 20; i++)
|
||||
{
|
||||
if(m_fingers[i] != null)
|
||||
{
|
||||
//m_fingers[i].position = p_data.m_fingerPosition[i];
|
||||
m_fingers[i].rotation = p_data.m_fingerRotation[i];
|
||||
}
|
||||
}
|
||||
|
||||
m_wrist.localPosition = p_data.m_position;
|
||||
m_wrist.localRotation = p_data.m_rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -83,6 +83,14 @@
|
|||
<HintPath>C:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputLegacyModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>D:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AssetsHandler.cs" />
|
||||
|
@ -130,6 +138,7 @@
|
|||
<Compile Include="vendor\LeapCSharp\StructMarshal.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\TransformExtensions.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\Vector.cs" />
|
||||
<Compile Include="VisualHand.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="vendor\LeapSDK\lib\x64\LeapC.dll">
|
||||
|
@ -142,6 +151,9 @@
|
|||
<ItemGroup>
|
||||
<EmbeddedResource Include="resources\menu.js" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="resources\leapmotion_hands.asset" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>copy /y "$(TargetPath)" "D:\Games\Steam\steamapps\common\ChilloutVR\Mods\"</PostBuildEvent>
|
||||
|
|
BIN
ml_lme/resources/leapmotion_hands.asset
Normal file
BIN
ml_lme/resources/leapmotion_hands.asset
Normal file
Binary file not shown.
|
@ -385,6 +385,13 @@ function inp_dropdown_mod_lme(_obj, _callbackName) {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class ="row-wrapper">
|
||||
<div class ="option-caption">Visualize hands: </div>
|
||||
<div class ="option-input">
|
||||
<div id="VisualHands" 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">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue