mirror of
https://github.com/hanetzer/sdraw_mods_cvr.git
synced 2025-09-03 10:29:22 +00:00
Source upload
This commit is contained in:
parent
50162481eb
commit
51ad6da4c3
51 changed files with 14957 additions and 0 deletions
21
LICENSE.txt
Normal file
21
LICENSE.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2022 SDraw
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
1
README.md
Normal file
1
README.md
Normal file
|
@ -0,0 +1 @@
|
|||
404: Not Found
|
76
ml_lme_cvr/DependenciesHandler.cs
Normal file
76
ml_lme_cvr/DependenciesHandler.cs
Normal file
|
@ -0,0 +1,76 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace ml_lme_cvr
|
||||
{
|
||||
static class DependenciesHandler
|
||||
{
|
||||
static readonly List<string> ms_libraries = new List<string>()
|
||||
{
|
||||
"LeapC.dll"
|
||||
};
|
||||
|
||||
public static void ExtractDependencies()
|
||||
{
|
||||
Assembly l_assembly = Assembly.GetExecutingAssembly();
|
||||
string l_assemblyName = l_assembly.GetName().Name;
|
||||
|
||||
foreach(string l_library in ms_libraries)
|
||||
{
|
||||
Stream l_libraryStream = l_assembly.GetManifestResourceStream(l_assemblyName + "." + l_library);
|
||||
|
||||
if(!File.Exists(l_library))
|
||||
{
|
||||
try
|
||||
{
|
||||
Stream l_fileStream = File.Create(l_library);
|
||||
l_libraryStream.CopyTo(l_fileStream);
|
||||
l_fileStream.Flush();
|
||||
l_fileStream.Close();
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error("Unable to extract embedded " + l_library + " library");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
FileStream l_fileStream = File.Open(l_library, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
|
||||
SHA256 l_hasher = SHA256.Create();
|
||||
byte[] l_libraryHash = l_hasher.ComputeHash(l_libraryStream);
|
||||
byte[] l_fileHash = l_hasher.ComputeHash(l_fileStream);
|
||||
|
||||
for(int i = 0; i < l_libraryHash.Length; i++)
|
||||
{
|
||||
if(l_libraryHash[i] != l_fileHash[i])
|
||||
{
|
||||
l_fileStream.SetLength(l_libraryStream.Length);
|
||||
l_fileStream.Position = 0;
|
||||
l_libraryStream.Position = 0;
|
||||
l_libraryStream.CopyTo(l_fileStream);
|
||||
l_fileStream.Flush();
|
||||
|
||||
MelonLoader.MelonLogger.Msg("Updated " + l_library + " library from embedded one");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
l_fileStream.Close();
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error("Unable to compare/update " + l_library + " library, delete it from game folder manually and restart.");
|
||||
}
|
||||
}
|
||||
|
||||
l_libraryStream.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
203
ml_lme_cvr/GestureMatcher.cs
Normal file
203
ml_lme_cvr/GestureMatcher.cs
Normal file
|
@ -0,0 +1,203 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ml_lme_cvr
|
||||
{
|
||||
static class GestureMatcher
|
||||
{
|
||||
|
||||
readonly static Vector2[] ms_fingerLimits =
|
||||
{
|
||||
new Vector2(0f, 15f),
|
||||
new Vector2(-20f, 20f),
|
||||
new Vector2(-50f, 50f),
|
||||
new Vector2(-7.5f, 7.5f),
|
||||
new Vector2(-20f, 20f)
|
||||
};
|
||||
|
||||
public class GesturesData
|
||||
{
|
||||
readonly public static int ms_handsCount = 2;
|
||||
readonly public static int ms_fingersCount = 5;
|
||||
|
||||
public bool[] m_handsPresenses = null;
|
||||
public Vector3[] m_handsPositons = null;
|
||||
public Quaternion[] m_handsRotations = null;
|
||||
public float[] m_leftFingersBends = null;
|
||||
public float[] m_leftFingersSpreads = null;
|
||||
public float[] m_rightFingersBends = null;
|
||||
public float[] m_rightFingersSpreads = null;
|
||||
|
||||
public GesturesData()
|
||||
{
|
||||
m_handsPresenses = new bool[ms_handsCount];
|
||||
m_handsPositons = new Vector3[ms_handsCount];
|
||||
m_handsRotations = new Quaternion[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];
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetGestures(Leap.Frame p_frame, ref GesturesData p_data)
|
||||
{
|
||||
// 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++)
|
||||
{
|
||||
p_data.m_leftFingersBends[i] = 0f;
|
||||
p_data.m_leftFingersSpreads[i] = 0f;
|
||||
p_data.m_rightFingersBends[i] = 0f;
|
||||
p_data.m_leftFingersSpreads[i] = 0f;
|
||||
}
|
||||
|
||||
// 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]);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void FillHandPosition(Leap.Hand p_hand, ref Vector3 p_pos)
|
||||
{
|
||||
p_pos.x = p_hand.PalmPosition.x;
|
||||
p_pos.y = p_hand.PalmPosition.y;
|
||||
p_pos.z = p_hand.PalmPosition.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 FillFingerBends(Leap.Hand p_hand, ref float[] p_bends)
|
||||
{
|
||||
foreach(Leap.Finger l_finger in p_hand.Fingers)
|
||||
{
|
||||
Quaternion l_prevSegment = Quaternion.identity;
|
||||
|
||||
float l_angle = 0f;
|
||||
foreach(Leap.Bone l_bone in l_finger.bones)
|
||||
{
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
|
||||
Quaternion l_curSegment = new Quaternion(l_bone.Rotation.x, l_bone.Rotation.y, l_bone.Rotation.z, l_bone.Rotation.w);
|
||||
Quaternion l_diff = Quaternion.Inverse(l_prevSegment) * l_curSegment;
|
||||
l_prevSegment = l_curSegment;
|
||||
|
||||
// Bend - local X rotation
|
||||
float l_curAngle = 360f - l_diff.eulerAngles.x;
|
||||
if(l_curAngle > 180f)
|
||||
l_curAngle -= 360f;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void FilFingerSpreads(Leap.Hand p_hand, ref float[] p_spreads)
|
||||
{
|
||||
|
||||
foreach(Leap.Finger l_finger in p_hand.Fingers)
|
||||
{
|
||||
float l_angle = 0f;
|
||||
|
||||
Leap.Bone l_parent = l_finger.Bone(Leap.Bone.BoneType.TYPE_METACARPAL);
|
||||
Leap.Bone l_child = l_finger.Bone(Leap.Bone.BoneType.TYPE_PROXIMAL);
|
||||
|
||||
Quaternion l_parentRot = new Quaternion(l_parent.Rotation.x, l_parent.Rotation.y, l_parent.Rotation.z, l_parent.Rotation.w);
|
||||
Quaternion l_childRot = new Quaternion(l_child.Rotation.x, l_child.Rotation.y, l_child.Rotation.z, l_child.Rotation.w);
|
||||
|
||||
Quaternion l_diff = Quaternion.Inverse(l_parentRot) * l_childRot;
|
||||
|
||||
// Spread - local Y rotation, but thumb is obnoxious
|
||||
l_angle = l_diff.eulerAngles.y;
|
||||
if(l_angle > 180f)
|
||||
l_angle -= 360f;
|
||||
|
||||
// Pain
|
||||
switch(l_finger.Type)
|
||||
{
|
||||
case Leap.Finger.FingerType.TYPE_THUMB:
|
||||
{
|
||||
if(p_hand.IsRight)
|
||||
l_angle *= -1f;
|
||||
l_angle += ms_fingerLimits[(int)Leap.Finger.FingerType.TYPE_INDEX].y * 2f;
|
||||
l_angle *= 0.5f;
|
||||
}
|
||||
break;
|
||||
|
||||
case Leap.Finger.FingerType.TYPE_INDEX:
|
||||
{
|
||||
if(p_hand.IsLeft)
|
||||
l_angle *= -1f;
|
||||
l_angle += ms_fingerLimits[(int)Leap.Finger.FingerType.TYPE_INDEX].y;
|
||||
l_angle *= 0.5f;
|
||||
}
|
||||
break;
|
||||
|
||||
case Leap.Finger.FingerType.TYPE_MIDDLE:
|
||||
{
|
||||
l_angle += (ms_fingerLimits[(int)Leap.Finger.FingerType.TYPE_MIDDLE].y * (p_hand.IsRight ? 0.125f : -0.125f));
|
||||
l_angle *= (p_hand.IsLeft ? -4f : 4f);
|
||||
}
|
||||
break;
|
||||
|
||||
case Leap.Finger.FingerType.TYPE_RING:
|
||||
{
|
||||
if(p_hand.IsRight)
|
||||
l_angle *= -1f;
|
||||
l_angle += ms_fingerLimits[(int)Leap.Finger.FingerType.TYPE_RING].y;
|
||||
l_angle *= 0.5f;
|
||||
}
|
||||
break;
|
||||
|
||||
case Leap.Finger.FingerType.TYPE_PINKY:
|
||||
{
|
||||
l_angle += (p_hand.IsRight ? ms_fingerLimits[(int)Leap.Finger.FingerType.TYPE_PINKY].x : ms_fingerLimits[(int)Leap.Finger.FingerType.TYPE_PINKY].y);
|
||||
l_angle *= (p_hand.IsRight ? -0.5f : 0.5f);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
p_spreads[(int)l_finger.Type] = Mathf.InverseLerp(ms_fingerLimits[(int)l_finger.Type].x, ms_fingerLimits[(int)l_finger.Type].y, l_angle);
|
||||
if(l_finger.Type != Leap.Finger.FingerType.TYPE_THUMB)
|
||||
{
|
||||
p_spreads[(int)l_finger.Type] *= 2f;
|
||||
p_spreads[(int)l_finger.Type] -= 1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
53
ml_lme_cvr/LeapIK.cs
Normal file
53
ml_lme_cvr/LeapIK.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ml_lme_cvr
|
||||
{
|
||||
[RequireComponent(typeof(Animator))]
|
||||
[DisallowMultipleComponent]
|
||||
public class LeapIK : MonoBehaviour
|
||||
{
|
||||
bool m_enabled = true;
|
||||
bool m_fingersOnly = false;
|
||||
|
||||
Animator m_animator = null;
|
||||
Transform m_leftHand = null;
|
||||
Transform m_rightHand = null;
|
||||
|
||||
void Start()
|
||||
{
|
||||
m_animator = this.GetComponent<Animator>();
|
||||
}
|
||||
|
||||
void OnAnimatorIK()
|
||||
{
|
||||
if(m_enabled && !m_fingersOnly && (m_animator != null))
|
||||
{
|
||||
if(m_leftHand != null)
|
||||
{
|
||||
m_animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1f);
|
||||
m_animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1f);
|
||||
m_animator.SetIKPosition(AvatarIKGoal.LeftHand, m_leftHand.position);
|
||||
m_animator.SetIKRotation(AvatarIKGoal.LeftHand, m_leftHand.rotation);
|
||||
}
|
||||
|
||||
if(m_rightHand != null)
|
||||
{
|
||||
m_animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1f);
|
||||
m_animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1f);
|
||||
m_animator.SetIKPosition(AvatarIKGoal.RightHand, m_rightHand.position);
|
||||
m_animator.SetIKRotation(AvatarIKGoal.RightHand, m_rightHand.rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetEnabled(bool p_state) => m_enabled = p_state;
|
||||
|
||||
public void SetFingersOnly(bool p_state) => m_fingersOnly = p_state;
|
||||
|
||||
public void SetHands(Transform p_left, Transform p_right)
|
||||
{
|
||||
m_leftHand = p_left;
|
||||
m_rightHand = p_right;
|
||||
}
|
||||
}
|
||||
}
|
141
ml_lme_cvr/LeapTracked.cs
Normal file
141
ml_lme_cvr/LeapTracked.cs
Normal file
|
@ -0,0 +1,141 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ml_lme_cvr
|
||||
{
|
||||
[RequireComponent(typeof(ABI_RC.Core.Player.IndexIK))]
|
||||
[DisallowMultipleComponent]
|
||||
class LeapTracked : MonoBehaviour
|
||||
{
|
||||
bool m_enabled = true;
|
||||
bool m_fingersOnly = false;
|
||||
bool m_calibrated = false;
|
||||
|
||||
Animator m_animator = null;
|
||||
ABI_RC.Core.Player.IndexIK m_indexIK = null;
|
||||
LeapIK m_leapIK = null;
|
||||
Transform m_leftHand = null;
|
||||
Transform m_rightHand = null;
|
||||
|
||||
void Start()
|
||||
{
|
||||
m_indexIK = this.GetComponent<ABI_RC.Core.Player.IndexIK>();
|
||||
|
||||
if((m_indexIK != null) && (m_animator != null))
|
||||
{
|
||||
m_indexIK.avatarAnimator = m_animator;
|
||||
m_indexIK.Recalibrate();
|
||||
|
||||
m_indexIK.activeControl = m_enabled;
|
||||
ABI_RC.Core.Savior.CVRInputManager.Instance.individualFingerTracking = m_enabled;
|
||||
|
||||
m_calibrated = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetEnabled(bool p_state)
|
||||
{
|
||||
m_enabled = p_state;
|
||||
if(m_enabled)
|
||||
{
|
||||
if((m_animator != null) && (m_indexIK != null))
|
||||
{
|
||||
m_indexIK.activeControl = true;
|
||||
if(!m_calibrated)
|
||||
{
|
||||
m_indexIK.avatarAnimator = m_animator;
|
||||
m_indexIK.Recalibrate();
|
||||
m_calibrated = true;
|
||||
}
|
||||
ABI_RC.Core.Savior.CVRInputManager.Instance.individualFingerTracking = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if((m_indexIK != null) && m_calibrated)
|
||||
{
|
||||
m_indexIK.activeControl = false;
|
||||
ABI_RC.Core.Savior.CVRInputManager.Instance.individualFingerTracking = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_leapIK != null)
|
||||
m_leapIK.SetEnabled(m_enabled);
|
||||
}
|
||||
|
||||
public void SetAnimator(Animator p_animator)
|
||||
{
|
||||
m_animator = p_animator;
|
||||
|
||||
m_leapIK = m_animator.gameObject.AddComponent<LeapIK>();
|
||||
m_leapIK.SetEnabled(m_enabled);
|
||||
m_leapIK.SetFingersOnly(m_fingersOnly);
|
||||
m_leapIK.SetHands(m_leftHand, m_rightHand);
|
||||
}
|
||||
|
||||
public void SetFingersOnly(bool p_state)
|
||||
{
|
||||
m_fingersOnly = p_state;
|
||||
|
||||
if(m_leapIK != null)
|
||||
m_leapIK.SetFingersOnly(m_fingersOnly);
|
||||
}
|
||||
|
||||
public void SetHands(Transform p_left, Transform p_right)
|
||||
{
|
||||
m_leftHand = p_left;
|
||||
m_rightHand = p_right;
|
||||
|
||||
if(m_leapIK != null)
|
||||
m_leapIK.SetHands(p_left, p_right);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
m_calibrated = false;
|
||||
m_animator = null;
|
||||
m_leapIK = null;
|
||||
}
|
||||
|
||||
public void UpdateTracking(GestureMatcher.GesturesData p_gesturesData)
|
||||
{
|
||||
if(m_enabled && (m_indexIK != null))
|
||||
{
|
||||
if(p_gesturesData.m_handsPresenses[0])
|
||||
{
|
||||
m_indexIK.leftThumbCurl = p_gesturesData.m_leftFingersBends[0];
|
||||
m_indexIK.leftIndexCurl = p_gesturesData.m_leftFingersBends[1];
|
||||
m_indexIK.leftMiddleCurl = p_gesturesData.m_leftFingersBends[2];
|
||||
m_indexIK.leftRingCurl = p_gesturesData.m_leftFingersBends[3];
|
||||
m_indexIK.leftPinkyCurl = p_gesturesData.m_leftFingersBends[4];
|
||||
|
||||
if(ABI_RC.Core.Savior.CVRInputManager.Instance != null)
|
||||
{
|
||||
ABI_RC.Core.Savior.CVRInputManager.Instance.fingerCurlLeftThumb = p_gesturesData.m_leftFingersBends[0];
|
||||
ABI_RC.Core.Savior.CVRInputManager.Instance.fingerCurlLeftIndex = p_gesturesData.m_leftFingersBends[1];
|
||||
ABI_RC.Core.Savior.CVRInputManager.Instance.fingerCurlLeftMiddle = p_gesturesData.m_leftFingersBends[2];
|
||||
ABI_RC.Core.Savior.CVRInputManager.Instance.fingerCurlLeftRing = p_gesturesData.m_leftFingersBends[3];
|
||||
ABI_RC.Core.Savior.CVRInputManager.Instance.fingerCurlLeftPinky = p_gesturesData.m_leftFingersBends[4];
|
||||
}
|
||||
}
|
||||
|
||||
if(p_gesturesData.m_handsPresenses[1])
|
||||
{
|
||||
m_indexIK.rightThumbCurl = p_gesturesData.m_rightFingersBends[0];
|
||||
m_indexIK.rightIndexCurl = p_gesturesData.m_rightFingersBends[1];
|
||||
m_indexIK.rightMiddleCurl = p_gesturesData.m_rightFingersBends[2];
|
||||
m_indexIK.rightRingCurl = p_gesturesData.m_rightFingersBends[3];
|
||||
m_indexIK.rightPinkyCurl = p_gesturesData.m_rightFingersBends[4];
|
||||
|
||||
if(ABI_RC.Core.Savior.CVRInputManager.Instance != null)
|
||||
{
|
||||
ABI_RC.Core.Savior.CVRInputManager.Instance.fingerCurlRightThumb = p_gesturesData.m_rightFingersBends[0];
|
||||
ABI_RC.Core.Savior.CVRInputManager.Instance.fingerCurlRightIndex = p_gesturesData.m_rightFingersBends[1];
|
||||
ABI_RC.Core.Savior.CVRInputManager.Instance.fingerCurlRightMiddle = p_gesturesData.m_rightFingersBends[2];
|
||||
ABI_RC.Core.Savior.CVRInputManager.Instance.fingerCurlRightRing = p_gesturesData.m_rightFingersBends[3];
|
||||
ABI_RC.Core.Savior.CVRInputManager.Instance.fingerCurlRightPinky = p_gesturesData.m_rightFingersBends[4];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
177
ml_lme_cvr/Main.cs
Normal file
177
ml_lme_cvr/Main.cs
Normal file
|
@ -0,0 +1,177 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ml_lme_cvr
|
||||
{
|
||||
|
||||
public class LeapMotionExtension : MelonLoader.MelonMod
|
||||
{
|
||||
static readonly Quaternion ms_hmdRotationFix = new Quaternion(0f, 0.7071068f, 0.7071068f, 0f);
|
||||
|
||||
static LeapMotionExtension ms_instance = null;
|
||||
|
||||
Leap.Controller m_leapController = null;
|
||||
GestureMatcher.GesturesData m_gesturesData = null;
|
||||
|
||||
GameObject m_leapTrackingRoot = null;
|
||||
GameObject[] m_leapHands = null;
|
||||
LeapTracked m_leapTracked = null;
|
||||
|
||||
Transform m_vrRig = null;
|
||||
Transform m_desktopRig = null;
|
||||
|
||||
public override void OnApplicationStart()
|
||||
{
|
||||
ms_instance = this;
|
||||
|
||||
DependenciesHandler.ExtractDependencies();
|
||||
|
||||
Settings.Init(HarmonyInstance);
|
||||
Settings.EnabledChange += this.OnSettingsEnableChange;
|
||||
Settings.DesktopOffsetChange += this.OnSettingsDesktopOffsetChange;
|
||||
Settings.FingersOnlyChange += this.OnSettingsFingersOptionChange;
|
||||
|
||||
m_leapController = new Leap.Controller();
|
||||
m_gesturesData = new GestureMatcher.GesturesData();
|
||||
|
||||
m_leapHands = new GameObject[GestureMatcher.GesturesData.ms_handsCount];
|
||||
|
||||
// Patches
|
||||
HarmonyInstance.Patch(
|
||||
typeof(ABI_RC.Core.Player.PlayerSetup).GetMethod(nameof(ABI_RC.Core.Player.PlayerSetup.SetupAvatar)),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(LeapMotionExtension).GetMethod(nameof(OnAvatarSetup), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic))
|
||||
);
|
||||
|
||||
MelonLoader.MelonCoroutines.Start(CreateTrackingObjects());
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator CreateTrackingObjects()
|
||||
{
|
||||
while(ABI_RC.Core.Player.PlayerSetup.Instance == null)
|
||||
yield return null;
|
||||
|
||||
while(m_vrRig == null)
|
||||
{
|
||||
m_vrRig = ABI_RC.Core.Player.PlayerSetup.Instance.transform.Find("[CameraRigVR]");
|
||||
yield return null;
|
||||
}
|
||||
|
||||
while(m_desktopRig == null)
|
||||
{
|
||||
m_desktopRig = ABI_RC.Core.Player.PlayerSetup.Instance.transform.Find("[CameraRigDesktop]");
|
||||
yield return null;
|
||||
}
|
||||
|
||||
m_leapTrackingRoot = new GameObject("[LeapRoot]");
|
||||
m_leapTrackingRoot.transform.parent = m_desktopRig;
|
||||
m_leapTrackingRoot.transform.localPosition = new Vector3(0f, -0.45637f, 0.35f);
|
||||
m_leapTrackingRoot.transform.localRotation = Quaternion.identity;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Settings.Reload();
|
||||
}
|
||||
|
||||
public override void OnUpdate()
|
||||
{
|
||||
if(Settings.Enabled && (m_leapController != null))
|
||||
{
|
||||
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_gesturesData.m_handsPresenses[i] && (m_leapHands[i] != null))
|
||||
{
|
||||
Vector3 l_pos = m_gesturesData.m_handsPositons[i];
|
||||
Quaternion l_rot = m_gesturesData.m_handsRotations[i];
|
||||
ReorientateLeapToUnity(ref l_pos, ref l_rot, false);
|
||||
m_leapHands[i].transform.localPosition = l_pos;
|
||||
m_leapHands[i].transform.localRotation = l_rot;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_leapTracked != null)
|
||||
m_leapTracked.UpdateTracking(m_gesturesData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnSettingsEnableChange()
|
||||
{
|
||||
if(Settings.Enabled)
|
||||
{
|
||||
m_leapController.StartConnection();
|
||||
m_leapController.SetAndClearPolicy(Leap.Controller.PolicyFlag.POLICY_DEFAULT, Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_SCREENTOP | Leap.Controller.PolicyFlag.POLICY_OPTIMIZE_HMD);
|
||||
}
|
||||
else
|
||||
m_leapController.StopConnection();
|
||||
|
||||
if(m_leapTracked != null)
|
||||
m_leapTracked.SetEnabled(Settings.Enabled);
|
||||
}
|
||||
|
||||
void OnSettingsDesktopOffsetChange()
|
||||
{
|
||||
if((m_leapTrackingRoot != null) && (m_vrRig != null))
|
||||
{
|
||||
m_leapTrackingRoot.transform.localPosition = new Vector3(Settings.DesktopOffsetX, Settings.DesktopOffsetY, Settings.DesktopOffsetZ) * m_vrRig.transform.localScale.x;
|
||||
m_leapTrackingRoot.transform.localScale = m_vrRig.transform.localScale;
|
||||
}
|
||||
}
|
||||
|
||||
void OnSettingsFingersOptionChange()
|
||||
{
|
||||
if(m_leapTracked != null)
|
||||
m_leapTracked.SetFingersOnly(Settings.FingersOnly);
|
||||
}
|
||||
|
||||
static void OnAvatarSetup(ref ABI_RC.Core.Player.PlayerSetup __instance)
|
||||
{
|
||||
if(__instance != null && __instance == ABI_RC.Core.Player.PlayerSetup.Instance)
|
||||
{
|
||||
ms_instance?.OnLocalPlayerAvatarSetup(__instance._animator, __instance.GetComponent<ABI_RC.Core.Player.IndexIK>());
|
||||
}
|
||||
}
|
||||
void OnLocalPlayerAvatarSetup(Animator p_animator, ABI_RC.Core.Player.IndexIK p_indexIK)
|
||||
{
|
||||
if(m_leapTracked != null)
|
||||
Object.DestroyImmediate(m_leapTracked);
|
||||
|
||||
m_leapTracked = p_indexIK.gameObject.AddComponent<LeapTracked>();
|
||||
m_leapTracked.SetEnabled(Settings.Enabled);
|
||||
m_leapTracked.SetAnimator(p_animator);
|
||||
m_leapTracked.SetHands(m_leapHands[0].transform, m_leapHands[1].transform);
|
||||
m_leapTracked.SetFingersOnly(Settings.FingersOnly);
|
||||
|
||||
if((m_leapTrackingRoot != null) && (m_vrRig != null))
|
||||
{
|
||||
m_leapTrackingRoot.transform.localPosition = new Vector3(Settings.DesktopOffsetX, Settings.DesktopOffsetY, Settings.DesktopOffsetZ) * m_vrRig.transform.localScale.x;
|
||||
m_leapTrackingRoot.transform.localScale = m_vrRig.transform.localScale;
|
||||
}
|
||||
}
|
||||
|
||||
static void ReorientateLeapToUnity(ref Vector3 p_pos, ref Quaternion p_rot, bool p_hmd)
|
||||
{
|
||||
p_pos *= 0.001f;
|
||||
p_pos.z *= -1f;
|
||||
p_rot.x *= -1f;
|
||||
p_rot.y *= -1f;
|
||||
|
||||
if(p_hmd)
|
||||
{
|
||||
p_pos.x *= -1f;
|
||||
Utils.Swap(ref p_pos.y, ref p_pos.z);
|
||||
p_rot = (ms_hmdRotationFix * p_rot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
10
ml_lme_cvr/Properties/AssemblyInfo.cs
Normal file
10
ml_lme_cvr/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyTitle("LeapMotionExtension")]
|
||||
[assembly: AssemblyVersion("1.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0")]
|
||||
|
||||
[assembly: MelonLoader.MelonInfo(typeof(ml_lme_cvr.LeapMotionExtension), "LeapMotionExtension", "1.0.0", "SDraw", "https://github.com/SDraw")]
|
||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
117
ml_lme_cvr/Settings.cs
Normal file
117
ml_lme_cvr/Settings.cs
Normal file
|
@ -0,0 +1,117 @@
|
|||
namespace ml_lme_cvr
|
||||
{
|
||||
static class Settings
|
||||
{
|
||||
public static readonly string[] ms_defaultSettings =
|
||||
{
|
||||
"InteractionLeapMotionTracking",
|
||||
"InteractionLeapMotionTrackingDesktopX",
|
||||
"InteractionLeapMotionTrackingDesktopY",
|
||||
"InteractionLeapMotionTrackingDesktopZ",
|
||||
"InteractionLeapMotionTrackingFingersOnly"
|
||||
};
|
||||
|
||||
static bool ms_enabled = false;
|
||||
static float ms_desktopOffsetX = 0f;
|
||||
static float ms_desktopOffsetY = -0.45f;
|
||||
static float ms_desktopOffsetZ = 0.3f;
|
||||
static bool ms_fingersOnly = false;
|
||||
|
||||
static bool ms_initialized = false;
|
||||
|
||||
static public event System.Action EnabledChange;
|
||||
static public event System.Action DesktopOffsetChange;
|
||||
static public event System.Action FingersOnlyChange;
|
||||
|
||||
public static void Init(HarmonyLib.Harmony p_instance)
|
||||
{
|
||||
p_instance.Patch(
|
||||
typeof(ABI_RC.Core.Savior.CVRSettings).GetMethod(nameof(ABI_RC.Core.Savior.CVRSettings.LoadSerializedSettings)),
|
||||
new HarmonyLib.HarmonyMethod(typeof(Settings).GetMethod(nameof(BeforeSettingsLoad), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)),
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
static void BeforeSettingsLoad(ref ABI_RC.Core.Savior.CVRSettings __instance)
|
||||
{
|
||||
if(!ms_initialized && __instance != null)
|
||||
{
|
||||
var l_settings = HarmonyLib.Traverse.Create(__instance)?.Field("_settings")?.GetValue<System.Collections.Generic.List<ABI_RC.Core.Savior.CVRSettingsValue>>();
|
||||
if(l_settings != null)
|
||||
{
|
||||
l_settings.Add(new ABI_RC.Core.Savior.CVRSettingsBool(ms_defaultSettings[0], false));
|
||||
l_settings.Add(new ABI_RC.Core.Savior.CVRSettingsInt(ms_defaultSettings[1], 0));
|
||||
l_settings.Add(new ABI_RC.Core.Savior.CVRSettingsInt(ms_defaultSettings[2], -45));
|
||||
l_settings.Add(new ABI_RC.Core.Savior.CVRSettingsInt(ms_defaultSettings[3], 30));
|
||||
l_settings.Add(new ABI_RC.Core.Savior.CVRSettingsBool(ms_defaultSettings[4], false));
|
||||
}
|
||||
|
||||
// Changes events
|
||||
__instance.settingBoolChanged.AddListener((name, value) =>
|
||||
{
|
||||
if(name == ms_defaultSettings[0])
|
||||
{
|
||||
Settings.Reload();
|
||||
EnabledChange?.Invoke();
|
||||
}
|
||||
});
|
||||
|
||||
__instance.settingIntChanged.AddListener((name, value) =>
|
||||
{
|
||||
for(int i=1; i <= 3; i++)
|
||||
{
|
||||
if(name == ms_defaultSettings[i])
|
||||
{
|
||||
Settings.Reload();
|
||||
DesktopOffsetChange?.Invoke();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
__instance.settingBoolChanged.AddListener((name, value) =>
|
||||
{
|
||||
if(name == ms_defaultSettings[4])
|
||||
{
|
||||
Settings.Reload();
|
||||
FingersOnlyChange?.Invoke();
|
||||
}
|
||||
});
|
||||
|
||||
ms_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
static public void Reload()
|
||||
{
|
||||
ms_enabled = ABI_RC.Core.Savior.MetaPort.Instance.settings.GetSettingsBool(ms_defaultSettings[0]);
|
||||
ms_desktopOffsetX = ABI_RC.Core.Savior.MetaPort.Instance.settings.GetSettingInt(ms_defaultSettings[1]) * 0.01f;
|
||||
ms_desktopOffsetY = ABI_RC.Core.Savior.MetaPort.Instance.settings.GetSettingInt(ms_defaultSettings[2]) * 0.01f;
|
||||
ms_desktopOffsetZ = ABI_RC.Core.Savior.MetaPort.Instance.settings.GetSettingInt(ms_defaultSettings[3]) * 0.01f;
|
||||
ms_fingersOnly = ABI_RC.Core.Savior.MetaPort.Instance.settings.GetSettingsBool(ms_defaultSettings[4]);
|
||||
}
|
||||
|
||||
public static bool Enabled
|
||||
{
|
||||
get => ms_enabled;
|
||||
}
|
||||
|
||||
public static float DesktopOffsetX
|
||||
{
|
||||
get => ms_desktopOffsetX;
|
||||
}
|
||||
public static float DesktopOffsetY
|
||||
{
|
||||
get => ms_desktopOffsetY;
|
||||
}
|
||||
public static float DesktopOffsetZ
|
||||
{
|
||||
get => ms_desktopOffsetZ;
|
||||
}
|
||||
|
||||
public static bool FingersOnly
|
||||
{
|
||||
get => ms_fingersOnly;
|
||||
}
|
||||
}
|
||||
}
|
12
ml_lme_cvr/Utils.cs
Normal file
12
ml_lme_cvr/Utils.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace ml_lme_cvr
|
||||
{
|
||||
static class Utils
|
||||
{
|
||||
public static void Swap<T>(ref T lhs, ref T rhs)
|
||||
{
|
||||
T temp = lhs;
|
||||
lhs = rhs;
|
||||
rhs = temp;
|
||||
}
|
||||
}
|
||||
}
|
119
ml_lme_cvr/ml_lme_cvr.csproj
Normal file
119
ml_lme_cvr/ml_lme_cvr.csproj
Normal file
|
@ -0,0 +1,119 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{83CC74B7-F444-40E1-BD06-67CEC995A919}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ml_lme_cvr</RootNamespace>
|
||||
<AssemblyName>ml_lme_cvr</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>C:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Assembly-CSharp-firstpass">
|
||||
<HintPath>C:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="MelonLoader">
|
||||
<HintPath>C:\Games\Steam\steamapps\common\ChilloutVR\MelonLoader\MelonLoader.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>C:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AnimationModule">
|
||||
<HintPath>C:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AnimationModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>C:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DependenciesHandler.cs" />
|
||||
<Compile Include="GestureMatcher.cs" />
|
||||
<Compile Include="LeapIK.cs" />
|
||||
<Compile Include="LeapTracked.cs" />
|
||||
<Compile Include="Main.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Settings.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\Arm.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\Bone.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\CircularObjectBuffer.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\Config.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\Connection.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\Controller.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\CopyFromLeapCExtensions.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\CopyFromOtherExtensions.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\CSharpExtensions.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\Device.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\DeviceList.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\DistortionData.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\Events.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\FailedDevice.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\FailedDeviceList.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\Finger.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\Frame.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\Hand.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\IController.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\Image.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\ImageData.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\LeapC.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\LeapQuaternion.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\LeapTransform.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\Logger.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\Matrix.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\MemoryManager.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\MessageSeverity.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\PointMapping.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\StructMarshal.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\TransformExtensions.cs" />
|
||||
<Compile Include="vendor\LeapCSharp\Vector.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="vendor\LeapSDK\lib\x64\LeapC.dll">
|
||||
<Link>LeapC.dll</Link>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>copy /y "$(TargetPath)" "C:\Games\Steam\steamapps\common\ChilloutVR\Mods\</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
6
ml_lme_cvr/ml_lme_cvr.csproj.user
Normal file
6
ml_lme_cvr/ml_lme_cvr.csproj.user
Normal file
|
@ -0,0 +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\steamapps\common\ChilloutVR\MelonLoader\;C:\Games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\</ReferencePath>
|
||||
</PropertyGroup>
|
||||
</Project>
|
101
ml_lme_cvr/vendor/LeapCSharp/Arm.cs
vendored
Normal file
101
ml_lme_cvr/vendor/LeapCSharp/Arm.cs
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// The Arm class represents the forearm.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class Arm : Bone, IEquatable<Arm>
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a default Arm object.
|
||||
/// Get valid Arm objects from a Hand object.
|
||||
///
|
||||
/// @since 2.0.3
|
||||
/// </summary>
|
||||
public Arm() : base() { }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new Arm object.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public Arm(Vector elbow,
|
||||
Vector wrist,
|
||||
Vector center,
|
||||
Vector direction,
|
||||
float length,
|
||||
float width,
|
||||
LeapQuaternion rotation)
|
||||
: base(elbow,
|
||||
wrist,
|
||||
center,
|
||||
direction,
|
||||
length,
|
||||
width,
|
||||
BoneType.TYPE_METACARPAL, //ignored for arms
|
||||
rotation)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Compare Arm object equality.
|
||||
/// Two Arm objects are equal if and only if both Arm objects represent the
|
||||
/// exact same physical arm in the same frame and both Arm objects are valid.
|
||||
/// @since 2.0.3
|
||||
/// </summary>
|
||||
public bool Equals(Arm other)
|
||||
{
|
||||
return Equals(other as Bone);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A string containing a brief, human readable description of the Arm object.
|
||||
/// @since 2.0.3
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return "Arm";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The position of the elbow.
|
||||
/// If not in view, the elbow position is estimated based on typical human
|
||||
/// anatomical proportions.
|
||||
///
|
||||
/// @since 2.0.3
|
||||
/// </summary>
|
||||
public Vector ElbowPosition
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.PrevJoint;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The position of the wrist.
|
||||
///
|
||||
/// Note that the wrist position is not collocated with the end of any bone in
|
||||
/// the hand. There is a gap of a few centimeters since the carpal bones are
|
||||
/// not included in the skeleton model.
|
||||
///
|
||||
/// @since 2.0.3
|
||||
/// </summary>
|
||||
public Vector WristPosition
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.NextJoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
183
ml_lme_cvr/vendor/LeapCSharp/Bone.cs
vendored
Normal file
183
ml_lme_cvr/vendor/LeapCSharp/Bone.cs
vendored
Normal file
|
@ -0,0 +1,183 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// The Bone class represents a tracked bone.
|
||||
///
|
||||
/// All fingers contain 4 bones that make up the anatomy of the finger.
|
||||
/// Get valid Bone objects from a Finger object.
|
||||
///
|
||||
/// Bones are ordered from base to tip, indexed from 0 to 3. Additionally, the
|
||||
/// bone's Type enum may be used to index a specific bone anatomically.
|
||||
///
|
||||
/// The thumb does not have a base metacarpal bone and therefore contains a valid,
|
||||
/// zero length bone at that location.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class Bone : IEquatable<Bone>
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a default invalid Bone object.
|
||||
///
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public Bone()
|
||||
{
|
||||
Type = BoneType.TYPE_INVALID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new Bone object.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public Bone(Vector prevJoint,
|
||||
Vector nextJoint,
|
||||
Vector center,
|
||||
Vector direction,
|
||||
float length,
|
||||
float width,
|
||||
Bone.BoneType type,
|
||||
LeapQuaternion rotation)
|
||||
{
|
||||
PrevJoint = prevJoint;
|
||||
NextJoint = nextJoint;
|
||||
Center = center;
|
||||
Direction = direction;
|
||||
Rotation = rotation;
|
||||
Length = length;
|
||||
Width = width;
|
||||
Type = type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare Bone object equality.
|
||||
///
|
||||
/// Two Bone objects are equal if and only if both Bone objects represent the
|
||||
/// exact same physical bone in the same frame and both Bone objects are valid.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public bool Equals(Bone other)
|
||||
{
|
||||
return Center == other.Center && Direction == other.Direction && Length == other.Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A string containing a brief, human readable description of the Bone object.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return Enum.GetName(typeof(BoneType), this.Type) + " bone";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The base of the bone, closest to the wrist.
|
||||
/// In anatomical terms, this is the proximal end of the bone.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public Vector PrevJoint;
|
||||
|
||||
/// <summary>
|
||||
/// The end of the bone, closest to the finger tip.
|
||||
/// In anatomical terms, this is the distal end of the bone.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public Vector NextJoint;
|
||||
|
||||
/// <summary>
|
||||
/// The midpoint of the bone.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public Vector Center;
|
||||
|
||||
/// <summary>
|
||||
/// The normalized direction of the bone from base to tip.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public Vector Direction;
|
||||
|
||||
/// <summary>
|
||||
/// The estimated length of the bone.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public float Length;
|
||||
|
||||
/// <summary>
|
||||
/// The average width of the flesh around the bone.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public float Width;
|
||||
|
||||
/// <summary>
|
||||
/// The type of this bone.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public BoneType Type;
|
||||
|
||||
/// <summary>
|
||||
/// The orientation of this Bone as a Quaternion.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public LeapQuaternion Rotation;
|
||||
|
||||
/// <summary>
|
||||
/// The orthonormal basis vectors for this Bone as a Matrix.
|
||||
/// The orientation of this Bone as a Quaternion.
|
||||
///
|
||||
/// Basis vectors specify the orientation of a bone.
|
||||
///
|
||||
/// **xBasis** Perpendicular to the longitudinal axis of the
|
||||
/// bone; exits the sides of the finger.
|
||||
///
|
||||
/// **yBasis or up vector** Perpendicular to the longitudinal
|
||||
/// axis of the bone; exits the top and bottom of the finger. More positive
|
||||
/// in the upward direction.
|
||||
///
|
||||
/// **zBasis** Aligned with the longitudinal axis of the bone.
|
||||
/// More positive toward the base of the finger.
|
||||
///
|
||||
/// The bases provided for the right hand use the right-hand rule; those for
|
||||
/// the left hand use the left-hand rule. Thus, the positive direction of the
|
||||
/// x-basis is to the right for the right hand and to the left for the left
|
||||
/// hand. You can change from right-hand to left-hand rule by multiplying the
|
||||
/// z basis vector by -1.
|
||||
///
|
||||
/// You can use the basis vectors for such purposes as measuring complex
|
||||
/// finger poses and skeletal animation.
|
||||
///
|
||||
/// Note that converting the basis vectors directly into a quaternion
|
||||
/// representation is not mathematically valid. If you use quaternions,
|
||||
/// create them from the derived rotation matrix not directly from the bases.
|
||||
///
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public LeapTransform Basis { get { return new LeapTransform(PrevJoint, Rotation); } }
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates the type of bones.
|
||||
///
|
||||
/// Members of this enumeration are returned by Bone.Type() to identify a
|
||||
/// Bone object.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public enum BoneType
|
||||
{
|
||||
TYPE_INVALID = -1,
|
||||
TYPE_METACARPAL = 0,
|
||||
TYPE_PROXIMAL = 1,
|
||||
TYPE_INTERMEDIATE = 2,
|
||||
TYPE_DISTAL = 3
|
||||
}
|
||||
}
|
||||
}
|
106
ml_lme_cvr/vendor/LeapCSharp/CSharpExtensions.cs
vendored
Normal file
106
ml_lme_cvr/vendor/LeapCSharp/CSharpExtensions.cs
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
using System;
|
||||
namespace Leap
|
||||
{
|
||||
/// <summary>
|
||||
/// Various C# extensions used by the Leap C# classes.
|
||||
///
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public static class CSharpExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares whether two floating point numbers are within an epsilon value of each other.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public static bool NearlyEquals(this float a, float b, float epsilon = Constants.EPSILON)
|
||||
{
|
||||
float absA = Math.Abs(a);
|
||||
float absB = Math.Abs(b);
|
||||
float diff = Math.Abs(a - b);
|
||||
|
||||
if (a == b)
|
||||
{ // shortcut, handles infinities
|
||||
return true;
|
||||
}
|
||||
else if (a == 0 || b == 0 || diff < float.MinValue)
|
||||
{
|
||||
// a or b is zero or both are extremely close to it
|
||||
// relative error is less meaningful here
|
||||
return diff < (epsilon * float.MinValue);
|
||||
}
|
||||
else
|
||||
{ // use relative error
|
||||
return diff / (absA + absB) < epsilon;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reports whether this object has the specified method.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public static bool HasMethod(this object objectToCheck, string methodName)
|
||||
{
|
||||
var type = objectToCheck.GetType();
|
||||
return type.GetMethod(methodName) != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the ordinal index of this enumeration item.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public static int indexOf(this Enum enumItem)
|
||||
{
|
||||
return Array.IndexOf(Enum.GetValues(enumItem.GetType()), enumItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item at the ordinal position in this enumeration.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public static T itemFor<T>(this int ordinal)
|
||||
{
|
||||
T[] values = (T[])Enum.GetValues(typeof(T));
|
||||
return values[ordinal];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convenience function to consolidate event dispatching boilerplate code.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public static void Dispatch<T>(this EventHandler<T> handler,
|
||||
object sender, T eventArgs) where T : EventArgs
|
||||
{
|
||||
if (handler != null) handler(sender, eventArgs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convenience function to consolidate event dispatching boilerplate code.
|
||||
/// Events are dispatched on the message queue of a threads' synchronization
|
||||
/// context, if possible.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public static void DispatchOnContext<T>(this EventHandler<T> handler, object sender,
|
||||
System.Threading.SynchronizationContext context,
|
||||
T eventArgs) where T : EventArgs
|
||||
{
|
||||
if (handler != null)
|
||||
{
|
||||
if (context != null)
|
||||
{
|
||||
System.Threading.SendOrPostCallback evt = (spc_args) => { handler(sender, spc_args as T); };
|
||||
context.Post(evt, eventArgs);
|
||||
}
|
||||
else
|
||||
handler(sender, eventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
110
ml_lme_cvr/vendor/LeapCSharp/CircularObjectBuffer.cs
vendored
Normal file
110
ml_lme_cvr/vendor/LeapCSharp/CircularObjectBuffer.cs
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace LeapInternal
|
||||
{
|
||||
//TODO add test for thread safety
|
||||
|
||||
/**
|
||||
* A Limited capacity, circular LIFO buffer that wraps around
|
||||
* when full. Supports indexing to get older items. Array-backed.
|
||||
* *
|
||||
* Unlike many collections, objects are never removed, just overwritten when
|
||||
* the buffer cycles back to their array location.
|
||||
*
|
||||
* Object types used must have default parameterless constructor. It should be obvious that
|
||||
* such default objects are invalid. I.e. for Leap API objects, the IsValid property should be false.
|
||||
*/
|
||||
public class CircularObjectBuffer<T> where T : new()
|
||||
{
|
||||
private T[] array;
|
||||
private int current = 0;
|
||||
private object locker = new object();
|
||||
public int Count { get; private set; }
|
||||
public int Capacity { get; private set; }
|
||||
public bool IsEmpty { get; private set; }
|
||||
|
||||
public CircularObjectBuffer(int capacity)
|
||||
{
|
||||
Capacity = capacity;
|
||||
array = new T[this.Capacity];
|
||||
current = 0;
|
||||
Count = 0;
|
||||
IsEmpty = true;
|
||||
}
|
||||
|
||||
/** Put an item at the head of the list. Once full, this will overwrite the oldest item. */
|
||||
public virtual void Put(ref T item)
|
||||
{
|
||||
lock (locker)
|
||||
{
|
||||
if (!IsEmpty)
|
||||
{
|
||||
current++;
|
||||
if (current >= Capacity)
|
||||
{
|
||||
current = 0;
|
||||
}
|
||||
}
|
||||
if (Count < Capacity)
|
||||
Count++;
|
||||
|
||||
lock (array)
|
||||
{
|
||||
array[current] = item;
|
||||
}
|
||||
IsEmpty = false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the item indexed backward from the head of the list */
|
||||
public void Get(out T t, int index = 0)
|
||||
{
|
||||
lock (locker)
|
||||
{
|
||||
if (IsEmpty || (index > Count - 1) || index < 0)
|
||||
{
|
||||
t = new T(); //default(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
int effectiveIndex = current - index;
|
||||
if (effectiveIndex < 0)
|
||||
{
|
||||
effectiveIndex += Capacity;
|
||||
}
|
||||
|
||||
t = array[effectiveIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Increase */
|
||||
public void Resize(int newCapacity)
|
||||
{
|
||||
lock (locker)
|
||||
{
|
||||
if (newCapacity <= Capacity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
T[] newArray = new T[newCapacity];
|
||||
int j = 0;
|
||||
for (int i = Count - 1; i >= 0; i--)
|
||||
{
|
||||
T t;
|
||||
Get(out t, i);
|
||||
newArray[j++] = t;
|
||||
}
|
||||
this.array = newArray;
|
||||
this.Capacity = newCapacity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
195
ml_lme_cvr/vendor/LeapCSharp/Config.cs
vendored
Normal file
195
ml_lme_cvr/vendor/LeapCSharp/Config.cs
vendored
Normal file
|
@ -0,0 +1,195 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
|
||||
using LeapInternal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// The Config class provides access to Leap Motion system configuration information.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public class Config
|
||||
{
|
||||
private Connection _connection;
|
||||
private Dictionary<UInt32, object> _transactions = new Dictionary<UInt32, object>();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Config object for setting runtime configuration settings.
|
||||
///
|
||||
/// Note that the Controller.Config provides a properly initialized Config object already.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public Config(Connection.Key connectionKey)
|
||||
{
|
||||
_connection = Connection.GetConnection(connectionKey);
|
||||
_connection.LeapConfigChange += handleConfigChange;
|
||||
_connection.LeapConfigResponse += handleConfigResponse;
|
||||
}
|
||||
public Config(int connectionId) : this(new Connection.Key(connectionId)) { }
|
||||
|
||||
private void handleConfigChange(object sender, ConfigChangeEventArgs eventArgs)
|
||||
{
|
||||
object actionDelegate;
|
||||
if (_transactions.TryGetValue(eventArgs.RequestId, out actionDelegate))
|
||||
{
|
||||
Action<bool> changeAction = actionDelegate as Action<bool>;
|
||||
changeAction(eventArgs.Succeeded);
|
||||
_transactions.Remove(eventArgs.RequestId);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleConfigResponse(object sender, SetConfigResponseEventArgs eventArgs)
|
||||
{
|
||||
object actionDelegate = new object();
|
||||
if (_transactions.TryGetValue(eventArgs.RequestId, out actionDelegate))
|
||||
{
|
||||
switch (eventArgs.DataType)
|
||||
{
|
||||
case ValueType.TYPE_BOOLEAN:
|
||||
Action<bool> boolAction = actionDelegate as Action<bool>;
|
||||
boolAction((int)eventArgs.Value != 0);
|
||||
break;
|
||||
case ValueType.TYPE_FLOAT:
|
||||
Action<float> floatAction = actionDelegate as Action<float>;
|
||||
floatAction((float)eventArgs.Value);
|
||||
break;
|
||||
case ValueType.TYPE_INT32:
|
||||
Action<Int32> intAction = actionDelegate as Action<Int32>;
|
||||
intAction((Int32)eventArgs.Value);
|
||||
break;
|
||||
case ValueType.TYPE_STRING:
|
||||
Action<string> stringAction = actionDelegate as Action<string>;
|
||||
stringAction((string)eventArgs.Value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_transactions.Remove(eventArgs.RequestId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests a configuration value.
|
||||
///
|
||||
/// You must provide an action to take when the Leap service returns the config value.
|
||||
/// The Action delegate must take a parameter matching the config value type. The current
|
||||
/// value of the setting is passed to this delegate.
|
||||
///
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public bool Get<T>(string key, Action<T> onResult)
|
||||
{
|
||||
uint requestId = _connection.GetConfigValue(key);
|
||||
if (requestId > 0)
|
||||
{
|
||||
_transactions.Add(requestId, onResult);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a configuration value.
|
||||
///
|
||||
/// You must provide an action to take when the Leap service sets the config value.
|
||||
/// The Action delegate must take a boolean parameter. The service calls this delegate
|
||||
/// with the value true if the setting was changed successfully and false, otherwise.
|
||||
///
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public bool Set<T>(string key, T value, Action<bool> onResult) where T : IConvertible
|
||||
{
|
||||
uint requestId = _connection.SetConfigValue<T>(key, value);
|
||||
|
||||
if (requestId > 0)
|
||||
{
|
||||
_transactions.Add(requestId, onResult);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[Obsolete("Use the generic Set<T> method instead.")]
|
||||
public ValueType Type(string key)
|
||||
{
|
||||
return ValueType.TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
[Obsolete("Use the generic Get<T> method instead.")]
|
||||
public bool GetBool(string key)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[Obsolete("Use the generic Set<T> method instead.")]
|
||||
public bool SetBool(string key, bool value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[Obsolete("Use the generic Get<T> method instead.")]
|
||||
public bool GetInt32(string key)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[Obsolete("Use the generic Set<T> method instead.")]
|
||||
public bool SetInt32(string key, int value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[Obsolete("Use the generic Get<T> method instead.")]
|
||||
public bool GetFloat(string key)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[Obsolete("Use the generic Set<T> method instead.")]
|
||||
public bool SetFloat(string key, float value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[Obsolete("Use the generic Get<T> method instead.")]
|
||||
public bool GetString(string key)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[Obsolete("Use the generic Set<T> method instead.")]
|
||||
public bool SetString(string key, string value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public bool Save()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates the possible data types for configuration values.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public enum ValueType
|
||||
{
|
||||
TYPE_UNKNOWN = 0,
|
||||
TYPE_BOOLEAN = 1,
|
||||
TYPE_INT32 = 2,
|
||||
TYPE_FLOAT = 6,
|
||||
TYPE_STRING = 8,
|
||||
}
|
||||
}
|
||||
}
|
1119
ml_lme_cvr/vendor/LeapCSharp/Connection.cs
vendored
Normal file
1119
ml_lme_cvr/vendor/LeapCSharp/Connection.cs
vendored
Normal file
File diff suppressed because it is too large
Load diff
894
ml_lme_cvr/vendor/LeapCSharp/Controller.cs
vendored
Normal file
894
ml_lme_cvr/vendor/LeapCSharp/Controller.cs
vendored
Normal file
|
@ -0,0 +1,894 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using LeapInternal;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// The Controller class is your main interface to the Leap Motion Controller.
|
||||
///
|
||||
/// Create an instance of this Controller class to access frames of tracking
|
||||
/// data and configuration information.Frame data can be polled at any time
|
||||
/// using the Controller.Frame() function.Call frame() or frame(0) to get the
|
||||
/// most recent frame.Set the history parameter to a positive integer to access
|
||||
/// previous frames.A controller stores up to 60 frames in its frame history.
|
||||
///
|
||||
///
|
||||
/// Polling is an appropriate strategy for applications which already have an
|
||||
/// intrinsic update loop, such as a game. You can also subscribe to the FrameReady
|
||||
/// event to get tracking frames through an event delegate.
|
||||
///
|
||||
/// If the current thread implements a SynchronizationContext that contains a message
|
||||
/// loop, events are posted to that threads message loop. Otherwise, events are called
|
||||
/// on an independent thread and applications must perform any needed synchronization
|
||||
/// or marshalling of data between threads. Note that Unity3D does not create an
|
||||
/// appropriate SynchronizationContext object. Typically, event handlers cannot access
|
||||
/// any Unity objects.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public class Controller :
|
||||
IController
|
||||
{
|
||||
Connection _connection;
|
||||
bool _disposed = false;
|
||||
bool _supportsMultipleDevices = true;
|
||||
string _serverNamespace = "Leap Service";
|
||||
Config _config;
|
||||
|
||||
/// <summary>
|
||||
/// The SynchronizationContext used for dispatching events.
|
||||
///
|
||||
/// By default the synchronization context of the thread creating the controller
|
||||
/// instance is used. You can change the context if desired.
|
||||
/// </summary>
|
||||
public SynchronizationContext EventContext
|
||||
{
|
||||
get
|
||||
{
|
||||
return _connection.EventContext;
|
||||
}
|
||||
set
|
||||
{
|
||||
_connection.EventContext = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when the connection is initialized (but not necessarily connected).
|
||||
///
|
||||
/// Can be dispatched more than once, if connection is restarted.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public event EventHandler<LeapEventArgs> Init
|
||||
{
|
||||
add
|
||||
{
|
||||
if (_hasInitialized)
|
||||
value(this, new LeapEventArgs(LeapEvent.EVENT_INIT));
|
||||
_init += value;
|
||||
}
|
||||
remove { _init -= value; }
|
||||
}
|
||||
|
||||
private bool _hasInitialized = false;
|
||||
private EventHandler<LeapEventArgs> _init;
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when the connection to the service is established.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public event EventHandler<ConnectionEventArgs> Connect
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapConnection += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapConnection -= value;
|
||||
}
|
||||
}
|
||||
|
||||
private EventHandler<ConnectionEventArgs> _connect;
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched if the connection to the service is lost.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public event EventHandler<ConnectionLostEventArgs> Disconnect
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapConnectionLost += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapConnectionLost -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when a tracking frame is ready.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public event EventHandler<FrameEventArgs> FrameReady
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapFrame += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapFrame -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when an internal tracking frame is ready.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public event EventHandler<InternalFrameEventArgs> InternalFrameReady
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapInternalFrame += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapInternalFrame -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when a Leap Motion device is connected.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public event EventHandler<DeviceEventArgs> Device
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapDevice += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapDevice -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when a Leap Motion device is disconnected.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public event EventHandler<DeviceEventArgs> DeviceLost
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapDeviceLost += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapDeviceLost -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when a Leap device fails to initialize.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public event EventHandler<DeviceFailureEventArgs> DeviceFailure
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapDeviceFailure += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapDeviceFailure -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when the system generates a loggable event.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public event EventHandler<LogEventArgs> LogMessage
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapLogEvent += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapLogEvent -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when a policy changes.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public event EventHandler<PolicyEventArgs> PolicyChange
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapPolicyChange += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapPolicyChange -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when a configuration setting changes.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public event EventHandler<ConfigChangeEventArgs> ConfigChange
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapConfigChange += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapConfigChange -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when the image distortion map changes.
|
||||
/// The distortion map can change when the Leap device switches orientation,
|
||||
/// or a new device becomes active.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public event EventHandler<DistortionEventArgs> DistortionChange
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapDistortionChange += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapDistortionChange -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when the service drops a tracking frame.
|
||||
/// </summary>
|
||||
public event EventHandler<DroppedFrameEventArgs> DroppedFrame
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapDroppedFrame += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapDroppedFrame -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when an unrequested image is ready.
|
||||
/// @since 4.0
|
||||
/// </summary>
|
||||
public event EventHandler<ImageEventArgs> ImageReady
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapImage += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapImage -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched whenever a thread wants to start profiling for a custom thread.
|
||||
/// The event is always dispatched from the thread itself.
|
||||
///
|
||||
/// The event data will contain the name of the thread, as well as an array of
|
||||
/// all possible profiling blocks that could be entered on that thread.
|
||||
///
|
||||
/// @since 4.0
|
||||
/// </summary>
|
||||
public event Action<BeginProfilingForThreadArgs> BeginProfilingForThread
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapBeginProfilingForThread += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapBeginProfilingForThread -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched whenever a thread is finished profiling. The event is always
|
||||
/// dispatched from the thread itself.
|
||||
///
|
||||
/// @since 4.0
|
||||
/// </summary>
|
||||
public event Action<EndProfilingForThreadArgs> EndProfilingForThread
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapEndProfilingForThread += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapEndProfilingForThread -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched whenever a thread enters a profiling block. The event is always
|
||||
/// dispatched from the thread itself.
|
||||
///
|
||||
/// The event data will contain the name of the profiling block.
|
||||
///
|
||||
/// @since 4.0
|
||||
/// </summary>
|
||||
public event Action<BeginProfilingBlockArgs> BeginProfilingBlock
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapBeginProfilingBlock += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapBeginProfilingBlock -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched whenever a thread ends a profiling block. The event is always
|
||||
/// dispatched from the thread itself.
|
||||
///
|
||||
/// The event data will contain the name of the profiling block.
|
||||
///
|
||||
/// @since 4.0
|
||||
/// </summary>
|
||||
public event Action<EndProfilingBlockArgs> EndProfilingBlock
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapEndProfilingBlock += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapEndProfilingBlock -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when point mapping change events are generated by the service.
|
||||
/// @since 4.0
|
||||
/// </summary>
|
||||
public event EventHandler<PointMappingChangeEventArgs> PointMappingChange
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapPointMappingChange += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapPointMappingChange -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when a new HeadPose is available.
|
||||
/// </summary>
|
||||
public event EventHandler<HeadPoseEventArgs> HeadPoseChange
|
||||
{
|
||||
add
|
||||
{
|
||||
_connection.LeapHeadPoseChange += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
_connection.LeapHeadPoseChange -= value;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// Protected implementation of Dispose pattern.
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_connection.Dispose();
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a Controller object.
|
||||
///
|
||||
/// The default constructor uses a connection key of 0.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Controller() : this(0, null, true) { }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a Controller object using the specified connection key.
|
||||
///
|
||||
/// All controller instances using the same key will use the same connection
|
||||
/// to the service. In general, an application should not use more than one connection
|
||||
/// for all its controllers. Each connection keeps its own cache of frames and images.
|
||||
///
|
||||
/// @param connectionKey An identifier specifying the connection to use. If a
|
||||
/// connection with the specified key already exists, that connection is used.
|
||||
/// Otherwise, a new connection is created.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public Controller(int connectionKey, string serverNamespace = "Leap Service", bool supportsMultipleDevices = true)
|
||||
{
|
||||
_connection = Connection.GetConnection(new Connection.Key(connectionKey, serverNamespace));
|
||||
_connection.EventContext = SynchronizationContext.Current;
|
||||
|
||||
_connection.LeapInit += OnInit;
|
||||
_connection.LeapConnection += OnConnect;
|
||||
_connection.LeapConnectionLost += OnDisconnect;
|
||||
|
||||
_supportsMultipleDevices = supportsMultipleDevices;
|
||||
_serverNamespace = serverNamespace;
|
||||
|
||||
_connection.Start(serverNamespace, supportsMultipleDevices);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Starts the connection.
|
||||
///
|
||||
/// A connection starts automatically when created, but you can
|
||||
/// use this function to restart the connection after stopping it.
|
||||
///
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public void StartConnection()
|
||||
{
|
||||
_connection.Start(_serverNamespace, _supportsMultipleDevices);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops the connection.
|
||||
///
|
||||
/// No more frames or other events are received from a stopped connection. You can
|
||||
/// restart with StartConnection().
|
||||
///
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public void StopConnection()
|
||||
{
|
||||
_connection.Stop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reports whether your application has a connection to the Leap Motion
|
||||
/// daemon/service. Can be true even if the Leap Motion hardware is not available.
|
||||
/// @since 1.2
|
||||
/// </summary>
|
||||
public bool IsServiceConnected
|
||||
{
|
||||
get
|
||||
{
|
||||
return _connection.IsServiceConnected;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests setting a policy.
|
||||
///
|
||||
/// A request to change a policy is subject to user approval and a policy
|
||||
/// can be changed by the user at any time (using the Leap Motion settings dialog).
|
||||
/// The desired policy flags must be set every time an application runs.
|
||||
///
|
||||
/// Policy changes are completed asynchronously and, because they are subject
|
||||
/// to user approval or system compatibility checks, may not complete successfully. Call
|
||||
/// Controller.IsPolicySet() after a suitable interval to test whether
|
||||
/// the change was accepted.
|
||||
/// @since 2.1.6
|
||||
/// </summary>
|
||||
public void SetAndClearPolicy(PolicyFlag set, PolicyFlag clear, string deviceSerial = "")
|
||||
{
|
||||
_connection.SetAndClearPolicy(set, clear);
|
||||
}
|
||||
|
||||
public void SetPolicy(PolicyFlag policy)
|
||||
{
|
||||
_connection.SetPolicy(policy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests clearing a policy.
|
||||
///
|
||||
/// Policy changes are completed asynchronously and, because they are subject
|
||||
/// to user approval or system compatibility checks, may not complete successfully. Call
|
||||
/// Controller.IsPolicySet() after a suitable interval to test whether
|
||||
/// the change was accepted.
|
||||
/// @since 2.1.6
|
||||
/// </summary>
|
||||
public void ClearPolicy(PolicyFlag policy)
|
||||
{
|
||||
_connection.ClearPolicy(policy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the active setting for a specific policy.
|
||||
///
|
||||
/// Keep in mind that setting a policy flag is asynchronous, so changes are
|
||||
/// not effective immediately after calling setPolicyFlag(). In addition, a
|
||||
/// policy request can be declined by the user. You should always set the
|
||||
/// policy flags required by your application at startup and check that the
|
||||
/// policy change request was successful after an appropriate interval.
|
||||
///
|
||||
/// If the controller object is not connected to the Leap Motion software, then the default
|
||||
/// state for the selected policy is returned.
|
||||
///
|
||||
/// @since 2.1.6
|
||||
/// </summary>
|
||||
public bool IsPolicySet(PolicyFlag policy)
|
||||
{
|
||||
return _connection.IsPolicySet(policy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// In most cases you should get Frame objects using the LeapProvider.CurrentFrame
|
||||
/// property. The data in Frame objects taken directly from a Leap.Controller instance
|
||||
/// is still in the Leap Motion frame of reference and will not match the hands
|
||||
/// displayed in a Unity scene.
|
||||
///
|
||||
/// Returns a frame of tracking data from the Leap Motion software. Use the optional
|
||||
/// history parameter to specify which frame to retrieve. Call frame() or
|
||||
/// frame(0) to access the most recent frame; call frame(1) to access the
|
||||
/// previous frame, and so on. If you use a history value greater than the
|
||||
/// number of stored frames, then the controller returns an empty frame.
|
||||
///
|
||||
/// @param history The age of the frame to return, counting backwards from
|
||||
/// the most recent frame (0) into the past and up to the maximum age (59).
|
||||
/// @returns The specified frame; or, if no history parameter is specified,
|
||||
/// the newest frame. If a frame is not available at the specified history
|
||||
/// position, an invalid Frame is returned.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Frame Frame(int history = 0)
|
||||
{
|
||||
Frame frame = new Frame();
|
||||
Frame(frame, history);
|
||||
return frame;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identical to Frame(history) but instead of constructing a new frame and returning
|
||||
/// it, the user provides a frame object to be filled with data instead.
|
||||
/// </summary>
|
||||
public void Frame(Frame toFill, int history = 0)
|
||||
{
|
||||
LEAP_TRACKING_EVENT trackingEvent;
|
||||
_connection.Frames.Get(out trackingEvent, history);
|
||||
toFill.CopyFrom(ref trackingEvent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the timestamp of a recent tracking frame. Use the
|
||||
/// optional history parameter to specify how many frames in the past
|
||||
/// to retrieve the timestamp. Leave the history parameter as
|
||||
/// it's default value to return the timestamp of the most recent
|
||||
/// tracked frame.
|
||||
/// </summary>
|
||||
public long FrameTimestamp(int history = 0)
|
||||
{
|
||||
LEAP_TRACKING_EVENT trackingEvent;
|
||||
_connection.Frames.Get(out trackingEvent, history);
|
||||
return trackingEvent.info.timestamp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the frame object with all hands transformed by the specified
|
||||
/// transform matrix.
|
||||
/// </summary>
|
||||
public Frame GetTransformedFrame(LeapTransform trs, int history = 0)
|
||||
{
|
||||
return new Frame().CopyFrom(Frame(history)).Transform(trs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Frame at the specified time, interpolating the data between existing frames, if necessary.
|
||||
/// </summary>
|
||||
public Frame GetInterpolatedFrame(Int64 time)
|
||||
{
|
||||
return _connection.GetInterpolatedFrame(time);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fills the Frame with data taken at the specified time, interpolating the data between existing frames, if necessary.
|
||||
/// </summary>
|
||||
public void GetInterpolatedFrame(Frame toFill, Int64 time)
|
||||
{
|
||||
_connection.GetInterpolatedFrame(toFill, time);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Head pose at the specified time, interpolating the data between existing frames, if necessary.
|
||||
/// </summary>
|
||||
public LEAP_HEAD_POSE_EVENT GetInterpolatedHeadPose(Int64 time)
|
||||
{
|
||||
return _connection.GetInterpolatedHeadPose(time);
|
||||
}
|
||||
|
||||
public void GetInterpolatedHeadPose(ref LEAP_HEAD_POSE_EVENT toFill, Int64 time)
|
||||
{
|
||||
_connection.GetInterpolatedHeadPose(ref toFill, time);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes to the events coming from an individual device
|
||||
///
|
||||
/// If this is not called, only the primary device will be subscribed.
|
||||
/// Will automatically unsubscribe the primary device if this is called
|
||||
/// on a secondary device, but not a primary one.
|
||||
///
|
||||
/// @since 4.1
|
||||
/// </summary>
|
||||
public void SubscribeToDeviceEvents(Device device)
|
||||
{
|
||||
_connection.SubscribeToDeviceEvents(device);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes from the events coming from an individual device
|
||||
///
|
||||
/// This can be called safely, even if the device has not been subscribed.
|
||||
///
|
||||
/// @since 4.1
|
||||
/// </summary>
|
||||
public void UnsubscribeFromDeviceEvents(Device device)
|
||||
{
|
||||
_connection.UnsubscribeFromDeviceEvents(device);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes to the events coming from all devices
|
||||
///
|
||||
/// @since 4.1
|
||||
/// </summary>
|
||||
public void SubscribeToAllDevices()
|
||||
{
|
||||
for (int i = 1; i < Devices.Count; i++)
|
||||
{
|
||||
_connection.SubscribeToDeviceEvents(Devices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes from the events coming from all devices
|
||||
///
|
||||
/// @since 4.1
|
||||
/// </summary>
|
||||
public void UnsubscribeFromAllDevices()
|
||||
{
|
||||
for (int i = 1; i < Devices.Count; i++)
|
||||
{
|
||||
_connection.UnsubscribeFromDeviceEvents(Devices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void TelemetryProfiling(ref LEAP_TELEMETRY_DATA telemetryData)
|
||||
{
|
||||
_connection.TelemetryProfiling(ref telemetryData);
|
||||
}
|
||||
|
||||
public UInt64 TelemetryGetNow()
|
||||
{
|
||||
return LeapC.TelemetryGetNow();
|
||||
}
|
||||
|
||||
public void GetPointMapping(ref PointMapping pointMapping)
|
||||
{
|
||||
_connection.GetPointMapping(ref pointMapping);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is a special variant of GetInterpolatedFrameFromTime, for use with special
|
||||
/// features that only require the position and orientation of the palm positions, and do
|
||||
/// not care about pose data or any other data.
|
||||
///
|
||||
/// You must specify the id of the hand that you wish to get a transform for. If you specify
|
||||
/// an id that is not present in the interpolated frame, the output transform will be the
|
||||
/// identity transform.
|
||||
/// </summary>
|
||||
public void GetInterpolatedLeftRightTransform(Int64 time,
|
||||
Int64 sourceTime,
|
||||
int leftId,
|
||||
int rightId,
|
||||
out LeapTransform leftTransform,
|
||||
out LeapTransform rightTransform)
|
||||
{
|
||||
_connection.GetInterpolatedLeftRightTransform(time, sourceTime, leftId, rightId, out leftTransform, out rightTransform);
|
||||
}
|
||||
|
||||
public void GetInterpolatedFrameFromTime(Frame toFill, Int64 time, Int64 sourceTime)
|
||||
{
|
||||
_connection.GetInterpolatedFrameFromTime(toFill, time, sourceTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a timestamp value as close as possible to the current time.
|
||||
/// Values are in microseconds, as with all the other timestamp values.
|
||||
///
|
||||
/// @since 2.2.7
|
||||
/// </summary>
|
||||
public long Now()
|
||||
{
|
||||
return LeapC.GetNow();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reports whether this Controller is connected to the Leap Motion service and
|
||||
/// the Leap Motion hardware is plugged in.
|
||||
///
|
||||
/// When you first create a Controller object, isConnected() returns false.
|
||||
/// After the controller finishes initializing and connects to the Leap Motion
|
||||
/// software and if the Leap Motion hardware is plugged in, isConnected() returns true.
|
||||
///
|
||||
/// You can either handle the onConnect event using a Listener instance or
|
||||
/// poll the isConnected() function if you need to wait for your
|
||||
/// application to be connected to the Leap Motion software before performing some other
|
||||
/// operation.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public bool IsConnected
|
||||
{
|
||||
get
|
||||
{
|
||||
return IsServiceConnected && Devices.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a Config object, which you can use to query the Leap Motion system for
|
||||
/// configuration information.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Config Config
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_config == null)
|
||||
_config = new Config(this._connection.ConnectionKey);
|
||||
return _config;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The list of currently attached and recognized Leap Motion controller devices.
|
||||
///
|
||||
/// The Device objects in the list describe information such as the range and
|
||||
/// tracking volume.
|
||||
///
|
||||
/// Currently, the Leap Motion Controller only allows a single active device at a time,
|
||||
/// however there may be multiple devices physically attached and listed here. Any active
|
||||
/// device(s) are guaranteed to be listed first, however order is not determined beyond that.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public DeviceList Devices
|
||||
{
|
||||
get
|
||||
{
|
||||
return _connection.Devices;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A list of any Leap Motion hardware devices that are physically connected to
|
||||
/// the client computer, but are not functioning correctly. The list contains
|
||||
/// FailedDevice objects containing the pnpID and the reason for failure. No
|
||||
/// other device information is available.
|
||||
///
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public FailedDeviceList FailedDevices()
|
||||
{
|
||||
return _connection.FailedDevices;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The supported controller policies.
|
||||
///
|
||||
/// The supported policy flags are:
|
||||
///
|
||||
/// **POLICY_BACKGROUND_FRAMES** -- requests that your application receives frames
|
||||
/// when it is not the foreground application for user input.
|
||||
///
|
||||
/// The background frames policy determines whether an application
|
||||
/// receives frames of tracking data while in the background. By
|
||||
/// default, the Leap Motion software only sends tracking data to the foreground application.
|
||||
/// Only applications that need this ability should request the background
|
||||
/// frames policy. The "Allow Background Apps" checkbox must be enabled in the
|
||||
/// Leap Motion Control Panel or this policy will be denied.
|
||||
///
|
||||
/// **POLICY_OPTIMIZE_HMD** -- request that the tracking be optimized for head-mounted
|
||||
/// tracking.
|
||||
///
|
||||
/// The optimize HMD policy improves tracking in situations where the Leap
|
||||
/// Motion hardware is attached to a head-mounted display. This policy is
|
||||
/// not granted for devices that cannot be mounted to an HMD, such as
|
||||
/// Leap Motion controllers embedded in a laptop or keyboard.
|
||||
///
|
||||
/// Some policies can be denied if the user has disabled the feature on
|
||||
/// their Leap Motion control panel.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public enum PolicyFlag
|
||||
{
|
||||
/// <summary>
|
||||
/// The default policy.
|
||||
/// </summary>
|
||||
POLICY_DEFAULT = 0,
|
||||
/// <summary>
|
||||
/// Receive background frames.
|
||||
/// </summary>
|
||||
POLICY_BACKGROUND_FRAMES = (1 << 0),
|
||||
/// <summary>
|
||||
/// Allow streaming images.
|
||||
/// </summary>
|
||||
POLICY_IMAGES = (1 << 1),
|
||||
/// <summary>
|
||||
/// Optimize the tracking for head-mounted device.
|
||||
/// </summary>
|
||||
POLICY_OPTIMIZE_HMD = (1 << 2),
|
||||
/// <summary>
|
||||
/// Allow pausing and unpausing of the Leap Motion service.
|
||||
/// </summary>
|
||||
POLICY_ALLOW_PAUSE_RESUME = (1 << 3),
|
||||
/// <summary>
|
||||
/// Allow streaming map point
|
||||
/// </summary>
|
||||
POLICY_MAP_POINTS = (1 << 7),
|
||||
/// <summary>
|
||||
/// Optimize the tracking for screen-top device.
|
||||
/// @since 5.0.0
|
||||
/// </summary>
|
||||
POLICY_OPTIMIZE_SCREENTOP = (1 << 8),
|
||||
}
|
||||
|
||||
protected virtual void OnInit(object sender, LeapEventArgs eventArgs)
|
||||
{
|
||||
_hasInitialized = true;
|
||||
}
|
||||
|
||||
protected virtual void OnConnect(object sender, ConnectionEventArgs eventArgs)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void OnDisconnect(object sender, ConnectionLostEventArgs eventArgs)
|
||||
{
|
||||
_hasInitialized = false;
|
||||
}
|
||||
}
|
||||
}
|
142
ml_lme_cvr/vendor/LeapCSharp/CopyFromLeapCExtensions.cs
vendored
Normal file
142
ml_lme_cvr/vendor/LeapCSharp/CopyFromLeapCExtensions.cs
vendored
Normal file
|
@ -0,0 +1,142 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace LeapInternal
|
||||
{
|
||||
using Leap;
|
||||
|
||||
public static class CopyFromLeapCExtensions
|
||||
{
|
||||
|
||||
/**
|
||||
* Copies the data from an internal tracking message into a frame.
|
||||
*
|
||||
* @param trackingMsg The internal tracking message with the data to be copied into this frame.
|
||||
*/
|
||||
public static Frame CopyFrom(this Frame frame, ref LEAP_TRACKING_EVENT trackingMsg)
|
||||
{
|
||||
frame.Id = (long)trackingMsg.info.frame_id;
|
||||
frame.Timestamp = (long)trackingMsg.info.timestamp;
|
||||
frame.CurrentFramesPerSecond = trackingMsg.framerate;
|
||||
|
||||
frame.ResizeHandList((int)trackingMsg.nHands);
|
||||
|
||||
for (int i = frame.Hands.Count; i-- != 0;)
|
||||
{
|
||||
LEAP_HAND hand;
|
||||
StructMarshal<LEAP_HAND>.ArrayElementToStruct(trackingMsg.pHands, i, out hand);
|
||||
frame.Hands[i].CopyFrom(ref hand, frame.Id);
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the data from an internal hand definition into a hand.
|
||||
*
|
||||
* @param leapHand The internal hand definition to be copied into this hand.
|
||||
* @param frameId The frame id of the frame this hand belongs to.
|
||||
*/
|
||||
public static Hand CopyFrom(this Hand hand, ref LEAP_HAND leapHand, long frameId)
|
||||
{
|
||||
hand.FrameId = frameId;
|
||||
hand.Id = (int)leapHand.id;
|
||||
|
||||
hand.Arm.CopyFrom(leapHand.arm, Bone.BoneType.TYPE_INVALID);
|
||||
|
||||
hand.Confidence = leapHand.confidence;
|
||||
hand.GrabStrength = leapHand.grab_strength;
|
||||
hand.GrabAngle = leapHand.grab_angle;
|
||||
hand.PinchStrength = leapHand.pinch_strength;
|
||||
hand.PinchDistance = leapHand.pinch_distance;
|
||||
hand.PalmWidth = leapHand.palm.width;
|
||||
hand.IsLeft = leapHand.type == eLeapHandType.eLeapHandType_Left;
|
||||
hand.TimeVisible = (float)(leapHand.visible_time * 1e-6);
|
||||
hand.PalmPosition = leapHand.palm.position.ToLeapVector();
|
||||
hand.StabilizedPalmPosition = leapHand.palm.stabilized_position.ToLeapVector();
|
||||
hand.PalmVelocity = leapHand.palm.velocity.ToLeapVector();
|
||||
hand.PalmNormal = leapHand.palm.normal.ToLeapVector();
|
||||
hand.Rotation = leapHand.palm.orientation.ToLeapQuaternion();
|
||||
hand.Direction = leapHand.palm.direction.ToLeapVector();
|
||||
hand.WristPosition = hand.Arm.NextJoint;
|
||||
|
||||
hand.Fingers[0].CopyFrom(leapHand.thumb, Leap.Finger.FingerType.TYPE_THUMB, hand.Id, hand.TimeVisible);
|
||||
hand.Fingers[1].CopyFrom(leapHand.index, Leap.Finger.FingerType.TYPE_INDEX, hand.Id, hand.TimeVisible);
|
||||
hand.Fingers[2].CopyFrom(leapHand.middle, Leap.Finger.FingerType.TYPE_MIDDLE, hand.Id, hand.TimeVisible);
|
||||
hand.Fingers[3].CopyFrom(leapHand.ring, Leap.Finger.FingerType.TYPE_RING, hand.Id, hand.TimeVisible);
|
||||
hand.Fingers[4].CopyFrom(leapHand.pinky, Leap.Finger.FingerType.TYPE_PINKY, hand.Id, hand.TimeVisible);
|
||||
|
||||
return hand;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the data from an internal finger definition into a finger.
|
||||
*
|
||||
* @param leapBone The internal finger definition to be copied into this finger.
|
||||
* @param type The finger type of this finger.
|
||||
* @param frameId The frame id of the frame this finger belongs to.
|
||||
* @param handId The hand id of the hand this finger belongs to.
|
||||
* @param timeVisible The time in seconds that this finger has been visible.
|
||||
*/
|
||||
public static Finger CopyFrom(this Finger finger, LEAP_DIGIT leapBone, Finger.FingerType type, int handId, float timeVisible)
|
||||
{
|
||||
finger.Id = (handId * 10) + leapBone.finger_id;
|
||||
finger.HandId = handId;
|
||||
finger.TimeVisible = timeVisible;
|
||||
|
||||
Bone metacarpal = finger.bones[0];
|
||||
Bone proximal = finger.bones[1];
|
||||
Bone intermediate = finger.bones[2];
|
||||
Bone distal = finger.bones[3];
|
||||
|
||||
metacarpal.CopyFrom(leapBone.metacarpal, Leap.Bone.BoneType.TYPE_METACARPAL);
|
||||
proximal.CopyFrom(leapBone.proximal, Leap.Bone.BoneType.TYPE_PROXIMAL);
|
||||
intermediate.CopyFrom(leapBone.intermediate, Leap.Bone.BoneType.TYPE_INTERMEDIATE);
|
||||
distal.CopyFrom(leapBone.distal, Leap.Bone.BoneType.TYPE_DISTAL);
|
||||
|
||||
finger.TipPosition = distal.NextJoint;
|
||||
finger.Direction = intermediate.Direction;
|
||||
finger.Width = intermediate.Width;
|
||||
finger.Length = (leapBone.finger_id == 0 ? 0.0f : 0.5f * proximal.Length) + intermediate.Length + 0.77f * distal.Length; //The values 0.5 for proximal and 0.77 for distal are used in platform code for this calculation
|
||||
finger.IsExtended = leapBone.is_extended != 0;
|
||||
finger.Type = type;
|
||||
|
||||
return finger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the data from an internal bone definition into a bone.
|
||||
*
|
||||
* @param leapBone The internal bone definition to be copied into this bone.
|
||||
* @param type The bone type of this bone.
|
||||
*/
|
||||
public static Bone CopyFrom(this Bone bone, LEAP_BONE leapBone, Bone.BoneType type)
|
||||
{
|
||||
bone.Type = type;
|
||||
bone.PrevJoint = leapBone.prev_joint.ToLeapVector();
|
||||
bone.NextJoint = leapBone.next_joint.ToLeapVector();
|
||||
bone.Direction = (bone.NextJoint - bone.PrevJoint);
|
||||
bone.Length = bone.Direction.Magnitude;
|
||||
|
||||
if (bone.Length < float.Epsilon)
|
||||
{
|
||||
bone.Direction = Vector.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
bone.Direction /= bone.Length;
|
||||
}
|
||||
|
||||
bone.Center = (bone.PrevJoint + bone.NextJoint) / 2.0f;
|
||||
bone.Rotation = leapBone.rotation.ToLeapQuaternion();
|
||||
bone.Width = leapBone.width;
|
||||
|
||||
return bone;
|
||||
}
|
||||
}
|
||||
}
|
120
ml_lme_cvr/vendor/LeapCSharp/CopyFromOtherExtensions.cs
vendored
Normal file
120
ml_lme_cvr/vendor/LeapCSharp/CopyFromOtherExtensions.cs
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
|
||||
public static class CopyFromOtherExtensions
|
||||
{
|
||||
|
||||
/**
|
||||
* Copies the data from a source frame into a frame. After the operation is
|
||||
* complete, the frame will be identical to the source frame.
|
||||
*
|
||||
* @param source The source frame that is copied into a frame.
|
||||
*/
|
||||
public static Frame CopyFrom(this Frame frame, Frame source)
|
||||
{
|
||||
frame.Id = source.Id;
|
||||
frame.Timestamp = source.Timestamp;
|
||||
frame.CurrentFramesPerSecond = source.CurrentFramesPerSecond;
|
||||
frame.DeviceID = source.DeviceID;
|
||||
|
||||
frame.ResizeHandList(source.Hands.Count);
|
||||
|
||||
for (int i = frame.Hands.Count; i-- != 0;)
|
||||
{
|
||||
frame.Hands[i].CopyFrom(source.Hands[i]);
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copies the data from a source hand into a hand. After the operation is
|
||||
* complete, the hand will be identical to the source hand.
|
||||
*
|
||||
* @param source The source hand that is copied into a hand.
|
||||
*/
|
||||
public static Hand CopyFrom(this Hand hand, Hand source)
|
||||
{
|
||||
hand.Id = source.Id;
|
||||
hand.Confidence = source.Confidence;
|
||||
hand.GrabStrength = source.GrabStrength;
|
||||
hand.GrabAngle = source.GrabAngle;
|
||||
hand.Rotation = source.Rotation;
|
||||
hand.PinchStrength = source.PinchStrength;
|
||||
hand.PinchDistance = source.PinchDistance;
|
||||
hand.PalmWidth = source.PalmWidth;
|
||||
hand.IsLeft = source.IsLeft;
|
||||
hand.TimeVisible = source.TimeVisible;
|
||||
hand.PalmPosition = source.PalmPosition;
|
||||
hand.StabilizedPalmPosition = source.StabilizedPalmPosition;
|
||||
hand.PalmVelocity = source.PalmVelocity;
|
||||
hand.PalmNormal = source.PalmNormal;
|
||||
hand.Direction = source.Direction;
|
||||
hand.WristPosition = source.WristPosition;
|
||||
|
||||
hand.Arm.CopyFrom(source.Arm);
|
||||
|
||||
for (int i = 5; i-- != 0;)
|
||||
{
|
||||
hand.Fingers[i].CopyFrom(source.Fingers[i]);
|
||||
}
|
||||
|
||||
return hand;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the data from a source finger into a finger. After the operation is
|
||||
* complete, the finger will be identical to the source finger.
|
||||
*
|
||||
* @param source The source finger that is copied into a finger.
|
||||
*/
|
||||
public static Finger CopyFrom(this Finger finger, Finger source)
|
||||
{
|
||||
for (int i = 4; i-- != 0;)
|
||||
{
|
||||
finger.bones[i].CopyFrom(source.bones[i]);
|
||||
}
|
||||
|
||||
finger.Id = source.Id;
|
||||
finger.HandId = source.HandId;
|
||||
finger.TimeVisible = source.TimeVisible;
|
||||
|
||||
finger.TipPosition = source.TipPosition;
|
||||
finger.Direction = source.Direction;
|
||||
finger.Width = source.Width;
|
||||
finger.Length = source.Length;
|
||||
finger.IsExtended = source.IsExtended;
|
||||
finger.Type = source.Type;
|
||||
|
||||
return finger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the data from a source bone into a bone. After the operation is
|
||||
* complete, the bone will be identical to the source bone.
|
||||
*
|
||||
* @param source The source bone that is copied into a bone.
|
||||
*/
|
||||
public static Bone CopyFrom(this Bone bone, Bone source)
|
||||
{
|
||||
bone.PrevJoint = source.PrevJoint;
|
||||
bone.NextJoint = source.NextJoint;
|
||||
bone.Direction = source.Direction;
|
||||
bone.Center = source.Center;
|
||||
bone.Length = source.Length;
|
||||
bone.Width = source.Width;
|
||||
bone.Rotation = source.Rotation;
|
||||
bone.Type = source.Type;
|
||||
|
||||
return bone;
|
||||
}
|
||||
}
|
||||
}
|
316
ml_lme_cvr/vendor/LeapCSharp/Device.cs
vendored
Normal file
316
ml_lme_cvr/vendor/LeapCSharp/Device.cs
vendored
Normal file
|
@ -0,0 +1,316 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using LeapInternal;
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// The Device class represents a physically connected device.
|
||||
///
|
||||
/// The Device class contains information related to a particular connected
|
||||
/// device such as device id, field of view relative to the device,
|
||||
/// and the position and orientation of the device in relative coordinates.
|
||||
///
|
||||
/// The position and orientation describe the alignment of the device relative to the user.
|
||||
/// The alignment relative to the user is only descriptive. Aligning devices to users
|
||||
/// provides consistency in the parameters that describe user interactions.
|
||||
///
|
||||
/// Note that Device objects can be invalid, which means that they do not contain
|
||||
/// valid device information and do not correspond to a physical device.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public class Device :
|
||||
IEquatable<Device>
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a default Device object.
|
||||
///
|
||||
/// Get valid Device objects from a DeviceList object obtained using the
|
||||
/// Controller.Devices() method.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Device() { }
|
||||
|
||||
public Device(IntPtr deviceHandle,
|
||||
IntPtr internalHandle,
|
||||
float horizontalViewAngle,
|
||||
float verticalViewAngle,
|
||||
float range,
|
||||
float baseline,
|
||||
DeviceType type,
|
||||
bool isStreaming,
|
||||
uint status,
|
||||
string serialNumber)
|
||||
{
|
||||
Handle = deviceHandle;
|
||||
InternalHandle = internalHandle;
|
||||
HorizontalViewAngle = horizontalViewAngle;
|
||||
VerticalViewAngle = verticalViewAngle;
|
||||
Range = range;
|
||||
Baseline = baseline;
|
||||
Type = type;
|
||||
IsStreaming = isStreaming;
|
||||
SerialNumber = serialNumber;
|
||||
UpdateStatus((eLeapDeviceStatus)status);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For internal use only.
|
||||
/// </summary>
|
||||
public void Update(
|
||||
float horizontalViewAngle,
|
||||
float verticalViewAngle,
|
||||
float range,
|
||||
float baseline,
|
||||
uint status,
|
||||
string serialNumber)
|
||||
{
|
||||
HorizontalViewAngle = horizontalViewAngle;
|
||||
VerticalViewAngle = verticalViewAngle;
|
||||
Range = range;
|
||||
Baseline = baseline;
|
||||
SerialNumber = serialNumber;
|
||||
UpdateStatus((eLeapDeviceStatus)status);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For internal use only.
|
||||
/// </summary>
|
||||
public void Update(Device updatedDevice)
|
||||
{
|
||||
HorizontalViewAngle = updatedDevice.HorizontalViewAngle;
|
||||
VerticalViewAngle = updatedDevice.VerticalViewAngle;
|
||||
Range = updatedDevice.Range;
|
||||
Baseline = updatedDevice.Baseline;
|
||||
IsStreaming = updatedDevice.IsStreaming;
|
||||
SerialNumber = updatedDevice.SerialNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the status fields by parsing the uint given by the event
|
||||
/// </summary>
|
||||
internal void UpdateStatus(eLeapDeviceStatus status)
|
||||
{
|
||||
if ((status & eLeapDeviceStatus.eLeapDeviceStatus_Streaming) == eLeapDeviceStatus.eLeapDeviceStatus_Streaming)
|
||||
IsStreaming = true;
|
||||
else
|
||||
IsStreaming = false;
|
||||
if ((status & eLeapDeviceStatus.eLeapDeviceStatus_Smudged) == eLeapDeviceStatus.eLeapDeviceStatus_Smudged)
|
||||
IsSmudged = true;
|
||||
else
|
||||
IsSmudged = false;
|
||||
if ((status & eLeapDeviceStatus.eLeapDeviceStatus_Robust) == eLeapDeviceStatus.eLeapDeviceStatus_Robust)
|
||||
IsLightingBad = true;
|
||||
else
|
||||
IsLightingBad = false;
|
||||
if ((status & eLeapDeviceStatus.eLeapDeviceStatus_LowResource) == eLeapDeviceStatus.eLeapDeviceStatus_LowResource)
|
||||
IsLowResource = true;
|
||||
else
|
||||
IsLowResource = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For internal use only.
|
||||
/// </summary>
|
||||
public IntPtr Handle { get; private set; }
|
||||
|
||||
private IntPtr InternalHandle;
|
||||
|
||||
public bool SetPaused(bool pause)
|
||||
{
|
||||
eLeapRS result = LeapC.LeapSetPause(Handle, pause);
|
||||
return result == eLeapRS.eLeapRS_Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare Device object equality.
|
||||
///
|
||||
/// Two Device objects are equal if and only if both Device objects represent the
|
||||
/// exact same Device and both Devices are valid.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public bool Equals(Device other)
|
||||
{
|
||||
return SerialNumber == other.SerialNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A string containing a brief, human readable description of the Device object.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return "Device serial# " + this.SerialNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The angle in radians of view along the x axis of this device.
|
||||
///
|
||||
/// The Leap Motion controller scans a region in the shape of an inverted pyramid
|
||||
/// centered at the device's center and extending upwards. The horizontalViewAngle
|
||||
/// reports the view angle along the long dimension of the device.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float HorizontalViewAngle { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The angle in radians of view along the z axis of this device.
|
||||
///
|
||||
/// The Leap Motion controller scans a region in the shape of an inverted pyramid
|
||||
/// centered at the device's center and extending upwards. The verticalViewAngle
|
||||
/// reports the view angle along the short dimension of the device.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float VerticalViewAngle { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The maximum reliable tracking range from the center of this device.
|
||||
///
|
||||
/// The range reports the maximum recommended distance from the device center
|
||||
/// for which tracking is expected to be reliable. This distance is not a hard limit.
|
||||
/// Tracking may be still be functional above this distance or begin to degrade slightly
|
||||
/// before this distance depending on calibration and extreme environmental conditions.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float Range { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The distance in mm between the center points of the stereo sensors.
|
||||
///
|
||||
/// The baseline value, together with the maximum resolution, influence the
|
||||
/// maximum range.
|
||||
///
|
||||
/// @since 2.2.5
|
||||
/// </summary>
|
||||
public float Baseline { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reports whether this device is streaming data to your application.
|
||||
///
|
||||
/// Currently only one controller can provide data at a time.
|
||||
/// @since 1.2
|
||||
/// </summary>
|
||||
public bool IsStreaming { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The device type.
|
||||
///
|
||||
/// Use the device type value in the (rare) circumstances that you
|
||||
/// have an application feature which relies on a particular type of device.
|
||||
/// Current types of device include the original Leap Motion peripheral,
|
||||
/// keyboard-embedded controllers, and laptop-embedded controllers.
|
||||
///
|
||||
/// @since 1.2
|
||||
/// </summary>
|
||||
public DeviceType Type { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// An alphanumeric serial number unique to each device.
|
||||
///
|
||||
/// Consumer device serial numbers consist of 2 letters followed by 11 digits.
|
||||
///
|
||||
/// When using multiple devices, the serial number provides an unambiguous
|
||||
/// identifier for each device.
|
||||
/// @since 2.2.2
|
||||
/// </summary>
|
||||
public string SerialNumber { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the internal status field of the current device
|
||||
/// </summary>
|
||||
protected uint GetDeviceStatus()
|
||||
{
|
||||
eLeapRS result;
|
||||
|
||||
LEAP_DEVICE_INFO deviceInfo = new LEAP_DEVICE_INFO();
|
||||
deviceInfo.serial = IntPtr.Zero;
|
||||
deviceInfo.size = (uint)System.Runtime.InteropServices.Marshal.SizeOf(deviceInfo);
|
||||
result = LeapC.GetDeviceInfo(InternalHandle, ref deviceInfo);
|
||||
|
||||
if (result != eLeapRS.eLeapRS_Success)
|
||||
return 0;
|
||||
uint status = deviceInfo.status;
|
||||
System.Runtime.InteropServices.Marshal.FreeCoTaskMem(deviceInfo.serial);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The software has detected a possible smudge on the translucent cover
|
||||
/// over the Leap Motion cameras.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public bool IsSmudged { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The software has entered low-resource mode
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public bool IsLowResource { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The software has detected excessive IR illumination, which may interfere
|
||||
/// with tracking. If robust mode is enabled, the system will enter robust mode when
|
||||
/// isLightingBad() is true.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public bool IsLightingBad { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The available types of Leap Motion controllers.
|
||||
/// </summary>
|
||||
public enum DeviceType
|
||||
{
|
||||
TYPE_INVALID = -1,
|
||||
|
||||
/// <summary>
|
||||
/// A standalone USB peripheral. The original Leap Motion controller device.
|
||||
/// @since 1.2
|
||||
/// </summary>
|
||||
TYPE_PERIPHERAL = (int)eLeapDeviceType.eLeapDeviceType_Peripheral,
|
||||
|
||||
/// <summary>
|
||||
/// Internal research product codename "Dragonfly".
|
||||
/// </summary>
|
||||
TYPE_DRAGONFLY = (int)eLeapDeviceType.eLeapDeviceType_Dragonfly,
|
||||
|
||||
/// <summary>
|
||||
/// Internal research product codename "Nightcrawler".
|
||||
/// </summary>
|
||||
TYPE_NIGHTCRAWLER = (int)eLeapDeviceType.eLeapDeviceType_Nightcrawler,
|
||||
|
||||
/// <summary>
|
||||
/// Research product codename "Rigel".
|
||||
/// </summary>
|
||||
TYPE_RIGEL = (int)eLeapDeviceType.eLeapDevicePID_Rigel,
|
||||
|
||||
/// <summary>
|
||||
/// The Ultraleap Stereo IR 170 (SIR170) hand tracking module.
|
||||
/// </summary>
|
||||
TYPE_SIR170 = (int)eLeapDeviceType.eLeapDevicePID_SIR170,
|
||||
|
||||
/// <summary>
|
||||
/// The Ultraleap 3Di hand tracking camera.
|
||||
/// </summary>
|
||||
TYPE_3DI = (int)eLeapDeviceType.eLeapDevicePID_3Di,
|
||||
|
||||
[Obsolete]
|
||||
TYPE_LAPTOP,
|
||||
[Obsolete]
|
||||
TYPE_KEYBOARD
|
||||
}
|
||||
}
|
||||
}
|
94
ml_lme_cvr/vendor/LeapCSharp/DeviceList.cs
vendored
Normal file
94
ml_lme_cvr/vendor/LeapCSharp/DeviceList.cs
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// The DeviceList class represents a list of Device objects.
|
||||
///
|
||||
/// Get a DeviceList object by calling Controller.Devices().
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public class DeviceList :
|
||||
List<Device>
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an empty list of devices.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public DeviceList() { }
|
||||
|
||||
/// <summary>
|
||||
/// For internal use only.
|
||||
/// </summary>
|
||||
public Device FindDeviceByHandle(IntPtr deviceHandle)
|
||||
{
|
||||
for (int d = 0; d < this.Count; d++)
|
||||
{
|
||||
if (this[d].Handle == deviceHandle)
|
||||
return this[d];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The device that is currently streaming tracking data.
|
||||
/// If no streaming devices are found, returns null
|
||||
/// </summary>
|
||||
public Device ActiveDevice
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Count == 1)
|
||||
{
|
||||
return this[0];
|
||||
}
|
||||
|
||||
for (int d = 0; d < Count; d++)
|
||||
{
|
||||
this[d].UpdateStatus(LeapInternal.eLeapDeviceStatus.eLeapDeviceStatus_Streaming);
|
||||
if (this[d].IsStreaming)
|
||||
{
|
||||
return this[d];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For internal use only.
|
||||
/// </summary>
|
||||
public void AddOrUpdate(Device device)
|
||||
{
|
||||
Device existingDevice = FindDeviceByHandle(device.Handle);
|
||||
if (existingDevice != null)
|
||||
{
|
||||
existingDevice.Update(device);
|
||||
}
|
||||
else
|
||||
{
|
||||
Add(device);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reports whether the list is empty.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public bool IsEmpty
|
||||
{
|
||||
get { return Count == 0; }
|
||||
}
|
||||
}
|
||||
}
|
93
ml_lme_cvr/vendor/LeapCSharp/DistortionData.cs
vendored
Normal file
93
ml_lme_cvr/vendor/LeapCSharp/DistortionData.cs
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
/// <summary>
|
||||
/// The DistortionData class contains the distortion map for correcting the
|
||||
/// lens distortion of an image.
|
||||
///
|
||||
/// The distortion data is an array containing a 64x64 grid of floating point pairs.
|
||||
/// The distortion map for both sides of an image pair are stacked in
|
||||
/// the Data array -- the left map first, followed by the right map.
|
||||
///
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public class DistortionData
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs an uninitialized distortion object.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public DistortionData() { }
|
||||
|
||||
/// <summary>
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public DistortionData(UInt64 version, float width, float height, float[] data)
|
||||
{
|
||||
Version = version;
|
||||
Width = width;
|
||||
Height = height;
|
||||
Data = data;
|
||||
}
|
||||
/// <summary>
|
||||
/// An identifier assigned to the distortion map.
|
||||
///
|
||||
/// When the distortion map changes -- either because the devices flips the images
|
||||
/// to automatically orient the hands or because a different device is plugged in,
|
||||
/// the version number of the distortion data changes.
|
||||
///
|
||||
/// Note that the version always increases. If the images change orientation and then
|
||||
/// return to their original orientation, a new version number is assigned. Thus
|
||||
/// the version number can be used to detect when the data has changed, but not
|
||||
/// to uniquely identify the data.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public UInt64 Version { get; set; }
|
||||
/// <summary>
|
||||
/// The width of the distortion map.
|
||||
///
|
||||
/// Currently always 64. Note that there are two floating point values for every point in the map.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public float Width { get; set; }
|
||||
/// <summary>
|
||||
/// The height of the distortion map.
|
||||
///
|
||||
/// Currently always 64.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public float Height { get; set; }
|
||||
/// <summary>
|
||||
/// The distortion data.
|
||||
///
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public float[] Data { get; set; }
|
||||
/// <summary>
|
||||
/// Reports whether the distortion data is internally consistent.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public bool IsValid
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Data != null &&
|
||||
Width == LeapInternal.LeapC.DistortionSize &&
|
||||
Height == LeapInternal.LeapC.DistortionSize &&
|
||||
Data.Length == Width * Height * 2)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
323
ml_lme_cvr/vendor/LeapCSharp/Events.cs
vendored
Normal file
323
ml_lme_cvr/vendor/LeapCSharp/Events.cs
vendored
Normal file
|
@ -0,0 +1,323 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using LeapInternal;
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// An enumeration defining the types of Leap Motion events.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public enum LeapEvent
|
||||
{
|
||||
EVENT_CONNECTION, //!< A connection event has occurred
|
||||
EVENT_CONNECTION_LOST, //!< The connection with the service has been lost
|
||||
EVENT_DEVICE, //!< A device event has occurred
|
||||
EVENT_DEVICE_FAILURE, //!< A device failure event has occurred
|
||||
EVENT_DEVICE_LOST, //!< Event asserted when the underlying device object has been lost
|
||||
EVENT_POLICY_CHANGE, //!< A change in policy occurred
|
||||
EVENT_CONFIG_RESPONSE, //!< Response to a Config value request
|
||||
EVENT_CONFIG_CHANGE, //!< Success response to a Config value change
|
||||
EVENT_FRAME, //!< A tracking frame has been received
|
||||
EVENT_INTERNAL_FRAME, //!< An internal tracking frame has been received
|
||||
EVENT_IMAGE_COMPLETE, //!< A requested image is available
|
||||
EVENT_IMAGE_REQUEST_FAILED, //!< A requested image could not be provided
|
||||
EVENT_DISTORTION_CHANGE, //!< The distortion matrix used for image correction has changed
|
||||
EVENT_LOG_EVENT, //!< A diagnostic event has occurred
|
||||
EVENT_INIT,
|
||||
EVENT_DROPPED_FRAME,
|
||||
EVENT_IMAGE, //!< An unrequested image is available
|
||||
EVENT_POINT_MAPPING_CHANGE,
|
||||
EVENT_HEAD_POSE
|
||||
};
|
||||
/// <summary>
|
||||
/// A generic object with no arguments beyond the event type.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public class LeapEventArgs : EventArgs
|
||||
{
|
||||
public LeapEventArgs(LeapEvent type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
public LeapEvent type { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when a tracking frame is ready.
|
||||
///
|
||||
/// Provides the Frame object as an argument.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public class FrameEventArgs : LeapEventArgs
|
||||
{
|
||||
public FrameEventArgs(Frame frame) : base(LeapEvent.EVENT_FRAME)
|
||||
{
|
||||
this.frame = frame;
|
||||
}
|
||||
|
||||
public Frame frame { get; set; }
|
||||
}
|
||||
|
||||
public class InternalFrameEventArgs : LeapEventArgs
|
||||
{
|
||||
public InternalFrameEventArgs(ref LEAP_TRACKING_EVENT frame) : base(LeapEvent.EVENT_INTERNAL_FRAME)
|
||||
{
|
||||
this.frame = frame;
|
||||
}
|
||||
|
||||
public LEAP_TRACKING_EVENT frame { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when loggable events are generated by the service and the
|
||||
/// service connection code.
|
||||
///
|
||||
/// Provides the severity rating, log text, and timestamp as arguments.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public class LogEventArgs : LeapEventArgs
|
||||
{
|
||||
public LogEventArgs(MessageSeverity severity, Int64 timestamp, string message) : base(LeapEvent.EVENT_LOG_EVENT)
|
||||
{
|
||||
this.severity = severity;
|
||||
this.message = message;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public MessageSeverity severity { get; set; }
|
||||
public Int64 timestamp { get; set; }
|
||||
public string message { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when a policy change is complete.
|
||||
///
|
||||
/// Provides the current and previous policies as arguments.
|
||||
///
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public class PolicyEventArgs : LeapEventArgs
|
||||
{
|
||||
public PolicyEventArgs(UInt64 currentPolicies, UInt64 oldPolicies) : base(LeapEvent.EVENT_POLICY_CHANGE)
|
||||
{
|
||||
this.currentPolicies = currentPolicies;
|
||||
this.oldPolicies = oldPolicies;
|
||||
}
|
||||
|
||||
public UInt64 currentPolicies { get; set; }
|
||||
public UInt64 oldPolicies { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when the image distortion map changes.
|
||||
///
|
||||
/// Provides the new distortion map as an argument.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public class DistortionEventArgs : LeapEventArgs
|
||||
{
|
||||
public DistortionEventArgs(DistortionData distortion, Image.CameraType camera) : base(LeapEvent.EVENT_DISTORTION_CHANGE)
|
||||
{
|
||||
this.distortion = distortion;
|
||||
this.camera = camera;
|
||||
}
|
||||
public DistortionData distortion { get; protected set; }
|
||||
public Image.CameraType camera { get; protected set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when a configuration change is completed.
|
||||
///
|
||||
/// Provides the configuration key, whether the change was successful, and the id of the original change request.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public class ConfigChangeEventArgs : LeapEventArgs
|
||||
{
|
||||
public ConfigChangeEventArgs(string config_key, bool succeeded, uint requestId) : base(LeapEvent.EVENT_CONFIG_CHANGE)
|
||||
{
|
||||
this.ConfigKey = config_key;
|
||||
this.Succeeded = succeeded;
|
||||
this.RequestId = requestId;
|
||||
}
|
||||
public string ConfigKey { get; set; }
|
||||
public bool Succeeded { get; set; }
|
||||
public uint RequestId { get; set; }
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when a configuration change is completed.
|
||||
///
|
||||
/// Provides the configuration key, whether the change was successful, and the id of the original change request.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public class SetConfigResponseEventArgs : LeapEventArgs
|
||||
{
|
||||
public SetConfigResponseEventArgs(string config_key, Config.ValueType dataType, object value, uint requestId) : base(LeapEvent.EVENT_CONFIG_RESPONSE)
|
||||
{
|
||||
this.ConfigKey = config_key;
|
||||
this.DataType = dataType;
|
||||
this.Value = value;
|
||||
this.RequestId = requestId;
|
||||
}
|
||||
public string ConfigKey { get; set; }
|
||||
public Config.ValueType DataType { get; set; }
|
||||
public object Value { get; set; }
|
||||
public uint RequestId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when the connection is established.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public class ConnectionEventArgs : LeapEventArgs
|
||||
{
|
||||
public ConnectionEventArgs() : base(LeapEvent.EVENT_CONNECTION) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when the connection is lost.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public class ConnectionLostEventArgs : LeapEventArgs
|
||||
{
|
||||
public ConnectionLostEventArgs() : base(LeapEvent.EVENT_CONNECTION_LOST) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when a device is plugged in.
|
||||
///
|
||||
/// Provides the device as an argument.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public class DeviceEventArgs : LeapEventArgs
|
||||
{
|
||||
public DeviceEventArgs(Device device) : base(LeapEvent.EVENT_DEVICE)
|
||||
{
|
||||
this.Device = device;
|
||||
}
|
||||
public Device Device { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when a device is plugged in, but fails to initialize or when
|
||||
/// a working device fails in use.
|
||||
///
|
||||
/// Provides the failure reason and, if available, the serial number.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public class DeviceFailureEventArgs : LeapEventArgs
|
||||
{
|
||||
public DeviceFailureEventArgs(uint code, string message, string serial) : base(LeapEvent.EVENT_DEVICE_FAILURE)
|
||||
{
|
||||
ErrorCode = code;
|
||||
ErrorMessage = message;
|
||||
DeviceSerialNumber = serial;
|
||||
}
|
||||
|
||||
public uint ErrorCode { get; set; }
|
||||
public string ErrorMessage { get; set; }
|
||||
public string DeviceSerialNumber { get; set; }
|
||||
}
|
||||
|
||||
public class DroppedFrameEventArgs : LeapEventArgs
|
||||
{
|
||||
public DroppedFrameEventArgs(Int64 frame_id, eLeapDroppedFrameType type) : base(LeapEvent.EVENT_DROPPED_FRAME)
|
||||
{
|
||||
frameID = frame_id;
|
||||
reason = type;
|
||||
}
|
||||
|
||||
public Int64 frameID { get; set; }
|
||||
public eLeapDroppedFrameType reason { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when an unrequested Image is ready.
|
||||
///
|
||||
/// Provides the Image object as an argument.
|
||||
/// @since 4.0
|
||||
/// </summary>
|
||||
public class ImageEventArgs : LeapEventArgs
|
||||
{
|
||||
public ImageEventArgs(Image image) : base(LeapEvent.EVENT_IMAGE)
|
||||
{
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public Image image { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatched when point mapping change events are generated by the service.
|
||||
///
|
||||
/// @since 4.0
|
||||
/// </summary>
|
||||
public class PointMappingChangeEventArgs : LeapEventArgs
|
||||
{
|
||||
public PointMappingChangeEventArgs(Int64 frame_id, Int64 timestamp, UInt32 nPoints) : base(LeapEvent.EVENT_POINT_MAPPING_CHANGE)
|
||||
{
|
||||
this.frameID = frame_id;
|
||||
this.timestamp = timestamp;
|
||||
this.nPoints = nPoints;
|
||||
}
|
||||
|
||||
public Int64 frameID { get; set; }
|
||||
public Int64 timestamp { get; set; }
|
||||
public UInt32 nPoints { get; set; }
|
||||
}
|
||||
|
||||
public class HeadPoseEventArgs : LeapEventArgs
|
||||
{
|
||||
public HeadPoseEventArgs(LEAP_VECTOR head_position, LEAP_QUATERNION head_orientation) : base(LeapEvent.EVENT_POINT_MAPPING_CHANGE)
|
||||
{
|
||||
this.headPosition = head_position;
|
||||
this.headOrientation = head_orientation;
|
||||
}
|
||||
|
||||
public LEAP_VECTOR headPosition { get; set; }
|
||||
public LEAP_QUATERNION headOrientation { get; set; }
|
||||
}
|
||||
|
||||
public struct BeginProfilingForThreadArgs
|
||||
{
|
||||
public string threadName;
|
||||
public string[] blockNames;
|
||||
|
||||
public BeginProfilingForThreadArgs(string threadName, params string[] blockNames)
|
||||
{
|
||||
this.threadName = threadName;
|
||||
this.blockNames = blockNames;
|
||||
}
|
||||
}
|
||||
|
||||
public struct EndProfilingForThreadArgs { }
|
||||
|
||||
public struct BeginProfilingBlockArgs
|
||||
{
|
||||
public string blockName;
|
||||
|
||||
public BeginProfilingBlockArgs(string blockName)
|
||||
{
|
||||
this.blockName = blockName;
|
||||
}
|
||||
}
|
||||
|
||||
public struct EndProfilingBlockArgs
|
||||
{
|
||||
public string blockName;
|
||||
|
||||
public EndProfilingBlockArgs(string blockName)
|
||||
{
|
||||
this.blockName = blockName;
|
||||
}
|
||||
}
|
||||
}
|
88
ml_lme_cvr/vendor/LeapCSharp/FailedDevice.cs
vendored
Normal file
88
ml_lme_cvr/vendor/LeapCSharp/FailedDevice.cs
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// The FailedDevice class provides information about Leap Motion hardware that
|
||||
/// has been physically connected to the client computer, but is not operating
|
||||
/// correctly.
|
||||
///
|
||||
/// Failed devices do not provide any tracking data and do not show up in the
|
||||
/// Controller.Devices() list.
|
||||
///
|
||||
/// Get the list of failed devices using Controller.FailedDevices().
|
||||
///
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public class FailedDevice :
|
||||
IEquatable<FailedDevice>
|
||||
{
|
||||
|
||||
public FailedDevice()
|
||||
{
|
||||
Failure = FailureType.FAIL_UNKNOWN;
|
||||
PnpId = "0";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test FailedDevice equality.
|
||||
/// True if the devices are the same.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public bool Equals(FailedDevice other)
|
||||
{
|
||||
return PnpId == other.PnpId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The device plug-and-play id string.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public string PnpId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The reason for device failure.
|
||||
/// The failure reasons are defined as members of the FailureType enumeration.
|
||||
///
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public FailureType Failure { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The errors that can cause a device to fail to properly connect to the service.
|
||||
///
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public enum FailureType
|
||||
{
|
||||
/// <summary>
|
||||
/// The cause of the error is unknown.
|
||||
/// </summary>
|
||||
FAIL_UNKNOWN,
|
||||
/// <summary>
|
||||
/// The device has a bad calibration record.
|
||||
/// </summary>
|
||||
FAIL_CALIBRATION,
|
||||
/// <summary>
|
||||
/// The device firmware is corrupt or failed to update.
|
||||
/// </summary>
|
||||
FAIL_FIRMWARE,
|
||||
/// <summary>
|
||||
/// The device is unresponsive.
|
||||
/// </summary>
|
||||
FAIL_TRANSPORT,
|
||||
/// <summary>
|
||||
/// The service cannot establish the required USB control interfaces.
|
||||
/// </summary>
|
||||
FAIL_CONTROl
|
||||
}
|
||||
}
|
||||
}
|
47
ml_lme_cvr/vendor/LeapCSharp/FailedDeviceList.cs
vendored
Normal file
47
ml_lme_cvr/vendor/LeapCSharp/FailedDeviceList.cs
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// The list of FailedDevice objects contains an entry for every failed Leap Motion
|
||||
/// hardware device connected to the client computer. FailedDevice objects report
|
||||
/// the device pnpID string and reason for failure.
|
||||
///
|
||||
/// Get the list of FailedDevice objects from Controller.FailedDevices().
|
||||
///
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public class FailedDeviceList : List<FailedDevice>
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an empty list.
|
||||
/// </summary>
|
||||
public FailedDeviceList() { }
|
||||
|
||||
/// <summary>
|
||||
/// Appends the contents of another FailedDeviceList to this one.
|
||||
/// </summary>
|
||||
public FailedDeviceList Append(FailedDeviceList other)
|
||||
{
|
||||
AddRange(other);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reports whether the list is empty.
|
||||
/// </summary>
|
||||
public bool IsEmpty
|
||||
{
|
||||
get { return Count == 0; }
|
||||
}
|
||||
}
|
||||
}
|
183
ml_lme_cvr/vendor/LeapCSharp/Finger.cs
vendored
Normal file
183
ml_lme_cvr/vendor/LeapCSharp/Finger.cs
vendored
Normal file
|
@ -0,0 +1,183 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// The Finger class represents a tracked finger.
|
||||
///
|
||||
/// Fingers are objects that the Leap Motion software has classified as a finger.
|
||||
/// Get valid Finger objects from a Frame or a Hand object.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class Finger
|
||||
{
|
||||
public Bone[] bones = new Bone[4];
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a finger.
|
||||
///
|
||||
/// An uninitialized finger is considered invalid.
|
||||
/// Get valid Finger objects from a Hand object.
|
||||
///
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public Finger()
|
||||
{
|
||||
bones[0] = new Bone();
|
||||
bones[1] = new Bone();
|
||||
bones[2] = new Bone();
|
||||
bones[3] = new Bone();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a finger.
|
||||
///
|
||||
/// Generally, you should not create your own finger objects. Such objects will not
|
||||
/// have valid tracking data. Get valid finger objects from a hand in a frame
|
||||
/// received from the service.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public Finger(long frameId,
|
||||
int handId,
|
||||
int fingerId,
|
||||
float timeVisible,
|
||||
Vector tipPosition,
|
||||
Vector direction,
|
||||
float width,
|
||||
float length,
|
||||
bool isExtended,
|
||||
FingerType type,
|
||||
Bone metacarpal,
|
||||
Bone proximal,
|
||||
Bone intermediate,
|
||||
Bone distal)
|
||||
{
|
||||
Type = type;
|
||||
bones[0] = metacarpal;
|
||||
bones[1] = proximal;
|
||||
bones[2] = intermediate;
|
||||
bones[3] = distal;
|
||||
Id = (handId * 10) + fingerId;
|
||||
HandId = handId;
|
||||
TipPosition = tipPosition;
|
||||
Direction = direction;
|
||||
Width = width;
|
||||
Length = length;
|
||||
IsExtended = isExtended;
|
||||
TimeVisible = timeVisible;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The bone at a given bone index on this finger.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public Bone Bone(Bone.BoneType boneIx)
|
||||
{
|
||||
return bones[(int)boneIx];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A string containing a brief, human readable description of the Finger object.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return Enum.GetName(typeof(FingerType), Type) + " id:" + Id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The type of this finger.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public Finger.FingerType Type;
|
||||
|
||||
/// <summary>
|
||||
/// A unique ID assigned to this Finger object, whose value remains the
|
||||
/// same across consecutive frames while the tracked hand remains visible.
|
||||
/// If tracking of the hand is lost, the Leap Motion software may assign a
|
||||
/// new ID when it detects the hand in a future frame.
|
||||
///
|
||||
/// Use the ID value to find this Finger object in future frames.
|
||||
///
|
||||
/// IDs should be from 1 to 100 (inclusive). If more than 100 objects are tracked
|
||||
/// an IDs of -1 will be used until an ID in the defined range is available.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public int Id;
|
||||
|
||||
/// <summary>
|
||||
/// The Hand associated with a finger.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public int HandId;
|
||||
|
||||
/// <summary>
|
||||
/// The tip position of this Finger.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector TipPosition;
|
||||
|
||||
/// <summary>
|
||||
/// The direction in which this finger or tool is pointing. The direction is expressed
|
||||
/// as a unit vector pointing in the same direction as the tip.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector Direction;
|
||||
|
||||
/// <summary>
|
||||
/// The estimated width of the finger.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float Width;
|
||||
|
||||
/// <summary>
|
||||
/// The estimated length of the finger.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float Length;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not this Finger is in an extended posture.
|
||||
///
|
||||
/// A finger is considered extended if it is extended straight from the hand as if
|
||||
/// pointing. A finger is not extended when it is bent down and curled towards the
|
||||
/// palm.
|
||||
///
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public bool IsExtended;
|
||||
|
||||
/// <summary>
|
||||
/// The duration of time this Finger has been visible to the Leap Motion Controller.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float TimeVisible;
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates the names of the fingers.
|
||||
///
|
||||
/// Members of this enumeration are returned by Finger.Type() to identify a
|
||||
/// Finger object.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public enum FingerType
|
||||
{
|
||||
TYPE_THUMB = 0,
|
||||
TYPE_INDEX = 1,
|
||||
TYPE_MIDDLE = 2,
|
||||
TYPE_RING = 3,
|
||||
TYPE_PINKY = 4,
|
||||
TYPE_UNKNOWN = -1
|
||||
}
|
||||
}
|
||||
}
|
221
ml_lme_cvr/vendor/LeapCSharp/Frame.cs
vendored
Normal file
221
ml_lme_cvr/vendor/LeapCSharp/Frame.cs
vendored
Normal file
|
@ -0,0 +1,221 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// The Frame class represents a set of hand and finger tracking data detected
|
||||
/// in a single frame.
|
||||
///
|
||||
/// The Leap Motion software detects hands, fingers and tools within the tracking area, reporting
|
||||
/// their positions, orientations, gestures, and motions in frames at the Leap Motion frame rate.
|
||||
///
|
||||
/// Access Frame objects through an instance of the Controller class.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class Frame : IEquatable<Frame>
|
||||
{
|
||||
[ThreadStatic]
|
||||
private static Queue<Hand> _handPool;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a Frame object.
|
||||
///
|
||||
/// Frame instances created with this constructor are invalid.
|
||||
/// Get valid Frame objects by calling the Controller.Frame() function.
|
||||
///
|
||||
/// The only time you should use this constructor is before deserializing
|
||||
/// serialized frame data, or if you are going to be passing this Frame
|
||||
/// to a method that fills it with valid data.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Frame(UInt32 DeviceID = 1)
|
||||
{
|
||||
Hands = new List<Hand>();
|
||||
this.DeviceID = DeviceID;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new Frame.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public Frame(long id, long timestamp, float fps, List<Hand> hands)
|
||||
{
|
||||
Id = id;
|
||||
Timestamp = timestamp;
|
||||
CurrentFramesPerSecond = fps;
|
||||
Hands = hands;
|
||||
DeviceID = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Device ID that this frame was seen from.
|
||||
///
|
||||
/// 1-Indexed; Non-Deterministic order
|
||||
///
|
||||
/// Only valid when `supportsMultipleDevices` is true on the LeapProvider.
|
||||
///
|
||||
/// @since 4.1
|
||||
/// </summary>
|
||||
public UInt32 DeviceID;
|
||||
|
||||
[Obsolete]
|
||||
public int SerializeLength
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public byte[] Serialize
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public void Deserialize(byte[] arg)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Hand object with the specified ID in this frame, or null if none
|
||||
/// exists.
|
||||
///
|
||||
/// Use the Frame.Hand() function to retrieve the Hand object from
|
||||
/// this frame using an ID value obtained from a previous frame.
|
||||
/// This function always returns a Hand object, but if no hand
|
||||
/// with the specified ID is present, an invalid Hand object is returned.
|
||||
///
|
||||
/// Note that ID values persist across frames, but only until tracking of a
|
||||
/// particular object is lost. If tracking of a hand is lost and subsequently
|
||||
/// regained, the new Hand object representing that physical hand may have
|
||||
/// a different ID than that representing the physical hand in an earlier frame.
|
||||
/// @since 1.0 </summary>
|
||||
public Hand Hand(int id)
|
||||
{
|
||||
for (int i = Hands.Count; i-- != 0;)
|
||||
{
|
||||
if (Hands[i].Id == id)
|
||||
{
|
||||
return Hands[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare Frame object equality.
|
||||
///
|
||||
/// Two Frame objects are equal if and only if both Frame objects represent
|
||||
/// the exact same frame of tracking data and both Frame objects are valid.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public bool Equals(Frame other)
|
||||
{
|
||||
return Id == other.Id && Timestamp == other.Timestamp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A string containing a brief, human readable description of the Frame object.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return "Frame id: " + this.Id + " timestamp: " + this.Timestamp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A unique ID for this Frame.
|
||||
///
|
||||
/// Consecutive frames processed by the Leap Motion software have consecutive
|
||||
/// increasing values. You can use the frame ID to avoid processing the same
|
||||
/// Frame object twice, as well as to make sure that your application processes
|
||||
/// every frame.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public long Id;
|
||||
|
||||
/// <summary>
|
||||
/// The frame capture time in microseconds elapsed since an arbitrary point in
|
||||
/// time in the past.
|
||||
///
|
||||
/// You can use Controller.Now() to calculate the age of the frame.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public long Timestamp;
|
||||
|
||||
/// <summary>
|
||||
/// The instantaneous framerate.
|
||||
///
|
||||
/// The rate at which the Leap Motion software is providing frames of data
|
||||
/// (in frames per second). The framerate can fluctuate depending on available computing
|
||||
/// resources, activity within the device field of view, software tracking settings,
|
||||
/// and other factors.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float CurrentFramesPerSecond;
|
||||
|
||||
/// <summary>
|
||||
/// The list of Hand objects detected in this frame, given in arbitrary order.
|
||||
/// The list can be empty if no hands are detected.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public List<Hand> Hands;
|
||||
|
||||
/// <summary>
|
||||
/// Resizes the Hand list to have a specific size. If the size is decreased,
|
||||
/// the removed hands are placed into the hand pool. If the size is increased, the
|
||||
/// new spaces are filled with hands taken from the hand pool. If the pool is
|
||||
/// empty, new hands are constructed instead.
|
||||
/// </summary>
|
||||
public void ResizeHandList(int count)
|
||||
{
|
||||
if (_handPool == null)
|
||||
{
|
||||
_handPool = new Queue<Hand>();
|
||||
}
|
||||
|
||||
while (Hands.Count < count)
|
||||
{
|
||||
Hand newHand;
|
||||
if (_handPool.Count > 0)
|
||||
{
|
||||
newHand = _handPool.Dequeue();
|
||||
}
|
||||
else
|
||||
{
|
||||
newHand = new Hand();
|
||||
}
|
||||
Hands.Add(newHand);
|
||||
}
|
||||
|
||||
while (Hands.Count > count)
|
||||
{
|
||||
Hand lastHand = Hands[Hands.Count - 1];
|
||||
Hands.RemoveAt(Hands.Count - 1);
|
||||
_handPool.Enqueue(lastHand);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
322
ml_lme_cvr/vendor/LeapCSharp/Hand.cs
vendored
Normal file
322
ml_lme_cvr/vendor/LeapCSharp/Hand.cs
vendored
Normal file
|
@ -0,0 +1,322 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// The Hand class reports the physical characteristics of a detected hand.
|
||||
///
|
||||
/// Hand tracking data includes a palm position and velocity; vectors for
|
||||
/// the palm normal and direction to the fingers; and lists of the attached fingers.
|
||||
///
|
||||
/// Note that Hand objects can be invalid, which means that they do not contain
|
||||
/// valid tracking data and do not correspond to a physical entity. Invalid Hand
|
||||
/// objects can be the result of using the default constructor, or modifying the
|
||||
/// hand data in an incorrect way.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class Hand : IEquatable<Hand>
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a Hand object.
|
||||
///
|
||||
/// An uninitialized hand is considered invalid.
|
||||
/// Get valid Hand objects from a Frame object.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Hand()
|
||||
{
|
||||
Arm = new Arm();
|
||||
Fingers = new List<Finger>(5);
|
||||
Fingers.Add(new Finger());
|
||||
Fingers.Add(new Finger());
|
||||
Fingers.Add(new Finger());
|
||||
Fingers.Add(new Finger());
|
||||
Fingers.Add(new Finger());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a hand.
|
||||
///
|
||||
/// Generally, you should not create your own Hand objects. Such objects will not
|
||||
/// have valid tracking data. Get valid Hand objects from a frame
|
||||
/// received from the service.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public Hand(long frameID,
|
||||
int id,
|
||||
float confidence,
|
||||
float grabStrength,
|
||||
float grabAngle,
|
||||
float pinchStrength,
|
||||
float pinchDistance,
|
||||
float palmWidth,
|
||||
bool isLeft,
|
||||
float timeVisible,
|
||||
Arm arm,
|
||||
List<Finger> fingers,
|
||||
Vector palmPosition,
|
||||
Vector stabilizedPalmPosition,
|
||||
Vector palmVelocity,
|
||||
Vector palmNormal,
|
||||
LeapQuaternion palmOrientation,
|
||||
Vector direction,
|
||||
Vector wristPosition)
|
||||
{
|
||||
FrameId = frameID;
|
||||
Id = id;
|
||||
Confidence = confidence;
|
||||
GrabStrength = grabStrength;
|
||||
GrabAngle = grabAngle;
|
||||
PinchStrength = pinchStrength;
|
||||
PinchDistance = pinchDistance;
|
||||
PalmWidth = palmWidth;
|
||||
IsLeft = isLeft;
|
||||
TimeVisible = timeVisible;
|
||||
Arm = arm;
|
||||
Fingers = fingers;
|
||||
PalmPosition = palmPosition;
|
||||
StabilizedPalmPosition = stabilizedPalmPosition;
|
||||
PalmVelocity = palmVelocity;
|
||||
PalmNormal = palmNormal;
|
||||
Rotation = palmOrientation;
|
||||
Direction = direction;
|
||||
WristPosition = wristPosition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Finger object with the specified ID attached to this hand.
|
||||
///
|
||||
/// Use the Hand.Finger() function to retrieve a Finger object attached to
|
||||
/// this hand using an ID value obtained from a previous frame.
|
||||
///
|
||||
/// Note that ID values persist across frames, but only until tracking of a
|
||||
/// particular object is lost. If tracking of a hand is lost and subsequently
|
||||
/// regained, the new Finger object representing that finger may have a
|
||||
/// different ID than that representing the finger in an earlier frame.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Finger Finger(int id)
|
||||
{
|
||||
for (int i = Fingers.Count; i-- != 0;)
|
||||
{
|
||||
if (Fingers[i].Id == id)
|
||||
{
|
||||
return Fingers[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare Hand object equality.
|
||||
///
|
||||
/// Two Hand objects are equal if and only if both Hand objects represent the
|
||||
/// exact same physical hand in the same frame and both Hand objects are valid.
|
||||
/// </summary>
|
||||
public bool Equals(Hand other)
|
||||
{
|
||||
return Id == other.Id && FrameId == other.FrameId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A string containing a brief, human readable description of the Hand object.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(
|
||||
"Hand {0} {1}.",
|
||||
this.Id,
|
||||
this.IsLeft ? "left" : "right"
|
||||
);
|
||||
}
|
||||
|
||||
public long FrameId;
|
||||
|
||||
/// <summary>
|
||||
/// A unique ID assigned to this Hand object, whose value remains the same
|
||||
/// across consecutive frames while the tracked hand remains visible. If
|
||||
/// tracking is lost (for example, when a hand is occluded by another hand
|
||||
/// or when it is withdrawn from or reaches the edge of the Leap Motion Controller field of view),
|
||||
/// the Leap Motion software may assign a new ID when it detects the hand in a future frame.
|
||||
///
|
||||
/// Use the ID value with the Frame.Hand() function to find this Hand object
|
||||
/// in future frames.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public int Id;
|
||||
|
||||
/// <summary>
|
||||
/// The list of Finger objects detected in this frame that are attached to
|
||||
/// this hand, given in order from thumb to pinky. The list cannot be empty.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public List<Finger> Fingers;
|
||||
|
||||
/// <summary>
|
||||
/// The center position of the palm.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector PalmPosition;
|
||||
|
||||
/// <summary>
|
||||
/// The rate of change of the palm position.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector PalmVelocity;
|
||||
|
||||
/// <summary>
|
||||
/// The normal vector to the palm. If your hand is flat, this vector will
|
||||
/// point downward, or "out" of the front surface of your palm.
|
||||
///
|
||||
/// The direction is expressed as a unit vector pointing in the same
|
||||
/// direction as the palm normal (that is, a vector orthogonal to the palm).
|
||||
///
|
||||
/// You can use the palm normal vector to compute the roll angle of the palm with
|
||||
/// respect to the horizontal plane.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector PalmNormal;
|
||||
|
||||
/// <summary>
|
||||
/// The direction from the palm position toward the fingers.
|
||||
///
|
||||
/// The direction is expressed as a unit vector pointing in the same
|
||||
/// direction as the directed line from the palm position to the fingers.
|
||||
///
|
||||
/// You can use the palm direction vector to compute the pitch and yaw angles of the palm with
|
||||
/// respect to the horizontal plane.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector Direction;
|
||||
|
||||
/// <summary>
|
||||
/// The transform of the hand.
|
||||
///
|
||||
/// Note, in version prior to 3.1, the Basis was a Matrix object.
|
||||
/// @since 3.1
|
||||
/// </summary>
|
||||
public LeapTransform Basis { get { return new LeapTransform(PalmPosition, Rotation); } }
|
||||
|
||||
/// <summary>
|
||||
/// The rotation of the hand as a quaternion.
|
||||
///
|
||||
/// @since 3.1
|
||||
/// </summary>
|
||||
public LeapQuaternion Rotation;
|
||||
|
||||
/// <summary>
|
||||
/// The strength of a grab hand pose.
|
||||
///
|
||||
/// The strength is zero for an open hand, and blends to one when a grabbing hand
|
||||
/// pose is recognized.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public float GrabStrength;
|
||||
|
||||
/// <summary>
|
||||
/// The angle between the fingers and the hand of a grab hand pose.
|
||||
///
|
||||
/// The angle is computed by looking at the angle between the direction of the
|
||||
/// 4 fingers and the direction of the hand. Thumb is not considered when
|
||||
/// computing the angle.
|
||||
/// The angle is 0 radian for an open hand, and reaches pi radians when the pose
|
||||
/// is a tight fist.
|
||||
///
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public float GrabAngle;
|
||||
|
||||
/// <summary>
|
||||
/// The holding strength of a pinch hand pose.
|
||||
///
|
||||
/// The strength is zero for an open hand, and blends to one when a pinching
|
||||
/// hand pose is recognized. Pinching can be done between the thumb
|
||||
/// and any other finger of the same hand.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public float PinchStrength;
|
||||
|
||||
/// <summary>
|
||||
/// The distance between the thumb and index finger of a pinch hand pose.
|
||||
///
|
||||
/// The distance is computed by looking at the shortest distance between
|
||||
/// the last 2 phalanges of the thumb and those of the index finger.
|
||||
/// This pinch measurement only takes thumb and index finger into account.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public float PinchDistance;
|
||||
|
||||
/// <summary>
|
||||
/// The estimated width of the palm when the hand is in a flat position.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public float PalmWidth;
|
||||
|
||||
/// <summary>
|
||||
/// The stabilized palm position of this Hand.
|
||||
///
|
||||
/// Smoothing and stabilization is performed in order to make
|
||||
/// this value more suitable for interaction with 2D content. The stabilized
|
||||
/// position lags behind the palm position by a variable amount, depending
|
||||
/// primarily on the speed of movement.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector StabilizedPalmPosition;
|
||||
|
||||
/// <summary>
|
||||
/// The position of the wrist of this hand.
|
||||
/// @since 2.0.3
|
||||
/// </summary>
|
||||
public Vector WristPosition;
|
||||
|
||||
/// <summary>
|
||||
/// The duration of time this Hand has been visible to the Leap Motion Controller.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float TimeVisible;
|
||||
|
||||
/// <summary>
|
||||
/// How confident we are with a given hand pose.
|
||||
/// The confidence level ranges between 0.0 and 1.0 inclusive.
|
||||
///
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public float Confidence;
|
||||
|
||||
/// <summary>
|
||||
/// Identifies whether this Hand is a left hand.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public bool IsLeft;
|
||||
|
||||
/// <summary>
|
||||
/// Identifies whether this Hand is a right hand.
|
||||
/// @since 2.0
|
||||
/// </summary>
|
||||
public bool IsRight { get { return !IsLeft; } }
|
||||
|
||||
/// <summary>
|
||||
/// The arm to which this hand is attached.
|
||||
///
|
||||
/// If the arm is not completely in view, Arm attributes are estimated based on
|
||||
/// the attributes of entities that are in view combined with typical human anatomy.
|
||||
/// @since 2.0.3
|
||||
/// </summary>
|
||||
public Arm Arm;
|
||||
}
|
||||
}
|
46
ml_lme_cvr/vendor/LeapCSharp/IController.cs
vendored
Normal file
46
ml_lme_cvr/vendor/LeapCSharp/IController.cs
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
public interface IController :
|
||||
IDisposable
|
||||
{
|
||||
Frame Frame(int history = 0);
|
||||
Frame GetTransformedFrame(LeapTransform trs, int history = 0);
|
||||
Frame GetInterpolatedFrame(Int64 time);
|
||||
|
||||
void SetPolicy(Controller.PolicyFlag policy);
|
||||
void ClearPolicy(Controller.PolicyFlag policy);
|
||||
bool IsPolicySet(Controller.PolicyFlag policy);
|
||||
|
||||
long Now();
|
||||
|
||||
bool IsConnected { get; }
|
||||
Config Config { get; }
|
||||
DeviceList Devices { get; }
|
||||
|
||||
event EventHandler<ConnectionEventArgs> Connect;
|
||||
event EventHandler<ConnectionLostEventArgs> Disconnect;
|
||||
event EventHandler<FrameEventArgs> FrameReady;
|
||||
event EventHandler<DeviceEventArgs> Device;
|
||||
event EventHandler<DeviceEventArgs> DeviceLost;
|
||||
event EventHandler<DeviceFailureEventArgs> DeviceFailure;
|
||||
event EventHandler<LogEventArgs> LogMessage;
|
||||
|
||||
//new
|
||||
event EventHandler<PolicyEventArgs> PolicyChange;
|
||||
event EventHandler<ConfigChangeEventArgs> ConfigChange;
|
||||
event EventHandler<DistortionEventArgs> DistortionChange;
|
||||
event EventHandler<ImageEventArgs> ImageReady;
|
||||
event EventHandler<PointMappingChangeEventArgs> PointMappingChange;
|
||||
event EventHandler<HeadPoseEventArgs> HeadPoseChange;
|
||||
}
|
||||
}
|
456
ml_lme_cvr/vendor/LeapCSharp/Image.cs
vendored
Normal file
456
ml_lme_cvr/vendor/LeapCSharp/Image.cs
vendored
Normal file
|
@ -0,0 +1,456 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using LeapInternal;
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// The Image class represents a stereo image pair from the Leap Motion device.
|
||||
///
|
||||
/// In addition to image data, the Image object provides a distortion map for correcting
|
||||
/// lens distortion.
|
||||
/// @since 2.1.0
|
||||
/// </summary>
|
||||
public class Image
|
||||
{
|
||||
private ImageData leftImage;
|
||||
private ImageData rightImage;
|
||||
private Int64 frameId = 0;
|
||||
private Int64 timestamp = 0;
|
||||
private UInt32 deviceId = 0;
|
||||
|
||||
public Image(Int64 frameId, Int64 timestamp, ImageData leftImage, ImageData rightImage, UInt32 deviceId = 1)
|
||||
{
|
||||
if (leftImage == null || rightImage == null)
|
||||
{
|
||||
throw new ArgumentNullException("images");
|
||||
}
|
||||
if (leftImage.type != rightImage.type ||
|
||||
leftImage.format != rightImage.format ||
|
||||
leftImage.width != rightImage.width ||
|
||||
leftImage.height != rightImage.height ||
|
||||
leftImage.bpp != rightImage.bpp ||
|
||||
leftImage.DistortionSize != rightImage.DistortionSize)
|
||||
{
|
||||
throw new ArgumentException("image mismatch");
|
||||
}
|
||||
this.frameId = frameId;
|
||||
this.timestamp = timestamp;
|
||||
this.leftImage = leftImage;
|
||||
this.rightImage = rightImage;
|
||||
this.deviceId = deviceId;
|
||||
}
|
||||
|
||||
|
||||
private ImageData imageData(CameraType camera)
|
||||
{
|
||||
return camera == CameraType.LEFT ? leftImage : rightImage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The buffer containing the image data.
|
||||
///
|
||||
/// The image data is a set of 8-bit intensity values. The buffer is
|
||||
/// image.Width * image.Height * image.BytesPerPixel bytes long.
|
||||
///
|
||||
/// Use the ByteOffset method to find the beginning offset
|
||||
/// of the data for the specified camera.
|
||||
///
|
||||
/// @since 4.0
|
||||
/// </summary>
|
||||
public byte[] Data(CameraType camera)
|
||||
{
|
||||
if (camera != CameraType.LEFT && camera != CameraType.RIGHT)
|
||||
return null;
|
||||
|
||||
return imageData(camera).AsByteArray;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a convenience device ID based on which attached device sent this
|
||||
/// image.
|
||||
/// @since 4.5.0
|
||||
/// </summary>
|
||||
public UInt32 DeviceID
|
||||
{
|
||||
get
|
||||
{
|
||||
return deviceId;
|
||||
}
|
||||
}
|
||||
|
||||
public enum CalibrationType
|
||||
{
|
||||
INFRARED = 0,
|
||||
VISIBLE = 1
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The offset, in number of bytes, from the beginning of the Data()
|
||||
/// buffer to the first byte of the image data for the specified camera.
|
||||
///
|
||||
/// @since 4.0
|
||||
/// </summary>
|
||||
public UInt32 ByteOffset(CameraType camera)
|
||||
{
|
||||
if (camera != CameraType.LEFT && camera != CameraType.RIGHT)
|
||||
return 0;
|
||||
|
||||
return imageData(camera).byteOffset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of bytes in the Data() buffer corresponding to each
|
||||
/// image. Use the ByteOffset() function to find the starting byte
|
||||
/// offset for each image.
|
||||
///
|
||||
/// @since 4.0
|
||||
/// </summary>
|
||||
public UInt32 NumBytes
|
||||
{
|
||||
get
|
||||
{
|
||||
return leftImage.width * leftImage.height * leftImage.bpp;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The distortion calibration map for this image.
|
||||
///
|
||||
/// The calibration map is a 64x64 grid of points. Each point is defined by
|
||||
/// a pair of 32-bit floating point values. Each point in the map
|
||||
/// represents a ray projected into the camera. The value of
|
||||
/// a grid point defines the pixel in the image data containing the brightness
|
||||
/// value produced by the light entering along the corresponding ray. By
|
||||
/// interpolating between grid data points, you can find the brightness value
|
||||
/// for any projected ray. Grid values that fall outside the range [0..1] do
|
||||
/// not correspond to a value in the image data and those points should be ignored.
|
||||
///
|
||||
/// The calibration map can be used to render an undistorted image as well as to
|
||||
/// find the true angle from the camera to a feature in the raw image. The
|
||||
/// distortion map itself is designed to be used with GLSL shader programs.
|
||||
/// In other contexts, it may be more convenient to use the Image Rectify()
|
||||
/// and Warp() functions.
|
||||
///
|
||||
/// Distortion is caused by the lens geometry as well as imperfections in the
|
||||
/// lens and sensor window. The calibration map is created by the calibration
|
||||
/// process run for each device at the factory (and which can be rerun by the
|
||||
/// user).
|
||||
///
|
||||
/// @since 2.1.0
|
||||
/// </summary>
|
||||
public float[] Distortion(CameraType camera)
|
||||
{
|
||||
if (camera != CameraType.LEFT && camera != CameraType.RIGHT)
|
||||
return null;
|
||||
|
||||
return imageData(camera).DistortionData.Data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides the corrected camera ray intercepting the specified point on the image.
|
||||
///
|
||||
/// Given a point on the image, PixelToRectilinear() corrects for camera distortion
|
||||
/// and returns the true direction from the camera to the source of that image point
|
||||
/// within the Leap Motion field of view.
|
||||
///
|
||||
/// This direction vector has an x and y component [x, y, 1], with the third element
|
||||
/// always one. Note that this vector uses the 2D camera coordinate system
|
||||
/// where the x-axis parallels the longer (typically horizontal) dimension and
|
||||
/// the y-axis parallels the shorter (vertical) dimension. The camera coordinate
|
||||
/// system does not correlate to the 3D Leap Motion coordinate system.
|
||||
///
|
||||
/// **Note:** This function should be called immediately after an image is obtained. Incorrect
|
||||
/// results will be returned if the image orientation has changed or a different device is plugged
|
||||
/// in between the time the image was received and the time this function is called.
|
||||
///
|
||||
/// Note, this function was formerly named Rectify().
|
||||
/// @since 2.1.0
|
||||
/// </summary>
|
||||
public Vector PixelToRectilinear(CameraType camera, Vector pixel)
|
||||
{
|
||||
return Connection.GetConnection().PixelToRectilinear(camera, pixel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides the point in the image corresponding to a ray projecting
|
||||
/// from the camera.
|
||||
///
|
||||
/// Given a ray projected from the camera in the specified direction, RectilinearToPixel()
|
||||
/// corrects for camera distortion and returns the corresponding pixel
|
||||
/// coordinates in the image.
|
||||
///
|
||||
/// The ray direction is specified in relationship to the camera. The first
|
||||
/// vector element corresponds to the "horizontal" view angle; the second
|
||||
/// corresponds to the "vertical" view angle.
|
||||
///
|
||||
/// The RectilinearToPixel() function returns pixel coordinates outside of the image bounds
|
||||
/// if you project a ray toward a point for which there is no recorded data.
|
||||
///
|
||||
/// RectilinearToPixel() is typically not fast enough for realtime distortion correction.
|
||||
/// For better performance, use a shader program executed on a GPU.
|
||||
///
|
||||
/// **Note:** This function should be called immediately after an image is obtained. Incorrect
|
||||
/// results will be returned if the image orientation has changed or a different device is plugged
|
||||
/// in between the time the image was received and the time this function is called.
|
||||
///
|
||||
/// Note, this function was formerly named Warp().
|
||||
/// @since 2.1.0
|
||||
/// </summary>
|
||||
public Vector RectilinearToPixel(CameraType camera, Vector ray)
|
||||
{
|
||||
return Connection.GetConnection().RectilinearToPixel(camera, ray);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare Image object equality.
|
||||
///
|
||||
/// Two Image objects are equal if and only if both Image objects represent the
|
||||
/// exact same Image and both Images are valid.
|
||||
/// @since 2.1.0
|
||||
/// </summary>
|
||||
public bool Equals(Image other)
|
||||
{
|
||||
return
|
||||
this.frameId == other.frameId &&
|
||||
this.Type == other.Type &&
|
||||
this.Timestamp == other.Timestamp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A string containing a brief, human readable description of the Image object.
|
||||
/// @since 2.1.0
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return "Image sequence" + this.frameId + ", format: " + this.Format + ", type: " + this.Type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The image sequence ID.
|
||||
/// @since 2.2.1
|
||||
/// </summary>
|
||||
public Int64 SequenceId
|
||||
{
|
||||
get
|
||||
{
|
||||
return frameId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The image width.
|
||||
/// @since 2.1.0
|
||||
/// </summary>
|
||||
public int Width
|
||||
{
|
||||
get
|
||||
{
|
||||
return (int)leftImage.width;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The image height.
|
||||
/// @since 2.1.0
|
||||
/// </summary>
|
||||
public int Height
|
||||
{
|
||||
get
|
||||
{
|
||||
return (int)leftImage.height;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of bytes per pixel.
|
||||
///
|
||||
/// Use this value along with Image.Width() and Image.Height()
|
||||
/// to calculate the size of the data buffer.
|
||||
///
|
||||
/// @since 2.2.0
|
||||
/// </summary>
|
||||
public int BytesPerPixel
|
||||
{
|
||||
get
|
||||
{
|
||||
return (int)leftImage.bpp;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The image format.
|
||||
/// @since 2.2.0
|
||||
/// </summary>
|
||||
public FormatType Format
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (leftImage.format)
|
||||
{
|
||||
case eLeapImageFormat.eLeapImageType_IR:
|
||||
return FormatType.INFRARED;
|
||||
case eLeapImageFormat.eLeapImageType_RGBIr_Bayer:
|
||||
return FormatType.IBRG;
|
||||
default:
|
||||
return FormatType.INFRARED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ImageType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (leftImage.type)
|
||||
{
|
||||
case eLeapImageType.eLeapImageType_Default:
|
||||
return ImageType.DEFAULT;
|
||||
case eLeapImageType.eLeapImageType_Raw:
|
||||
return ImageType.RAW;
|
||||
default:
|
||||
return ImageType.DEFAULT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The stride of the distortion map.
|
||||
///
|
||||
/// Since each point on the 64x64 element distortion map has two values in the
|
||||
/// buffer, the stride is 2 times the size of the grid. (Stride is currently fixed
|
||||
/// at 2 * 64 = 128).
|
||||
///
|
||||
/// @since 2.1.0
|
||||
/// </summary>
|
||||
public int DistortionWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
return leftImage.DistortionSize * 2;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The distortion map height.
|
||||
/// Currently fixed at 64.
|
||||
///
|
||||
/// @since 2.1.0
|
||||
/// </summary>
|
||||
public int DistortionHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
return leftImage.DistortionSize;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The horizontal ray offset for a particular camera.
|
||||
///
|
||||
/// Used to convert between normalized coordinates in the range [0..1] and the
|
||||
/// ray slope range [-4..4].
|
||||
///
|
||||
/// @since 4.0
|
||||
/// </summary>
|
||||
public float RayOffsetX(CameraType camera)
|
||||
{
|
||||
if (camera != CameraType.LEFT && camera != CameraType.RIGHT)
|
||||
return 0;
|
||||
|
||||
return imageData(camera).RayOffsetX;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The vertical ray offset for a particular camera.
|
||||
///
|
||||
/// Used to convert between normalized coordinates in the range [0..1] and the
|
||||
/// ray slope range [-4..4].
|
||||
///
|
||||
/// @since 2.1.0
|
||||
/// </summary>
|
||||
public float RayOffsetY(CameraType camera)
|
||||
{
|
||||
if (camera != CameraType.LEFT && camera != CameraType.RIGHT)
|
||||
return 0;
|
||||
|
||||
return imageData(camera).RayOffsetY;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The horizontal ray scale factor for a particular camera.
|
||||
///
|
||||
/// Used to convert between normalized coordinates in the range [0..1] and the
|
||||
/// ray slope range [-4..4].
|
||||
///
|
||||
/// @since 2.1.0
|
||||
/// </summary>
|
||||
public float RayScaleX(CameraType camera)
|
||||
{
|
||||
if (camera != CameraType.LEFT && camera != CameraType.RIGHT)
|
||||
return 0;
|
||||
|
||||
return imageData(camera).RayScaleX;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The vertical ray scale factor for a particular camera.
|
||||
///
|
||||
/// Used to convert between normalized coordinates in the range [0..1] and the
|
||||
/// ray slope range [-4..4].
|
||||
///
|
||||
/// @since 2.1.0
|
||||
/// </summary>
|
||||
public float RayScaleY(CameraType camera)
|
||||
{
|
||||
if (camera != CameraType.LEFT && camera != CameraType.RIGHT)
|
||||
return 0;
|
||||
|
||||
return imageData(camera).RayScaleY;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a timestamp indicating when this frame began being captured on the device.
|
||||
/// @since 2.2.7
|
||||
/// </summary>
|
||||
public Int64 Timestamp
|
||||
{
|
||||
get
|
||||
{
|
||||
return timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates the possible image formats.
|
||||
///
|
||||
/// The Image.Format() function returns an item from the FormatType enumeration.
|
||||
/// @since 2.2.0
|
||||
/// </summary>
|
||||
public enum FormatType
|
||||
{
|
||||
INFRARED = 0,
|
||||
IBRG = 1
|
||||
}
|
||||
|
||||
public enum ImageType
|
||||
{
|
||||
DEFAULT,
|
||||
RAW
|
||||
}
|
||||
|
||||
public enum CameraType
|
||||
{
|
||||
LEFT = 0,
|
||||
RIGHT = 1
|
||||
};
|
||||
}
|
||||
|
||||
}
|
47
ml_lme_cvr/vendor/LeapCSharp/ImageData.cs
vendored
Normal file
47
ml_lme_cvr/vendor/LeapCSharp/ImageData.cs
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace LeapInternal
|
||||
{
|
||||
using Leap;
|
||||
using System;
|
||||
|
||||
public class ImageData
|
||||
{
|
||||
private LEAP_IMAGE_PROPERTIES _properties;
|
||||
private object _object;
|
||||
|
||||
public Image.CameraType camera { get; protected set; }
|
||||
public eLeapImageType type { get { return _properties.type; } }
|
||||
public eLeapImageFormat format { get { return _properties.format; } }
|
||||
public UInt32 bpp { get { return _properties.bpp; } }
|
||||
public UInt32 width { get { return _properties.width; } }
|
||||
public UInt32 height { get { return _properties.height; } }
|
||||
public float RayScaleX { get { return _properties.x_scale; } }
|
||||
public float RayScaleY { get { return _properties.y_scale; } }
|
||||
public float RayOffsetX { get { return _properties.x_offset; } }
|
||||
public float RayOffsetY { get { return _properties.y_offset; } }
|
||||
public byte[] AsByteArray { get { return _object as byte[]; } }
|
||||
public float[] AsFloatArray { get { return _object as float[]; } }
|
||||
public UInt32 byteOffset { get; protected set; }
|
||||
|
||||
public int DistortionSize { get { return LeapC.DistortionSize; } }
|
||||
public UInt64 DistortionMatrixKey { get; protected set; }
|
||||
public DistortionData DistortionData { get; protected set; }
|
||||
|
||||
public ImageData(Image.CameraType camera, LEAP_IMAGE image, DistortionData distortionData)
|
||||
{
|
||||
this.camera = camera;
|
||||
this._properties = image.properties;
|
||||
this.DistortionMatrixKey = image.matrix_version;
|
||||
this.DistortionData = distortionData;
|
||||
this._object = MemoryManager.GetPinnedObject(image.data);
|
||||
this.byteOffset = image.offset;
|
||||
}
|
||||
}
|
||||
}
|
1195
ml_lme_cvr/vendor/LeapCSharp/LeapC.cs
vendored
Normal file
1195
ml_lme_cvr/vendor/LeapCSharp/LeapC.cs
vendored
Normal file
File diff suppressed because it is too large
Load diff
171
ml_lme_cvr/vendor/LeapCSharp/LeapQuaternion.cs
vendored
Normal file
171
ml_lme_cvr/vendor/LeapCSharp/LeapQuaternion.cs
vendored
Normal file
|
@ -0,0 +1,171 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// The LeapQuaternion struct represents a rotation in three-dimensional space.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct LeapQuaternion :
|
||||
IEquatable<LeapQuaternion>
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new LeapQuaternion with the specified component values.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public LeapQuaternion(float x, float y, float z, float w) :
|
||||
this()
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.w = w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the specified LeapQuaternion.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public LeapQuaternion(LeapQuaternion quaternion) :
|
||||
this()
|
||||
{
|
||||
x = quaternion.x;
|
||||
y = quaternion.y;
|
||||
z = quaternion.z;
|
||||
w = quaternion.w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the specified LEAP_QUATERNION.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public LeapQuaternion(LeapInternal.LEAP_QUATERNION quaternion) :
|
||||
this()
|
||||
{
|
||||
x = quaternion.x;
|
||||
y = quaternion.y;
|
||||
z = quaternion.z;
|
||||
w = quaternion.w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string containing this quaternion in a human readable format: (x, y, z).
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return "(" + x + ", " + y + ", " + z + ", " + w + ")";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare LeapQuaternion equality component-wise.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public bool Equals(LeapQuaternion v)
|
||||
{
|
||||
return x.NearlyEquals(v.x) && y.NearlyEquals(v.y) && z.NearlyEquals(v.z) && w.NearlyEquals(v.w);
|
||||
}
|
||||
public override bool Equals(Object obj)
|
||||
{
|
||||
return obj is LeapQuaternion && Equals((LeapQuaternion)obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if all of the quaternion's components are finite. If any
|
||||
/// component is NaN or infinite, then this returns false.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public bool IsValid()
|
||||
{
|
||||
return !(float.IsNaN(x) || float.IsInfinity(x) ||
|
||||
float.IsNaN(y) || float.IsInfinity(y) ||
|
||||
float.IsNaN(z) || float.IsInfinity(z) ||
|
||||
float.IsNaN(w) || float.IsInfinity(w));
|
||||
}
|
||||
|
||||
public float x;
|
||||
public float y;
|
||||
public float z;
|
||||
public float w;
|
||||
|
||||
/// <summary>
|
||||
/// The magnitude, or length, of this quaternion.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public float Magnitude
|
||||
{
|
||||
get { return (float)Math.Sqrt(x * x + y * y + z * z + w * w); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The square of the magnitude, or length, of this quaternion.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public float MagnitudeSquared
|
||||
{
|
||||
get { return x * x + y * y + z * z + w * w; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A normalized copy of this quaternion.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public LeapQuaternion Normalized
|
||||
{
|
||||
get
|
||||
{
|
||||
float denom = MagnitudeSquared;
|
||||
if (denom <= Constants.EPSILON)
|
||||
{
|
||||
return Identity;
|
||||
}
|
||||
denom = 1.0f / (float)Math.Sqrt(denom);
|
||||
return new LeapQuaternion(x * denom, y * denom, z * denom, w * denom);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Concatenates the rotation described by this quaternion with the one provided
|
||||
/// and returns the result.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public LeapQuaternion Multiply(LeapQuaternion rhs)
|
||||
{
|
||||
return new LeapQuaternion(
|
||||
w * rhs.x + x * rhs.w + y * rhs.z - z * rhs.y,
|
||||
w * rhs.y + y * rhs.w + z * rhs.x - x * rhs.z,
|
||||
w * rhs.z + z * rhs.w + x * rhs.y - y * rhs.x,
|
||||
w * rhs.w - x * rhs.x - y * rhs.y - z * rhs.z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The identity quaternion.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public static readonly LeapQuaternion Identity = new LeapQuaternion(0, 0, 0, 1);
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked // Overflow is fine, just wrap
|
||||
{
|
||||
int hash = 17;
|
||||
hash = hash * 23 + x.GetHashCode();
|
||||
hash = hash * 23 + y.GetHashCode();
|
||||
hash = hash * 23 + z.GetHashCode();
|
||||
hash = hash * 23 + w.GetHashCode();
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
277
ml_lme_cvr/vendor/LeapCSharp/LeapTransform.cs
vendored
Normal file
277
ml_lme_cvr/vendor/LeapCSharp/LeapTransform.cs
vendored
Normal file
|
@ -0,0 +1,277 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// The LeapTransform class represents a transform in three dimensional space.
|
||||
///
|
||||
/// Note that the LeapTransform class replaces the Leap.Matrix class.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public struct LeapTransform
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs a new transform from the specified translation and rotation.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public LeapTransform(Vector translation, LeapQuaternion rotation) :
|
||||
this(translation, rotation, Vector.Ones)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new transform from the specified translation, rotation and scale.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public LeapTransform(Vector translation, LeapQuaternion rotation, Vector scale) :
|
||||
this()
|
||||
{
|
||||
_scale = scale;
|
||||
// these are non-trival setters.
|
||||
this.translation = translation;
|
||||
this.rotation = rotation; // Calls validateBasis
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms the specified position vector, applying translation, rotation and scale.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public Vector TransformPoint(Vector point)
|
||||
{
|
||||
return _xBasisScaled * point.x + _yBasisScaled * point.y + _zBasisScaled * point.z + translation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms the specified direction vector, applying rotation only.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public Vector TransformDirection(Vector direction)
|
||||
{
|
||||
return _xBasis * direction.x + _yBasis * direction.y + _zBasis * direction.z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms the specified velocity vector, applying rotation and scale.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public Vector TransformVelocity(Vector velocity)
|
||||
{
|
||||
return _xBasisScaled * velocity.x + _yBasisScaled * velocity.y + _zBasisScaled * velocity.z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms the specified quaternion.
|
||||
/// Multiplies the quaternion representing the rotational part of this transform by the specified
|
||||
/// quaternion.
|
||||
///
|
||||
/// **Important:** Modifying the basis vectors of this transform directly leaves the underlying quaternion in
|
||||
/// an indeterminate state. Neither this function nor the LeapTransform.rotation quaternion can be used after
|
||||
/// the basis vectors are set.
|
||||
///
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public LeapQuaternion TransformQuaternion(LeapQuaternion rhs)
|
||||
{
|
||||
if (_quaternionDirty)
|
||||
throw new InvalidOperationException("Calling TransformQuaternion after Basis vectors have been modified.");
|
||||
|
||||
if (_flip)
|
||||
{
|
||||
// Mirror the axis of rotation across the flip axis.
|
||||
rhs.x *= _flipAxes.x;
|
||||
rhs.y *= _flipAxes.y;
|
||||
rhs.z *= _flipAxes.z;
|
||||
}
|
||||
|
||||
LeapQuaternion t = _quaternion.Multiply(rhs);
|
||||
return t;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mirrors this transform's rotation and scale across the x-axis. Translation is not affected.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public void MirrorX()
|
||||
{
|
||||
_xBasis = -_xBasis;
|
||||
_xBasisScaled = -_xBasisScaled;
|
||||
|
||||
_flip = true;
|
||||
_flipAxes.y = -_flipAxes.y;
|
||||
_flipAxes.z = -_flipAxes.z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mirrors this transform's rotation and scale across the z-axis. Translation is not affected.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public void MirrorZ()
|
||||
{
|
||||
_zBasis = -_zBasis;
|
||||
_zBasisScaled = -_zBasisScaled;
|
||||
|
||||
_flip = true;
|
||||
_flipAxes.x = -_flipAxes.x;
|
||||
_flipAxes.y = -_flipAxes.y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The x-basis of the transform.
|
||||
///
|
||||
/// **Important:** Modifying the basis vectors of this transform directly leaves the underlying quaternion in
|
||||
/// an indeterminate state. Neither the TransformQuaternion() function nor the LeapTransform.rotation quaternion
|
||||
/// can be used after the basis vectors are set.
|
||||
///
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public Vector xBasis
|
||||
{
|
||||
get { return _xBasis; }
|
||||
set
|
||||
{
|
||||
_xBasis = value;
|
||||
_xBasisScaled = value * scale.x;
|
||||
_quaternionDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The y-basis of the transform.
|
||||
///
|
||||
/// **Important:** Modifying the basis vectors of this transform directly leaves the underlying quaternion in
|
||||
/// an indeterminate state. Neither the TransformQuaternion() function nor the LeapTransform.rotation quaternion
|
||||
/// can be used after the basis vectors are set.
|
||||
///
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public Vector yBasis
|
||||
{
|
||||
get { return _yBasis; }
|
||||
set
|
||||
{
|
||||
_yBasis = value;
|
||||
_yBasisScaled = value * scale.y;
|
||||
_quaternionDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The z-basis of the transform.
|
||||
///
|
||||
/// **Important:** Modifying the basis vectors of this transform directly leaves the underlying quaternion in
|
||||
/// an indeterminate state. Neither the TransformQuaternion() function nor the LeapTransform.rotation quaternion
|
||||
/// can be used after the basis vectors are set.
|
||||
///
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public Vector zBasis
|
||||
{
|
||||
get { return _zBasis; }
|
||||
set
|
||||
{
|
||||
_zBasis = value;
|
||||
_zBasisScaled = value * scale.z;
|
||||
_quaternionDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The translation component of the transform.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public Vector translation
|
||||
{
|
||||
get { return _translation; }
|
||||
set
|
||||
{
|
||||
_translation = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The scale factors of the transform.
|
||||
/// Scale is kept separate from translation.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public Vector scale
|
||||
{
|
||||
get { return _scale; }
|
||||
set
|
||||
{
|
||||
_scale = value;
|
||||
_xBasisScaled = _xBasis * scale.x;
|
||||
_yBasisScaled = _yBasis * scale.y;
|
||||
_zBasisScaled = _zBasis * scale.z;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The rotational component of the transform.
|
||||
///
|
||||
/// **Important:** Modifying the basis vectors of this transform directly leaves the underlying quaternion in
|
||||
/// an indeterminate state. This rotation quaternion cannot be accessed after
|
||||
/// the basis vectors are modified directly.
|
||||
///
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public LeapQuaternion rotation
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_quaternionDirty)
|
||||
throw new InvalidOperationException("Requesting rotation after Basis vectors have been modified.");
|
||||
return _quaternion;
|
||||
}
|
||||
set
|
||||
{
|
||||
_quaternion = value;
|
||||
|
||||
float d = value.MagnitudeSquared;
|
||||
float s = 2.0f / d;
|
||||
float xs = value.x * s, ys = value.y * s, zs = value.z * s;
|
||||
float wx = value.w * xs, wy = value.w * ys, wz = value.w * zs;
|
||||
float xx = value.x * xs, xy = value.x * ys, xz = value.x * zs;
|
||||
float yy = value.y * ys, yz = value.y * zs, zz = value.z * zs;
|
||||
|
||||
_xBasis = new Vector(1.0f - (yy + zz), xy + wz, xz - wy);
|
||||
_yBasis = new Vector(xy - wz, 1.0f - (xx + zz), yz + wx);
|
||||
_zBasis = new Vector(xz + wy, yz - wx, 1.0f - (xx + yy));
|
||||
|
||||
_xBasisScaled = _xBasis * scale.x;
|
||||
_yBasisScaled = _yBasis * scale.y;
|
||||
_zBasisScaled = _zBasis * scale.z;
|
||||
|
||||
_quaternionDirty = false;
|
||||
_flip = false;
|
||||
_flipAxes = new Vector(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The identity transform.
|
||||
/// @since 3.1.2
|
||||
/// </summary>
|
||||
public static readonly LeapTransform Identity = new LeapTransform(Vector.Zero, LeapQuaternion.Identity, Vector.Ones);
|
||||
|
||||
private Vector _translation;
|
||||
private Vector _scale;
|
||||
private LeapQuaternion _quaternion;
|
||||
private bool _quaternionDirty;
|
||||
private bool _flip;
|
||||
private Vector _flipAxes;
|
||||
private Vector _xBasis;
|
||||
private Vector _yBasis;
|
||||
private Vector _zBasis;
|
||||
private Vector _xBasisScaled;
|
||||
private Vector _yBasisScaled;
|
||||
private Vector _zBasisScaled;
|
||||
}
|
||||
}
|
55
ml_lme_cvr/vendor/LeapCSharp/Logger.cs
vendored
Normal file
55
ml_lme_cvr/vendor/LeapCSharp/Logger.cs
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LeapInternal
|
||||
{
|
||||
public static class Logger
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Logs message to the a Console.
|
||||
/// </summary>
|
||||
public static void Log(object message)
|
||||
{
|
||||
UnityEngine.Debug.Log(message);
|
||||
}
|
||||
|
||||
public static void LogStruct(object thisObject, string title = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!thisObject.GetType().IsValueType)
|
||||
{
|
||||
Log(title + " ---- Trying to log non-struct with struct logger");
|
||||
return;
|
||||
}
|
||||
Log(title + " ---- " + thisObject.GetType().ToString());
|
||||
FieldInfo[] fieldInfos;
|
||||
fieldInfos = thisObject.GetType().GetFields(
|
||||
BindingFlags.Public | BindingFlags.NonPublic // Get public and non-public
|
||||
| BindingFlags.Static | BindingFlags.Instance // Get instance + static
|
||||
| BindingFlags.FlattenHierarchy); // Search up the hierarchy
|
||||
|
||||
// write member names
|
||||
foreach (FieldInfo fieldInfo in fieldInfos)
|
||||
{
|
||||
object obj = fieldInfo.GetValue(thisObject);
|
||||
string value = obj == null ? "null" : obj.ToString();
|
||||
Log(" -------- Name: " + fieldInfo.Name + ", Value = " + value);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log(exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
362
ml_lme_cvr/vendor/LeapCSharp/Matrix.cs
vendored
Normal file
362
ml_lme_cvr/vendor/LeapCSharp/Matrix.cs
vendored
Normal file
|
@ -0,0 +1,362 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// The Matrix struct represents a transformation matrix.
|
||||
///
|
||||
/// To use this struct to transform a Vector, construct a matrix containing the
|
||||
/// desired transformation and then use the Matrix::transformPoint() or
|
||||
/// Matrix.TransformDirection() functions to apply the transform.
|
||||
///
|
||||
/// Transforms can be combined by multiplying two or more transform matrices using
|
||||
/// the * operator.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public struct Matrix
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Multiply two matrices.
|
||||
/// </summary>
|
||||
public static Matrix operator *(Matrix m1, Matrix m2)
|
||||
{
|
||||
return m1._operator_mul(m2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy this matrix to the specified array of 9 float values in row-major order.
|
||||
/// </summary>
|
||||
public float[] ToArray3x3(float[] output)
|
||||
{
|
||||
output[0] = xBasis.x;
|
||||
output[1] = xBasis.y;
|
||||
output[2] = xBasis.z;
|
||||
output[3] = yBasis.x;
|
||||
output[4] = yBasis.y;
|
||||
output[5] = yBasis.z;
|
||||
output[6] = zBasis.x;
|
||||
output[7] = zBasis.y;
|
||||
output[8] = zBasis.z;
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy this matrix to the specified array containing 9 double values in row-major order.
|
||||
/// </summary>
|
||||
public double[] ToArray3x3(double[] output)
|
||||
{
|
||||
output[0] = xBasis.x;
|
||||
output[1] = xBasis.y;
|
||||
output[2] = xBasis.z;
|
||||
output[3] = yBasis.x;
|
||||
output[4] = yBasis.y;
|
||||
output[5] = yBasis.z;
|
||||
output[6] = zBasis.x;
|
||||
output[7] = zBasis.y;
|
||||
output[8] = zBasis.z;
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert this matrix to an array containing 9 float values in row-major order.
|
||||
/// </summary>
|
||||
public float[] ToArray3x3()
|
||||
{
|
||||
return ToArray3x3(new float[9]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy this matrix to the specified array of 16 float values in row-major order.
|
||||
/// </summary>
|
||||
public float[] ToArray4x4(float[] output)
|
||||
{
|
||||
output[0] = xBasis.x;
|
||||
output[1] = xBasis.y;
|
||||
output[2] = xBasis.z;
|
||||
output[3] = 0.0f;
|
||||
output[4] = yBasis.x;
|
||||
output[5] = yBasis.y;
|
||||
output[6] = yBasis.z;
|
||||
output[7] = 0.0f;
|
||||
output[8] = zBasis.x;
|
||||
output[9] = zBasis.y;
|
||||
output[10] = zBasis.z;
|
||||
output[11] = 0.0f;
|
||||
output[12] = origin.x;
|
||||
output[13] = origin.y;
|
||||
output[14] = origin.z;
|
||||
output[15] = 1.0f;
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy this matrix to the specified array of 16 double values in row-major order.
|
||||
/// </summary>
|
||||
public double[] ToArray4x4(double[] output)
|
||||
{
|
||||
output[0] = xBasis.x;
|
||||
output[1] = xBasis.y;
|
||||
output[2] = xBasis.z;
|
||||
output[3] = 0.0f;
|
||||
output[4] = yBasis.x;
|
||||
output[5] = yBasis.y;
|
||||
output[6] = yBasis.z;
|
||||
output[7] = 0.0f;
|
||||
output[8] = zBasis.x;
|
||||
output[9] = zBasis.y;
|
||||
output[10] = zBasis.z;
|
||||
output[11] = 0.0f;
|
||||
output[12] = origin.x;
|
||||
output[13] = origin.y;
|
||||
output[14] = origin.z;
|
||||
output[15] = 1.0f;
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert this matrix to an array containing 16 float values in row-major order.
|
||||
/// </summary>
|
||||
public float[] ToArray4x4()
|
||||
{
|
||||
return ToArray4x4(new float[16]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a copy of the specified Matrix object.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Matrix(Matrix other) :
|
||||
this()
|
||||
{
|
||||
xBasis = other.xBasis;
|
||||
yBasis = other.yBasis;
|
||||
zBasis = other.zBasis;
|
||||
origin = other.origin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a transformation matrix from the specified basis vectors.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Matrix(Vector xBasis, Vector yBasis, Vector zBasis) :
|
||||
this()
|
||||
{
|
||||
this.xBasis = xBasis;
|
||||
this.yBasis = yBasis;
|
||||
this.zBasis = zBasis;
|
||||
this.origin = Vector.Zero;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a transformation matrix from the specified basis and translation vectors.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Matrix(Vector xBasis, Vector yBasis, Vector zBasis, Vector origin) :
|
||||
this()
|
||||
{
|
||||
this.xBasis = xBasis;
|
||||
this.yBasis = yBasis;
|
||||
this.zBasis = zBasis;
|
||||
this.origin = origin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a transformation matrix specifying a rotation around the specified vector.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Matrix(Vector axis, float angleRadians) :
|
||||
this()
|
||||
{
|
||||
xBasis = Vector.XAxis;
|
||||
yBasis = Vector.YAxis;
|
||||
zBasis = Vector.ZAxis;
|
||||
origin = Vector.Zero;
|
||||
SetRotation(axis, angleRadians);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a transformation matrix specifying a rotation around the specified vector
|
||||
/// and a translation by the specified vector.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Matrix(Vector axis, float angleRadians, Vector translation) :
|
||||
this()
|
||||
{
|
||||
xBasis = Vector.XAxis;
|
||||
yBasis = Vector.YAxis;
|
||||
zBasis = Vector.ZAxis;
|
||||
origin = translation;
|
||||
this.SetRotation(axis, angleRadians);
|
||||
}
|
||||
|
||||
public Matrix(float m00,
|
||||
float m01,
|
||||
float m02,
|
||||
float m10,
|
||||
float m11,
|
||||
float m12,
|
||||
float m20,
|
||||
float m21,
|
||||
float m22) :
|
||||
this()
|
||||
{
|
||||
xBasis = new Vector(m00, m01, m02);
|
||||
yBasis = new Vector(m10, m11, m12);
|
||||
zBasis = new Vector(m20, m21, m22);
|
||||
origin = Vector.Zero;
|
||||
}
|
||||
|
||||
public Matrix(float m00,
|
||||
float m01,
|
||||
float m02,
|
||||
float m10,
|
||||
float m11,
|
||||
float m12,
|
||||
float m20,
|
||||
float m21,
|
||||
float m22,
|
||||
float m30,
|
||||
float m31,
|
||||
float m32) :
|
||||
this()
|
||||
{
|
||||
xBasis = new Vector(m00, m01, m02);
|
||||
yBasis = new Vector(m10, m11, m12);
|
||||
zBasis = new Vector(m20, m21, m22);
|
||||
origin = new Vector(m30, m31, m32);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets this transformation matrix to represent a rotation around the specified vector.
|
||||
///
|
||||
/// This function erases any previous rotation and scale transforms applied
|
||||
/// to this matrix, but does not affect translation.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public void SetRotation(Vector axis, float angleRadians)
|
||||
{
|
||||
Vector n = axis.Normalized;
|
||||
float s = (float)Math.Sin(angleRadians);
|
||||
float c = (float)Math.Cos(angleRadians);
|
||||
float C = (1 - c);
|
||||
|
||||
xBasis = new Vector(n[0] * n[0] * C + c, n[0] * n[1] * C - n[2] * s, n[0] * n[2] * C + n[1] * s);
|
||||
yBasis = new Vector(n[1] * n[0] * C + n[2] * s, n[1] * n[1] * C + c, n[1] * n[2] * C - n[0] * s);
|
||||
zBasis = new Vector(n[2] * n[0] * C - n[1] * s, n[2] * n[1] * C + n[0] * s, n[2] * n[2] * C + c);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a vector with this matrix by transforming its rotation,
|
||||
/// scale, and translation.
|
||||
///
|
||||
/// Translation is applied after rotation and scale.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector TransformPoint(Vector point)
|
||||
{
|
||||
return xBasis * point.x + yBasis * point.y + zBasis * point.z + origin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a vector with this matrix by transforming its rotation and
|
||||
/// scale only.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector TransformDirection(Vector direction)
|
||||
{
|
||||
return xBasis * direction.x + yBasis * direction.y + zBasis * direction.z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a matrix inverse if the matrix consists entirely of rigid
|
||||
/// transformations (translations and rotations). If the matrix is not rigid,
|
||||
/// this operation will not represent an inverse.
|
||||
///
|
||||
/// Note that all matrices that are directly returned by the API are rigid.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Matrix RigidInverse()
|
||||
{
|
||||
Matrix rotInverse = new Matrix(new Vector(xBasis[0], yBasis[0], zBasis[0]),
|
||||
new Vector(xBasis[1], yBasis[1], zBasis[1]),
|
||||
new Vector(xBasis[2], yBasis[2], zBasis[2]));
|
||||
rotInverse.origin = rotInverse.TransformDirection(-origin);
|
||||
return rotInverse;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiply transform matrices.
|
||||
/// Combines two transformations into a single equivalent transformation.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
private Matrix _operator_mul(Matrix other)
|
||||
{
|
||||
return new Matrix(TransformDirection(other.xBasis),
|
||||
TransformDirection(other.yBasis),
|
||||
TransformDirection(other.zBasis),
|
||||
TransformPoint(other.origin));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare Matrix equality component-wise.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public bool Equals(Matrix other)
|
||||
{
|
||||
return xBasis == other.xBasis &&
|
||||
yBasis == other.yBasis &&
|
||||
zBasis == other.zBasis &&
|
||||
origin == other.origin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write the matrix to a string in a human readable format.
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("xBasis: {0} yBasis: {1} zBasis: {2} origin: {3}", xBasis, yBasis, zBasis, origin);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The basis vector for the x-axis.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector xBasis { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The basis vector for the y-axis.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector yBasis { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The basis vector for the z-axis.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector zBasis { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The translation factors for all three axes.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector origin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the identity matrix specifying no translation, rotation, and scale.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public static readonly Matrix Identity = new Matrix(Vector.XAxis, Vector.YAxis, Vector.ZAxis, Vector.Zero);
|
||||
}
|
||||
}
|
190
ml_lme_cvr/vendor/LeapCSharp/MemoryManager.cs
vendored
Normal file
190
ml_lme_cvr/vendor/LeapCSharp/MemoryManager.cs
vendored
Normal file
|
@ -0,0 +1,190 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
using AOT;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace LeapInternal
|
||||
{
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate IntPtr Allocate(UInt32 size, eLeapAllocatorType typeHint, IntPtr state);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void Deallocate(IntPtr buffer, IntPtr state);
|
||||
|
||||
public static class MemoryManager
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Specifies whether or not a pooling strategy should be used for the
|
||||
/// internal MemoryManager. If enabled, memory will be periodically
|
||||
/// recycled to be used again instead of being deallocated.
|
||||
///
|
||||
/// An object may be reclaimed from the pool at any time on the
|
||||
/// worker thread. If you are running into issues where an object
|
||||
/// you are working with is being overwritten, consider making a copy,
|
||||
/// or turning up the MinPoolSize.
|
||||
/// </summary>
|
||||
public static bool EnablePooling = true;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies how many objects of a specific type need to be in the pool
|
||||
/// before they will start to be recycled. Turning this number up can
|
||||
/// help prevent issues where objects you are working with are being
|
||||
/// overwritten with new objects. Turning this number down can reduce
|
||||
/// the total memory footprint used by the memory manager.
|
||||
/// </summary>
|
||||
public static uint MinPoolSize = 64;
|
||||
|
||||
private static ConcurrentDictionary<IntPtr, ActiveMemoryInfo> _activeMemory =
|
||||
new ConcurrentDictionary<IntPtr, ActiveMemoryInfo>();
|
||||
private static ConcurrentDictionary<PoolKey, Queue<object>> _pooledMemory =
|
||||
new ConcurrentDictionary<PoolKey, Queue<object>>();
|
||||
|
||||
[MonoPInvokeCallback(typeof(Allocate))]
|
||||
public static IntPtr Pin(UInt32 size, eLeapAllocatorType typeHint, IntPtr state)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Construct a key to identify the desired allocation
|
||||
PoolKey key = new PoolKey()
|
||||
{
|
||||
type = typeHint,
|
||||
size = size
|
||||
};
|
||||
|
||||
//Attempt to find the pool that holds this type of allocation
|
||||
Queue<object> pool;
|
||||
if (!_pooledMemory.TryGetValue(key, out pool))
|
||||
{
|
||||
//Construct a new pool if none exists yet
|
||||
pool = new Queue<object>();
|
||||
_pooledMemory[key] = pool;
|
||||
}
|
||||
|
||||
//Attempt to get an object from the pool
|
||||
object memory;
|
||||
if (EnablePooling && pool.Count > MinPoolSize)
|
||||
{
|
||||
memory = pool.Dequeue();
|
||||
}
|
||||
else
|
||||
{
|
||||
//If the pool is empty, we need to construct a new object
|
||||
switch (typeHint)
|
||||
{
|
||||
default:
|
||||
case eLeapAllocatorType.eLeapAllocatorType_Uint8:
|
||||
memory = new byte[size];
|
||||
break;
|
||||
case eLeapAllocatorType.eLeapAllocatorType_Float:
|
||||
memory = new float[(size + sizeof(float) - 1) / sizeof(float)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Pin the object so its address will not change
|
||||
GCHandle handle = GCHandle.Alloc(memory, GCHandleType.Pinned);
|
||||
IntPtr ptr = handle.AddrOfPinnedObject();
|
||||
|
||||
//Put the information about the newly pinned allocation into the
|
||||
//active memory map so it can be retrieved and freed layer.
|
||||
_activeMemory.TryAdd(ptr, new ActiveMemoryInfo()
|
||||
{
|
||||
handle = handle,
|
||||
key = key
|
||||
});
|
||||
|
||||
return ptr;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogException(e);
|
||||
}
|
||||
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
[MonoPInvokeCallback(typeof(Deallocate))]
|
||||
public static void Unpin(IntPtr ptr, IntPtr state)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Grab the info for the given pointer
|
||||
ActiveMemoryInfo info = _activeMemory[ptr];
|
||||
|
||||
//First we return the object back to its pool
|
||||
if (EnablePooling)
|
||||
{
|
||||
_pooledMemory[info.key].Enqueue(info.handle.Target);
|
||||
}
|
||||
|
||||
//Then we remove the pointer from the active memory map
|
||||
ActiveMemoryInfo value;
|
||||
|
||||
_activeMemory.TryRemove(ptr, out value);
|
||||
|
||||
//Finally we unpin the memory
|
||||
info.handle.Free();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static object GetPinnedObject(IntPtr ptr)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _activeMemory[ptr].handle.Target;
|
||||
}
|
||||
catch (Exception) { }
|
||||
return null;
|
||||
}
|
||||
|
||||
private struct PoolKey : IEquatable<PoolKey>
|
||||
{
|
||||
public eLeapAllocatorType type;
|
||||
public UInt32 size;
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (int)type | (int)size << 4;
|
||||
}
|
||||
|
||||
public bool Equals(PoolKey other)
|
||||
{
|
||||
return type == other.type &&
|
||||
size == other.size;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is PoolKey)
|
||||
{
|
||||
return Equals((PoolKey)obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct ActiveMemoryInfo
|
||||
{
|
||||
public GCHandle handle;
|
||||
public PoolKey key;
|
||||
}
|
||||
}
|
||||
}
|
24
ml_lme_cvr/vendor/LeapCSharp/MessageSeverity.cs
vendored
Normal file
24
ml_lme_cvr/vendor/LeapCSharp/MessageSeverity.cs
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
/// <summary>
|
||||
/// Reports whether the message is for
|
||||
/// a severe failure, a recoverable warning, or a status change.
|
||||
/// @since 3.0
|
||||
/// </summary>
|
||||
public enum MessageSeverity
|
||||
{
|
||||
MESSAGE_UNKNOWN = 0,
|
||||
MESSAGE_CRITICAL = 1,
|
||||
MESSAGE_WARNING = 2,
|
||||
/** A verbose, informational message */
|
||||
MESSAGE_INFORMATION = 3
|
||||
}
|
||||
}
|
19
ml_lme_cvr/vendor/LeapCSharp/PointMapping.cs
vendored
Normal file
19
ml_lme_cvr/vendor/LeapCSharp/PointMapping.cs
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
|
||||
public struct PointMapping
|
||||
{
|
||||
public long frameId;
|
||||
public long timestamp;
|
||||
public Vector[] points;
|
||||
public uint[] ids;
|
||||
}
|
||||
}
|
92
ml_lme_cvr/vendor/LeapCSharp/StructMarshal.cs
vendored
Normal file
92
ml_lme_cvr/vendor/LeapCSharp/StructMarshal.cs
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace LeapInternal
|
||||
{
|
||||
|
||||
/**
|
||||
* A helper class to marshal between unmanaged memory and structs without creating garbage.
|
||||
*/
|
||||
public static class StructMarshal<T> where T : struct
|
||||
{
|
||||
#if !ENABLE_IL2CPP
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private class StructContainer
|
||||
{
|
||||
public T value;
|
||||
}
|
||||
|
||||
[ThreadStatic]
|
||||
private static StructContainer _container;
|
||||
#endif
|
||||
|
||||
private static int _sizeofT;
|
||||
|
||||
static StructMarshal()
|
||||
{
|
||||
_sizeofT = Marshal.SizeOf(typeof(T));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size in bytes of the struct of type T. This call is equivalent to
|
||||
* Marshal.Sizeof(typeof(T)) but caches the result for ease of access.
|
||||
*/
|
||||
public static int Size
|
||||
{
|
||||
get
|
||||
{
|
||||
return _sizeofT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an IntPtr to a struct of type T.
|
||||
*/
|
||||
public static void PtrToStruct(IntPtr ptr, out T t)
|
||||
{
|
||||
#if ENABLE_IL2CPP
|
||||
#if UNITY_2018_1_OR_NEWER
|
||||
unsafe {
|
||||
Unity.Collections.LowLevel.Unsafe.UnsafeUtility.CopyPtrToStructure((void*)ptr, out t);
|
||||
}
|
||||
#else
|
||||
#error UnityModules Only supports IL2CPP on versions of Unity 2018.1 or greater.
|
||||
#endif
|
||||
#else
|
||||
if (_container == null)
|
||||
{
|
||||
_container = new StructContainer();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Marshal.PtrToStructure(ptr, _container);
|
||||
t = _container.value;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogException(e);
|
||||
t = default(T);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a single element in an array pointed to by ptr to a struct
|
||||
* of type T. This method does not and cannot do any bounds checking!
|
||||
* This method does not create any garbage.
|
||||
*/
|
||||
public static void ArrayElementToStruct(IntPtr ptr, int arrayIndex, out T t)
|
||||
{
|
||||
PtrToStruct(new IntPtr(ptr.ToInt64() + _sizeofT * arrayIndex), out t);
|
||||
}
|
||||
}
|
||||
}
|
176
ml_lme_cvr/vendor/LeapCSharp/TransformExtensions.cs
vendored
Normal file
176
ml_lme_cvr/vendor/LeapCSharp/TransformExtensions.cs
vendored
Normal file
|
@ -0,0 +1,176 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using System;
|
||||
|
||||
public static class TransformExtensions
|
||||
{
|
||||
|
||||
/**
|
||||
* Does an in-place rigid transformation of a Frame.
|
||||
*
|
||||
* @param transform A LeapTransform containing the desired translation, rotation, and scale
|
||||
* to be applied to the Frame.
|
||||
*/
|
||||
public static Frame Transform(this Frame frame, LeapTransform transform)
|
||||
{
|
||||
for (int i = frame.Hands.Count; i-- != 0;)
|
||||
{
|
||||
frame.Hands[i].Transform(transform);
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new frame that is a copy of a frame, with an additional rigid
|
||||
* transformation applied to it.
|
||||
*
|
||||
* @param transform The transformation to be applied to the copied frame.
|
||||
*/
|
||||
public static Frame TransformedCopy(this Frame frame, LeapTransform transform)
|
||||
{
|
||||
return new Frame().CopyFrom(frame).Transform(transform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does an in-place rigid transformation of a Hand.
|
||||
*
|
||||
* @param transform A LeapTransform containing the desired translation, rotation, and scale
|
||||
* to be applied to the Hand.
|
||||
*/
|
||||
public static Hand Transform(this Hand hand, LeapTransform transform)
|
||||
{
|
||||
hand.PalmPosition = transform.TransformPoint(hand.PalmPosition);
|
||||
hand.StabilizedPalmPosition = transform.TransformPoint(hand.StabilizedPalmPosition);
|
||||
hand.PalmVelocity = transform.TransformVelocity(hand.PalmVelocity);
|
||||
hand.PalmNormal = transform.TransformDirection(hand.PalmNormal);
|
||||
hand.Direction = transform.TransformDirection(hand.Direction);
|
||||
hand.WristPosition = transform.TransformPoint(hand.WristPosition);
|
||||
hand.PalmWidth *= Math.Abs(transform.scale.x);
|
||||
hand.Rotation = transform.TransformQuaternion(hand.Rotation);
|
||||
|
||||
hand.Arm.Transform(transform);
|
||||
|
||||
for (int i = 5; i-- != 0;)
|
||||
{
|
||||
hand.Fingers[i].Transform(transform);
|
||||
}
|
||||
|
||||
return hand;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new hand that is a copy of a hand, with an additional rigid
|
||||
* transformation applied to it.
|
||||
*
|
||||
* @param transform The transformation to be applied to the copied hand.
|
||||
*/
|
||||
public static Hand TransformedCopy(this Hand hand, LeapTransform transform)
|
||||
{
|
||||
return new Hand().CopyFrom(hand).Transform(transform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does an in-place rigid transformation of a Finger.
|
||||
*
|
||||
* @param transform A LeapTransform containing the desired translation, rotation, and scale
|
||||
* to be applied to the Finger.
|
||||
*/
|
||||
public static Finger Transform(this Finger finger, LeapTransform transform)
|
||||
{
|
||||
Bone nextBone = finger.bones[3];
|
||||
nextBone.NextJoint = transform.TransformPoint(nextBone.NextJoint);
|
||||
|
||||
finger.TipPosition = nextBone.NextJoint;
|
||||
|
||||
for (int i = 3; i-- != 0;)
|
||||
{
|
||||
Bone bone = finger.bones[i];
|
||||
|
||||
bone.NextJoint = nextBone.PrevJoint = transform.TransformPoint(bone.NextJoint);
|
||||
|
||||
nextBone.TransformGivenJoints(transform);
|
||||
nextBone = bone;
|
||||
}
|
||||
|
||||
nextBone.PrevJoint = transform.TransformPoint(nextBone.PrevJoint);
|
||||
nextBone.TransformGivenJoints(transform);
|
||||
|
||||
finger.Direction = finger.bones[2].Direction;
|
||||
finger.Width *= Math.Abs(transform.scale.x);
|
||||
finger.Length *= Math.Abs(transform.scale.z);
|
||||
|
||||
return finger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new finger that is a copy of a finger, with an additional rigid
|
||||
* transformation applied to it.
|
||||
*
|
||||
* @param transform The transformation to be applied to the copied finger.
|
||||
*/
|
||||
public static Finger TransformedCopy(this Finger finger, LeapTransform transform)
|
||||
{
|
||||
return new Finger().CopyFrom(finger).Transform(transform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does an in-place rigid transformation of a Bone.
|
||||
*
|
||||
* @param transform A LeapTransform containing the desired translation, rotation, and scale
|
||||
- * to be applied to the bone.
|
||||
*/
|
||||
public static Bone Transform(this Bone bone, LeapTransform transform)
|
||||
{
|
||||
bone.PrevJoint = transform.TransformPoint(bone.PrevJoint);
|
||||
bone.NextJoint = transform.TransformPoint(bone.NextJoint);
|
||||
|
||||
bone.TransformGivenJoints(transform);
|
||||
|
||||
return bone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does an in-place rigid transformation of a Bone, assuming the joints have already been transformed.
|
||||
*
|
||||
* @param transform A LeapTransform containing the desired translation, rotation, and scale
|
||||
- * to be applied to the bone.
|
||||
*/
|
||||
internal static void TransformGivenJoints(this Bone bone, LeapTransform transform)
|
||||
{
|
||||
bone.Length *= Math.Abs(transform.scale.z);
|
||||
bone.Center = (bone.PrevJoint + bone.NextJoint) / 2.0f;
|
||||
|
||||
if (bone.Length < float.Epsilon)
|
||||
{
|
||||
bone.Direction = Vector.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
bone.Direction = (bone.NextJoint - bone.PrevJoint) / bone.Length;
|
||||
}
|
||||
|
||||
bone.Width *= Math.Abs(transform.scale.x);
|
||||
bone.Rotation = transform.TransformQuaternion(bone.Rotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new bone that is a copy of a bone, with an additional rigid
|
||||
* transformation applied to it.
|
||||
*
|
||||
* @param transform The transformation to be applied to the copied bone.
|
||||
*/
|
||||
public static Bone TransformedCopy(this Bone bone, LeapTransform transform)
|
||||
{
|
||||
return new Bone().CopyFrom(bone).Transform(transform);
|
||||
}
|
||||
}
|
||||
}
|
425
ml_lme_cvr/vendor/LeapCSharp/Vector.cs
vendored
Normal file
425
ml_lme_cvr/vendor/LeapCSharp/Vector.cs
vendored
Normal file
|
@ -0,0 +1,425 @@
|
|||
/******************************************************************************
|
||||
* Copyright (C) Ultraleap, Inc. 2011-2021. *
|
||||
* *
|
||||
* Use subject to the terms of the Apache License 2.0 available at *
|
||||
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
|
||||
* between Ultraleap and you, your company or other organization. *
|
||||
******************************************************************************/
|
||||
|
||||
namespace Leap
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Constants used in Leap Motion math functions.
|
||||
/// </summary>
|
||||
public static class Constants
|
||||
{
|
||||
public const float PI = 3.1415926536f;
|
||||
public const float DEG_TO_RAD = 0.0174532925f;
|
||||
public const float RAD_TO_DEG = 57.295779513f;
|
||||
public const float EPSILON = 1.192092896e-07f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Vector struct represents a three-component mathematical vector or point
|
||||
/// such as a direction or position in three-dimensional space.
|
||||
///
|
||||
/// The Leap Motion software employs a right-handed Cartesian coordinate system.
|
||||
/// Values given are in units of real-world millimeters. The origin is centered
|
||||
/// at the center of the Leap Motion Controller. The x- and z-axes lie in the horizontal
|
||||
/// plane, with the x-axis running parallel to the long edge of the device.
|
||||
/// The y-axis is vertical, with positive values increasing upwards (in contrast
|
||||
/// to the downward orientation of most computer graphics coordinate systems).
|
||||
/// The z-axis has positive values increasing away from the computer screen.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct Vector : IEquatable<Vector>
|
||||
{
|
||||
|
||||
public static Vector operator +(Vector v1, Vector v2)
|
||||
{
|
||||
return new Vector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
|
||||
}
|
||||
|
||||
public static Vector operator -(Vector v1, Vector v2)
|
||||
{
|
||||
return new Vector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
|
||||
}
|
||||
|
||||
public static Vector operator *(Vector v1, float scalar)
|
||||
{
|
||||
return new Vector(v1.x * scalar, v1.y * scalar, v1.z * scalar);
|
||||
}
|
||||
|
||||
public static Vector operator *(float scalar, Vector v1)
|
||||
{
|
||||
return new Vector(v1.x * scalar, v1.y * scalar, v1.z * scalar);
|
||||
}
|
||||
|
||||
public static Vector operator /(Vector v1, float scalar)
|
||||
{
|
||||
return new Vector(v1.x / scalar, v1.y / scalar, v1.z / scalar);
|
||||
}
|
||||
|
||||
public static Vector operator -(Vector v1)
|
||||
{
|
||||
return new Vector(-v1.x, -v1.y, -v1.z);
|
||||
}
|
||||
|
||||
public static bool operator ==(Vector v1, Vector v2)
|
||||
{
|
||||
return v1.Equals(v2);
|
||||
}
|
||||
|
||||
public static bool operator !=(Vector v1, Vector v2)
|
||||
{
|
||||
return !v1.Equals(v2);
|
||||
}
|
||||
|
||||
public float[] ToFloatArray()
|
||||
{
|
||||
return new float[] { x, y, z };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Vector with the specified component values.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector(float x, float y, float z) :
|
||||
this()
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the specified Vector.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector(Vector vector) :
|
||||
this()
|
||||
{
|
||||
x = vector.x;
|
||||
y = vector.y;
|
||||
z = vector.z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The distance between the point represented by this Vector
|
||||
/// object and a point represented by the specified Vector object.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float DistanceTo(Vector other)
|
||||
{
|
||||
return (float)Math.Sqrt((x - other.x) * (x - other.x) +
|
||||
(y - other.y) * (y - other.y) +
|
||||
(z - other.z) * (z - other.z));
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The angle between this vector and the specified vector in radians.
|
||||
///
|
||||
/// The angle is measured in the plane formed by the two vectors. The
|
||||
/// angle returned is always the smaller of the two conjugate angles.
|
||||
/// Thus A.angleTo(B) == B.angleTo(A) and is always a positive
|
||||
/// value less than or equal to pi radians (180 degrees).
|
||||
///
|
||||
/// If either vector has zero length, then this function returns zero.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float AngleTo(Vector other)
|
||||
{
|
||||
float denom = MagnitudeSquared * other.MagnitudeSquared;
|
||||
if (denom <= Constants.EPSILON)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
float val = Dot(other) / (float)Math.Sqrt(denom);
|
||||
if (val >= 1.0f)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
else if (val <= -1.0f)
|
||||
{
|
||||
return Constants.PI;
|
||||
}
|
||||
return (float)Math.Acos(val);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The dot product of this vector with another vector.
|
||||
///
|
||||
/// The dot product is the magnitude of the projection of this vector
|
||||
/// onto the specified vector.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float Dot(Vector other)
|
||||
{
|
||||
return (x * other.x) + (y * other.y) + (z * other.z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The cross product of this vector and the specified vector.
|
||||
///
|
||||
/// The cross product is a vector orthogonal to both original vectors.
|
||||
/// It has a magnitude equal to the area of a parallelogram having the
|
||||
/// two vectors as sides. The direction of the returned vector is
|
||||
/// determined by the right-hand rule. Thus A.cross(B) == -B.cross(A).
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector Cross(Vector other)
|
||||
{
|
||||
return new Vector((y * other.z) - (z * other.y),
|
||||
(z * other.x) - (x * other.z),
|
||||
(x * other.y) - (y * other.x));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string containing this vector in a human readable format: (x, y, z).
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return "(" + x + ", " + y + ", " + z + ")";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare Vector equality component-wise.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public bool Equals(Vector v)
|
||||
{
|
||||
return x.NearlyEquals(v.x) && y.NearlyEquals(v.y) && z.NearlyEquals(v.z);
|
||||
}
|
||||
|
||||
public override bool Equals(Object obj)
|
||||
{
|
||||
return obj is Vector && Equals((Vector)obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if all of the vector's components are finite. If any
|
||||
/// component is NaN or infinite, then this returns false.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public bool IsValid()
|
||||
{
|
||||
return !(float.IsNaN(x) || float.IsInfinity(x) ||
|
||||
float.IsNaN(y) || float.IsInfinity(y) ||
|
||||
float.IsNaN(z) || float.IsInfinity(z));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Index vector components numerically.
|
||||
/// Index 0 is x, index 1 is y, and index 2 is z.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float this[uint index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index == 0)
|
||||
return x;
|
||||
if (index == 1)
|
||||
return y;
|
||||
if (index == 2)
|
||||
return z;
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (index == 0)
|
||||
x = value;
|
||||
if (index == 1)
|
||||
y = value;
|
||||
if (index == 2)
|
||||
z = value;
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public float x;
|
||||
public float y;
|
||||
public float z;
|
||||
|
||||
/// <summary>
|
||||
/// The magnitude, or length, of this vector.
|
||||
///
|
||||
/// The magnitude is the L2 norm, or Euclidean distance between the origin and
|
||||
/// the point represented by the (x, y, z) components of this Vector object.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float Magnitude
|
||||
{
|
||||
get { return (float)Math.Sqrt(x * x + y * y + z * z); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The square of the magnitude, or length, of this vector.
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float MagnitudeSquared
|
||||
{
|
||||
get { return x * x + y * y + z * z; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The pitch angle in radians.
|
||||
///
|
||||
/// Pitch is the angle between the negative z-axis and the projection of
|
||||
/// the vector onto the y-z plane. In other words, pitch represents rotation
|
||||
/// around the x-axis.
|
||||
/// If the vector points upward, the returned angle is between 0 and pi radians
|
||||
/// (180 degrees); if it points downward, the angle is between 0 and -pi radians.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float Pitch
|
||||
{
|
||||
get { return (float)Math.Atan2(y, -z); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The roll angle in radians.
|
||||
///
|
||||
/// Roll is the angle between the y-axis and the projection of
|
||||
/// the vector onto the x-y plane. In other words, roll represents rotation
|
||||
/// around the z-axis. If the vector points to the left of the y-axis,
|
||||
/// then the returned angle is between 0 and pi radians (180 degrees);
|
||||
/// if it points to the right, the angle is between 0 and -pi radians.
|
||||
///
|
||||
/// Use this function to get roll angle of the plane to which this vector is a
|
||||
/// normal. For example, if this vector represents the normal to the palm,
|
||||
/// then this function returns the tilt or roll of the palm plane compared
|
||||
/// to the horizontal (x-z) plane.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float Roll
|
||||
{
|
||||
get { return (float)Math.Atan2(x, -y); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The yaw angle in radians.
|
||||
///
|
||||
/// Yaw is the angle between the negative z-axis and the projection of
|
||||
/// the vector onto the x-z plane. In other words, yaw represents rotation
|
||||
/// around the y-axis. If the vector points to the right of the negative z-axis,
|
||||
/// then the returned angle is between 0 and pi radians (180 degrees);
|
||||
/// if it points to the left, the angle is between 0 and -pi radians.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public float Yaw
|
||||
{
|
||||
get { return (float)Math.Atan2(x, -z); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A normalized copy of this vector.
|
||||
///
|
||||
/// A normalized vector has the same direction as the original vector,
|
||||
/// but with a length of one.
|
||||
///
|
||||
/// @since 1.0
|
||||
/// </summary>
|
||||
public Vector Normalized
|
||||
{
|
||||
get
|
||||
{
|
||||
float denom = MagnitudeSquared;
|
||||
if (denom <= Constants.EPSILON)
|
||||
{
|
||||
return Zero;
|
||||
}
|
||||
denom = 1.0f / (float)Math.Sqrt(denom);
|
||||
return new Vector(x * denom, y * denom, z * denom);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The zero vector: (0, 0, 0)
|
||||
/// </summary>
|
||||
public static readonly Vector Zero = new Vector(0, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The ones vector: (1, 1, 1)
|
||||
/// </summary>
|
||||
public static readonly Vector Ones = new Vector(1, 1, 1);
|
||||
|
||||
/// <summary>
|
||||
/// The x-axis unit vector: (1, 0, 0)
|
||||
/// </summary>
|
||||
public static readonly Vector XAxis = new Vector(1, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The y-axis unit vector: (0, 1, 0)
|
||||
/// </summary>
|
||||
public static readonly Vector YAxis = new Vector(0, 1, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The z-axis unit vector: (0, 0, 1)
|
||||
/// </summary>
|
||||
public static readonly Vector ZAxis = new Vector(0, 0, 1);
|
||||
|
||||
/// <summary>
|
||||
/// The unit vector pointing forward along the negative z-axis: (0, 0, -1)
|
||||
/// </summary>
|
||||
public static readonly Vector Forward = new Vector(0, 0, -1);
|
||||
|
||||
/// <summary>
|
||||
/// The unit vector pointing backward along the positive z-axis: (0, 0, 1)
|
||||
/// </summary>
|
||||
public static readonly Vector Backward = new Vector(0, 0, 1);
|
||||
|
||||
/// <summary>
|
||||
/// The unit vector pointing left along the negative x-axis: (-1, 0, 0)
|
||||
/// </summary>
|
||||
public static readonly Vector Left = new Vector(-1, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The unit vector pointing right along the positive x-axis: (1, 0, 0)
|
||||
/// </summary>
|
||||
public static readonly Vector Right = new Vector(1, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The unit vector pointing up along the positive y-axis: (0, 1, 0)
|
||||
/// </summary>
|
||||
public static readonly Vector Up = new Vector(0, 1, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The unit vector pointing down along the negative y-axis: (0, -1, 0)
|
||||
/// </summary>
|
||||
public static readonly Vector Down = new Vector(0, -1, 0);
|
||||
|
||||
|
||||
public static Vector Lerp(Vector a, Vector b, float t)
|
||||
{
|
||||
return new Vector(
|
||||
a.x + t * (b.x - a.x),
|
||||
a.y + t * (b.y - a.y),
|
||||
a.z + t * (b.z - a.z)
|
||||
);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked // Overflow is fine, just wrap
|
||||
{
|
||||
int hash = 17;
|
||||
hash = hash * 23 + x.GetHashCode();
|
||||
hash = hash * 23 + y.GetHashCode();
|
||||
hash = hash * 23 + z.GetHashCode();
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
388
ml_lme_cvr/vendor/LeapSDK/LICENSE.md
vendored
Normal file
388
ml_lme_cvr/vendor/LeapSDK/LICENSE.md
vendored
Normal file
|
@ -0,0 +1,388 @@
|
|||
ULTRALEAP TRACKING SDK AGREEMENT
|
||||
Updated: 26 October 2021
|
||||
Permitted uses
|
||||
This SDK Agreement (“Agreement”) covers use of the Ultraleap hand tracking SDK (the “SDK”) by
|
||||
individuals and businesses for the following purposes:
|
||||
1. Your personal, non-commercial use (for the avoidance of doubt, excluding use for the design or
|
||||
manufacture of a commercial or distributable product (e.g in design studios)); or
|
||||
2. Commercial use for the development and sale consumer facing games, made available for sale to
|
||||
be purchased by consumers for personal use either at retail or through app stores (excluding,
|
||||
without limitation, location-based entertainment and arcade applications); or
|
||||
3. Demonstration of your application to internal and external stakeholders and customers where
|
||||
there is no transaction, no sale of tickets specifically for the application, or any other form of
|
||||
compensation for you or your organisation,
|
||||
but in all cases excluding applications relating to the following: (a) the production of or trade in tobacco,
|
||||
alcoholic beverages, and related products, (b) the production or trade in weapons of any kind or any
|
||||
military applications, (c) casinos, gambling and equivalent enterprises, (d) human cloning, human
|
||||
embryos, or stem cells, or (e) nuclear energy.
|
||||
Any other uses, or applications using third party hardware are “Specialised Applications” and will require
|
||||
a separate license agreement. Please contact Ultraleap info@ultraleap.com for more information.
|
||||
In each case, the SDK may only be used with Ultraleap Hardware and Ultraleap Software.
|
||||
|
||||
1. Parties
|
||||
1.1. This Agreement is made between the individual or entity (“you” or the “Developer”) that accepts
|
||||
it and Ultraleap Limited (“Ultraleap”). You accept this Agreement by (a) accepting it on download
|
||||
of the SDK, or (b) if you use or access the SDK or any part of the SDK. Your entry into this
|
||||
Agreement also binds your authorized users, and your company or organisation.
|
||||
1.2. If you do not agree to the terms of this Agreement you must not use the SDK.
|
||||
1.3. Capitalized terms bear the meanings given in the “Definitions” section of this Agreement.
|
||||
1.4. This Agreement incorporates the terms of the Ultraleap Hand Tracking End User License
|
||||
Agreement (“EULA”), which is available at https://developer.leapmotion.com/end-user-license-
|
||||
agreement or from Ultraleap on request. In the event of a conflict between these terms and the
|
||||
EULA, these terms will prevail.
|
||||
2. License
|
||||
Development License
|
||||
2.1. Conditional on your compliance with the terms and conditions of this Agreement, Ultraleap
|
||||
hereby grants you a limited, non-exclusive, personal, revocable, non-sublicensable, and non-
|
||||
transferable license to:
|
||||
2.1.1. install and use a reasonable number of copies of the SDK on computers owned or
|
||||
controlled by you for the purpose of developing and testing applications that (a) are not
|
||||
Specialised Applications and (b) are intended for use solely in connection with Ultraleap
|
||||
Hardware and Ultraleap Software (each being an “Ultraleap Enabled Application”); and
|
||||
2.1.2. modify and incorporate into your Ultraleap Enabled Application any sample code
|
||||
provided in the SDK.
|
||||
Distribution License
|
||||
2.2. Conditional on your compliance with the terms and conditions of this Agreement, Ultraleap
|
||||
hereby grants you a limited, non-exclusive, personal, revocable, non-transferrable license of
|
||||
Ultraleap’s intellectual property rights to the extent necessary to:
|
||||
2.2.1. copy and distribute (or have copied and distributed) the Ultraleap Redistributables,
|
||||
solely as compiled with, incorporated into, or packaged with, your Ultraleap Enabled
|
||||
Application; and
|
||||
2.2.2. to make (but not have made), use, sell, offer for sale, and import your Ultraleap Enabled
|
||||
Application.
|
||||
3. Restrictions
|
||||
3.1. The license granted to you in section 2.1 and section 2.2 is subject to the following restrictions,
|
||||
as well as others listed in this Agreement:
|
||||
3.1.1. Except as expressly permitted in section 2.1, (a) you may not publish, distribute, or copy
|
||||
the SDK, and (b) you may not modify or create derivative works of the SDK;
|
||||
3.1.2. Except as expressly permitted in section 2.2, you may not, and may not allow any third
|
||||
party, directly or indirectly, to publish, post, or otherwise make available, the Ultraleap
|
||||
Redistributables;
|
||||
3.1.3. You may not, and may not enable others to, distributed the Non-Redistributable
|
||||
Materials;
|
||||
3.1.4. You may use the SDK solely in connection with Ultraleap Hardware and/or Ultraleap
|
||||
Software;
|
||||
3.1.5. You may not use the SDK to create, or aid in the creation, directly or indirectly, of any
|
||||
software or hardware which provides hand tracking functionality or which is otherwise
|
||||
substantially similar to the features or functionality of Ultraleap products;
|
||||
3.1.6. You may not, and may not enable others to, directly or indirectly, reverse engineer,
|
||||
decompile, disassemble, or otherwise attempt to reconstruct, identify, or discover any
|
||||
source code, underlying ideas, techniques, or algorithms in the Ultraleap Software, the
|
||||
Ultraleap Hardware, or any software which forms part of the SDK, nor attempt to
|
||||
circumvent any related security measures (except as and only to the extent any
|
||||
foregoing restriction is prohibited by applicable law notwithstanding the foregoing
|
||||
restriction, or to the extent as may be permitted by licensing terms governing the use of
|
||||
any open source software components or sample code contained within the SDK;
|
||||
3.1.7. You may not remove, obscure, or alter any proprietary rights or confidentiality notices
|
||||
within the SDK or any software, documentation, or other materials in it or supplied with
|
||||
it;
|
||||
3.1.8. You must not allow the Ultraleap Software or SDK to fall under the terms of any license
|
||||
which would obligate you or Ultraleap to make available or publish any part of the
|
||||
Ultraleap Software or SDK.
|
||||
3.1.9. You may not create Ultraleap Enabled Applications or other software that prevent or
|
||||
degrade the interaction of applications developed by others with the Ultraleap Software;
|
||||
3.1.10. You may not represent functionality provided by any Ultraleap hardware or software as
|
||||
your technology or the technology of any third party. For example (without limitation)
|
||||
you may not describe any application, technology, or feature developed or distributed
|
||||
by you that incorporates Ultraleap technology as your gesture or touchless control
|
||||
technology without providing attribution to Ultraleap; and
|
||||
3.1.11. You may not allow your Ultraleap Enabled Application to be used for a High Risk Use.
|
||||
4. Updates
|
||||
4.1. The terms of this Agreement will apply to any Updates which Ultraleap (in its sole discretion)
|
||||
makes available to you. You agree that Updates may require you to change or update your
|
||||
Ultraleap Enabled Application, and may affect your ability to use, access, or interact with the
|
||||
Ultraleap Software, the Ultraleap Hardware, and/or the SDK. You are solely responsible for
|
||||
turning off any auto-update functionality of the Ultraleap Software.
|
||||
5. Trademarks and Marketing
|
||||
5.1. Conditioned upon compliance with the terms and conditions of this Agreement, Ultraleap grants
|
||||
you a limited, non-exclusive, personal, license to reproduce and use Ultraleap trademarks solely
|
||||
to (a) mark the Ultraleap Enabled Application, (b) produce and make available related collateral,
|
||||
and (c) to promote and market your Ultraleap Enabled Application, in each case solely in
|
||||
accordance with the Ultraleap trademark guidelines that Ultraleap may provide to you from time
|
||||
to time.
|
||||
5.2. For so long as Ultraleap technology is included with the Ultraleap Enabled Application, you must
|
||||
identify on the packaging of the Ultraleap Enabled Application, the loading screen and start-up
|
||||
messages for the Ultraleap Enabled Application, and list on your website and marketing collateral
|
||||
(in each case, where applicable), as prominently as other listed features and functionality, that
|
||||
Ultraleap technology is included with the Ultraleap Enabled Application, in accordance with the
|
||||
Ultraleap trademark guidelines that Ultraleap may provide to you from time to time. All
|
||||
references to Ultraleap or Ultraleap Technology will be subject to Ultraleap’s prior approval,
|
||||
which will not be unreasonably withheld.
|
||||
5.3. Ultraleap may at its option mention you and your products using Ultraleap technology in
|
||||
Ultraleap’s press releases, press briefings, social media accounts, and/or website, and may use
|
||||
your trademarks for such purpose. You grant to Ultraleap and its affiliates a non-exclusive,
|
||||
worldwide and royalty-free limited license to use, reproduce, display, perform, publish and
|
||||
distribute screenshots, elements, assets, photographic, graphic or video reproductions or
|
||||
fragments of your Ultraleap Enabled Application in any medium or media, solely for purposes of
|
||||
promotion of your Ultraleap Enabled Application or of Ultraleap and its technology and business.
|
||||
The rights set out in this section 5.3 will survive termination of this Agreement in respect of
|
||||
materials already in existence as at the date of termination.
|
||||
6. EULA and Other Licenses
|
||||
6.1. Example code made publicly available by Ultraleap on its developer web site may be provided
|
||||
subject to the Apache 2.0 license, this Agreement, or other licenses, as specified in the notice or
|
||||
readme files distributed with the example or in related documentation. The SDK may otherwise
|
||||
include software or other materials that are provided under a separate license agreement, and
|
||||
that separate license will govern the use of such software or other materials in the event of a
|
||||
conflict with this Agreement. Any such separate license agreement may be indicated in the
|
||||
license, notice, or readme files distributed with the applicable software or other materials or in
|
||||
related documentation.
|
||||
6.2. You must either require end users of your Ultraleap Enabled Application to affirmatively agree to
|
||||
the Ultraleap EULA, or require its End Users to affirmatively agree to your own end user license
|
||||
agreement that protects Ultraleap at least as much as the Ultraleap EULA.
|
||||
7. High Risk Uses and Waiver
|
||||
7.1. Notwithstanding anything in this Agreement, you are not licensed to, and you agree not to, use,
|
||||
copy, sell, offer for sale, or distribute the SDK, Ultraleap Hardware, Ultraleap Software or
|
||||
Ultraleap Redistributables (whether compiled with, incorporated into, or packaged with your
|
||||
Ultraleap Enabled Application or otherwise), for or in connection with uses where failure or fault
|
||||
of the Ultraleap Hardware, Ultraleap Software, Ultraleap Redistributables or your Ultraleap
|
||||
Enabled Application could lead to death or serious bodily injury of any person, or to severe
|
||||
physical or environmental damage (“High Risk Use”). Any such use is strictly prohibited.
|
||||
7.2. You acknowledge the SDK may allow you to develop Ultraleap Enabled Applications that enable
|
||||
the control of motorized or mechanical equipment, or other systems, machines or devices. If you
|
||||
elect to use the SDK in such a way, you must take steps to design and test your Ultraleap Enabled
|
||||
Applications to ensure that your Ultraleap Enabled Applications do not present risks of personal
|
||||
injury or death, property damage, or other losses. The Ultraleap Hardware, the Ultraleap
|
||||
Software, the Ultraleap Redistributables and other software in the SDK may not always function
|
||||
as intended. You must design your Ultraleap Enabled Applications so that any failure of Ultraleap
|
||||
Technology and/or such other software as Ultraleap may make available from time to time does
|
||||
not cause personal injury or death, property damage, or other losses. If you choose to use the
|
||||
SDK, (i) you assume all risk that use of the Ultraleap Technology and/or such other software by
|
||||
you or by any others causes any harm or loss, including to the end users of your Ultraleap
|
||||
Enabled Applications or to third parties, (ii) you hereby waive, on behalf of yourself and your
|
||||
Authorized Users, all claims against Ultraleap and its affiliates related to such use, harm or loss
|
||||
(including, but not limited to, any claim that Ultraleap Technology or such other software is
|
||||
defective), and (iii) you agree to hold Ultraleap and its affiliates harmless from such claims.
|
||||
8. Confidentiality and Data Protection
|
||||
8.1. Beta Software etc. Obligations. You acknowledge and agree that Ultraleap may share alpha or
|
||||
beta software or hardware with you that it identifies as non-public. If so, you agree not to
|
||||
disclose such software or hardware to others without the prior written consent of Ultraleap
|
||||
until the time, if any, it is made public by Ultraleap, and to use such software or hardware only
|
||||
as expressly permitted by Ultraleap. Without limitation to the foregoing, the distribution license
|
||||
set out in section 2.2 shall not apply to any alpha or beta software which may be shared with
|
||||
you.
|
||||
8.2. Your Information. Ultraleap may collect personal information provided by you or your
|
||||
Authorized Users to Ultraleap or any group company of Ultraleap in connection with the SDK,
|
||||
and may collect other information from you or your Authorized Users, including technical, non-
|
||||
personally identifiable and/or aggregated information such as usage statistics, hardware
|
||||
configuration, problem / fault data, IP addresses, version number of the SDK, information about
|
||||
which tools and/or services in the SDK are being used and how they are being used, and any
|
||||
other information described in Ultraleap’s privacy policy, currently available at
|
||||
https://www.ultraleap.com/privacy-policy/. Ultraleap may use the information collected to
|
||||
facilitate the provision of Updates and other services to you, to verify compliance with, and
|
||||
enforce, the terms of this Agreement, to improve the SDK and Ultraleap’s other products, and
|
||||
for any other purposes set out in Ultraleap’s privacy policy (these uses, collectively, are
|
||||
“Permitted Uses”). The information collected may be transferred to, stored, and processed in a
|
||||
destination outside the European Economic Area, including (without limitation) by our staff in
|
||||
the USA, China, Japan, and Hong Kong. By submitting information about you and/or your
|
||||
Authorized Users to Ultraleap through your access and use of the SDK, you consent to
|
||||
Ultraleap’s collection and use of the information for the Permitted Uses and represent that you
|
||||
have obtained all consents and permits necessary under applicable law to disclose your
|
||||
Authorized Users’ information to Ultraleap for the Permitted Uses. You further agree that
|
||||
Ultraleap may provide any information collected under this Section 8.2, including your or your
|
||||
Authorized Users’ user name, IP address or other identifying information to law enforcement
|
||||
authorities or as required by applicable law or regulation.
|
||||
9. Ownership and Feedback
|
||||
9.1. As between you and Ultraleap, Ultraleap owns all right, title, and interest, including all
|
||||
intellectual property rights, in and to the SDK, the Ultraleap Software, Ultraleap Hardware, the
|
||||
Ultraleap Redistributables, and all documentation associated with the foregoing, other than any
|
||||
third party software or materials incorporated into the SDK. You agree not to contest Ultraleap’s
|
||||
ownership of any of the foregoing.
|
||||
9.2. Subject to Section 9.1, Ultraleap agrees that it obtains no right, title, or interest from you (or
|
||||
your licensors) under this Agreement in or to your Ultraleap Enabled Applications, including any
|
||||
intellectual property rights which subsist in those Ultraleap Enabled Applications.
|
||||
9.3. Feedback. You may (but are not required to) provide feedback, comments, and suggestions
|
||||
(collectively “Feedback”) to Ultraleap. You hereby grant to Ultraleap a non-exclusive, perpetual,
|
||||
irrevocable, paid-up, transferrable, sub-licensable, worldwide license under all intellectual
|
||||
property rights covering such Feedback to use, disclose, and exploit all such Feedback for any
|
||||
purpose.
|
||||
10. Your Obligations and Warranties
|
||||
In addition to your other obligations under this Agreement, you warrant and agree that:
|
||||
10.1. you are at least 18 years of age and have the right and authority to enter into this Agreement on
|
||||
your own behalf and that of your Authorized Users. If you are entering into this Agreement on
|
||||
behalf of your company or organization, you warrant that you have the right and authority to
|
||||
legally bind your company or organization and its Authorized Users;
|
||||
10.2. you will use the SDK only in accordance with all accompanying documentation, and in the
|
||||
manner expressly permitted by this Agreement; and
|
||||
10.3. your use of the SDK, and the marketing, sales and distribution of your Ultraleap Enabled
|
||||
Application, will be in compliance with all applicable laws and regulations and all UK, U.S. and
|
||||
local or foreign export and re-export restrictions applicable to the technology and
|
||||
documentation provided under this Agreement (including privacy and data security laws and
|
||||
regulations), and you will not develop any Ultraleap Enabled Application which would commit or
|
||||
facilitate the commission of a crime, or other tortious, unlawful, or illegal act.
|
||||
11. Agreement and Development Program
|
||||
11.1. We reserve the right to change this Agreement, the SDK or the Ultraleap development and
|
||||
licensing program at any time in our discretion. Ultraleap may require that you either accept
|
||||
and agree to the new terms of this Agreement, or, if you do not agree to the new terms, cease
|
||||
or terminate your use of the SDK. Your continued use of the SDK after changes to this
|
||||
Agreement take effect will constitute your acceptance of the changes. If you do not agree to a
|
||||
change, you must stop using the SDK and terminate this Agreement. Any termination of this
|
||||
Agreement by you under this Section 11 (and only this Section 11) will not affect your right,
|
||||
subject to your continued compliance with your obligations under this Agreement, to continue
|
||||
to distribute versions of your Ultraleap Enabled Application created and first distributed before
|
||||
termination, and will not affect the right of your End Users to continue using such versions of
|
||||
your Ultraleap Enabled Application, both of which rights will survive termination.
|
||||
12. Term and Termination
|
||||
12.1. Term. This Agreement will continue to apply until terminated by either you or Ultraleap as set
|
||||
out below.
|
||||
12.2. Termination by You. If you want to terminate this Agreement, you may terminate it by
|
||||
uninstalling and destroying all copies of the SDK that are in the possession, custody or control of
|
||||
you, your Authorized Users and your organization.
|
||||
12.3. Termination by Ultraleap. Ultraleap may at any time, terminate this Agreement with you for
|
||||
any reason or for no reason in Ultraleap’s sole discretion, including as a result of non-
|
||||
compliance by you with the restrictions in in this Agreement, or for other reasons.
|
||||
12.4. Effect of Termination. Upon termination of this Agreement, all rights granted to you under this
|
||||
Agreement will immediately terminate and you must immediately cease all use and destroy all
|
||||
copies of the SDK in your and your Authorized Users’ possession, custody or control, and, except
|
||||
as specifically set out in Section 11, cease your distribution of Ultraleap Enabled Applications.
|
||||
Sections 3, 8.1, 8.2, 9, 12.4, 14-16, and 17, will survive termination of this Agreement.
|
||||
Termination of this Agreement will not affect the right of your End Users who have downloaded
|
||||
your Ultraleap Enabled Application prior to termination to continue using it.
|
||||
13. Indemnification.
|
||||
13.1. You agree to indemnify, hold harmless and, at Ultraleap’s option, defend Ultraleap and its
|
||||
affiliates and their respective officers, directors, employees, agents, and representatives
|
||||
harmless from any and all judgments, awards, settlements, liabilities, damages, costs, penalties,
|
||||
fines and other expenses (including court costs and reasonable attorneys’ fees) incurred by
|
||||
them arising out of or relating to any third party claim (a) with respect to your Ultraleap Enabled
|
||||
Application, including products liability, privacy, or intellectual property infringement claims, or
|
||||
(b) based upon your negligence or wilful misconduct or any breach or alleged breach of your
|
||||
representations, warranties, and covenants under this Agreement. In no event may you enter
|
||||
into any settlement or like agreement with a third party that affects Ultraleap’s rights or binds
|
||||
Ultraleap or its affiliates in any way, without the prior written consent of Ultraleap.
|
||||
14. Warranty Disclaimer.
|
||||
14.1. THE SDK, THE ULTRALEAP SOFTWARE AND THE ULTRALEAP REDISTRIBUTABLES ARE PROVIDED
|
||||
"AS IS" WITHOUT WARRANTY OF ANY KIND. ULTRALEAP, ON BEHALF OF ITSELF AND ITS
|
||||
SUPPLIERS, HEREBY DISCLAIMS ALL REPRESENTATIONS, PROMISES, OR WARRANTIES, WHETHER
|
||||
EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO THE SDK, THE ULTRALEAP
|
||||
SOFTWARE AND THE ULTRALEAP REDISTRIBUTABLES, INCLUDING THEIR CONDITION,
|
||||
AVAILABILITY, OR THE EXISTENCE OF ANY LATENT DEFECTS, AND ULTRALEAP SPECIFICALLY
|
||||
DISCLAIMS ALL IMPLIED WARRANTIES OF MERCHANTABILITY, TITLE, NONINFRINGEMENT,
|
||||
SUITABILITY, AND FITNESS FOR ANY PURPOSE. ULTRALEAP DOES NOT WARRANT THAT THE SDK,
|
||||
THE ULTRALEAP SOFTWARE OR THE ULTALEAP REDISTRIBUTABLES WILL BE ERROR-FREE OR
|
||||
THAT THEY WILL WORK WITHOUT INTERRUPTION.
|
||||
15. Limitation of Liability.
|
||||
15.1. ULTRALEAP SHALL NOT IN ANY CIRCUMSTANCES WHATEVER BE LIABLE TO YOU, WHETHER IN
|
||||
CONTRACT, TORT (INCLUDING NEGLIGENCE), BREACH OF STATUTORY DUTY, OR OTHERWISE,
|
||||
ARISING UNDER OR IN CONNECTION WITH THE AGREEMENT FOR:
|
||||
15.1.1. LOSS OF PROFITS, SALES, BUSINESS, OR REVENUE;
|
||||
15.1.2. BUSINESS INTERRUPTION;
|
||||
15.1.3. LOSS OF ANTICIPATED SAVINGS;
|
||||
15.1.4. LOSS OR CORRUPTION OF DATA OR INFORMATION;
|
||||
15.1.5. LOSS OF BUSINESS OPPORTUNITY, GOODWILL OR REPUTATION; OR
|
||||
15.1.6. ANY INDIRECT OR CONSEQUENTIAL LOSS OR DAMAGE.
|
||||
15.2. OTHER THAN THE LOSSES SET OUT ABOVE (FOR WHICH ULTRALEAP IS NOT LIABLE),
|
||||
ULTRALEAP’S MAXIMUM AGGREGATE LIABILITY UNDER OR IN CONNECTION WITH THE
|
||||
AGREEMENT WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE), BREACH OF STATUTORY
|
||||
DUTY, OR OTHERWISE, SHALL IN ALL CIRCUMSTANCES BE LIMITED TO $1,000 (ONE THOUSAND
|
||||
US DOLLARS). THIS MAXIMUM CAP DOES NOT APPLY TO DEATH OR PERSONAL INJURY
|
||||
RESULTING FROM ULTRALEAP'S NEGLIGENCE; FRAUD OR FRAUDULENT MISREPRESENTATION;
|
||||
OR ANY OTHER LIABILITY THAT CANNOT BE EXCLUDED OR LIMITED BY APPLICABLE LAW.
|
||||
15.3. THE AGREEMENT SETS OUT THE FULL EXTENT OF ULTRALEAP’S OBLIGATIONS AND LIABILITIES IN
|
||||
RESPECT OF THE SUPPLY OF THE ULTRALEAP DEVICES, DELIVERABLES AND SOFTWARE. EXCEPT
|
||||
AS EXPRESSLY STATED IN THE AGREEMENT, THERE ARE NO CONDITIONS, WARRANTIES,
|
||||
REPRESENTATIONS OR OTHER TERMS, EXPRESS OR IMPLIED, THAT ARE BINDING ON
|
||||
ULTRALEAP. ANY CONDITION, WARRANTY, REPRESENTATION OR OTHER TERM CONCERNING
|
||||
THE SUPPLY OF THE ULTRALEAP HARDWARE, ULTRALEAP SOFTWARE, THE SDK, THE ULTRALEAP
|
||||
REDISTRIBUTABLES, OR ANY OTHER ULTRALEAP TECHNOLOGY WHICH MIGHT OTHERWISE BE
|
||||
IMPLIED INTO, OR INCORPORATED IN THE AGREEMENT WHETHER BY STATUTE, COMMON LAW
|
||||
OR OTHERWISE, INCLUDING ANY WARRANTY OR CONDITION OF MERCHANTABILITY OR FITNESS
|
||||
FOR A PARTICULAR PURPOSE, IS EXCLUDED TO THE FULLEST EXTENT PERMITTED BY LAW. THESE
|
||||
LIMITATIONS WILL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ANY
|
||||
LIMITED REMEDY. THE PARTIES AGREE THAT THE FOREGOING LIMITATIONS REPRESENT A
|
||||
REASONABLE ALLOCATION OF RISK UNDER THIS AGREEMENT.
|
||||
16. Miscellaneous.
|
||||
16.1. Assignment. You may not assign this Agreement without the prior written consent of Ultraleap.
|
||||
Any assignment without such consent is void and of no effect. Ultraleap may assign this
|
||||
Agreement without your consent in connection with (a) a merger or consolidation of Ultraleap,
|
||||
(b) a sale or assignment of substantially all its assets, or (c) any other transaction which results
|
||||
in another entity or person owning substantially all of the assets of Ultraleap, or (d) to any of its
|
||||
affiliates. In the event of a permitted assignment, this Agreement will inure to the benefit of and
|
||||
be binding upon the parties and their respective successors and permitted assigns.
|
||||
16.2. Waiver; Severability. The failure of the other party to enforce any rights under this Agreement
|
||||
will not be deemed a waiver of any rights. The rights and remedies of the parties in this
|
||||
Agreement are not exclusive and are in addition to any other rights and remedies provided by
|
||||
law. If any provision of this Agreement is held by a court of competent jurisdiction to be
|
||||
contrary to law, the remaining provisions of this Agreement will remain in full force and effect.
|
||||
16.3. Reservation. All licenses not expressly granted in this Agreement are reserved and no other
|
||||
licenses, immunity or rights, express or implied, are granted by Ultraleap, by implication,
|
||||
estoppel, or otherwise. The software in the SDK is licensed, not sold.
|
||||
16.4. Export Restrictions. The Ultraleap Software is subject to United States and UK export laws and
|
||||
regulations. You must comply with all domestic and international export laws and regulations
|
||||
that apply to the Ultraleap Software. These laws include restrictions on destinations, end users,
|
||||
and end use.
|
||||
16.5. Governing Law and Jurisdiction. This Agreement will be exclusively governed by and construed
|
||||
under the laws of the England and Wales, without reference to or application of rules governing
|
||||
choice of laws. All disputes arising out of or related to this Agreement will be subject to the
|
||||
exclusive jurisdiction of courts of England and you hereby consent to such jurisdiction. However,
|
||||
Ultraleap may apply to any court or tribunal worldwide, including but not limited to those
|
||||
having jurisdiction over you or your Authorized Users, to seek injunctive relief.
|
||||
16.6. Relationship of the Parties. This Agreement does not create any agency, partnership, or joint
|
||||
venture relationship between Ultraleap and you. This Agreement is for the sole benefit of
|
||||
Ultraleap and you (and indemnified parties), and no other persons will have any right or remedy
|
||||
under this Agreement.
|
||||
16.7. Notices. The address for notice to Ultraleap under this Agreement is:
|
||||
Ultraleap Limited
|
||||
The West Wing
|
||||
Glass Wharf
|
||||
Bristol, BS2 0EL
|
||||
United Kingdom
|
||||
Ultraleap may provide you notice under this Agreement by email or other electronic
|
||||
communication or by posting communications to its development community on the Ultraleap
|
||||
developer portal. You consent to receive such notices in any of the foregoing manners and
|
||||
agree that any such notices by Ultraleap will satisfy any legal communication requirements.
|
||||
16.8. Entire Agreement. This Agreement is the entire understanding of the parties with respect to its
|
||||
subject matter and supersedes any previous or contemporaneous communications, whether
|
||||
oral or written with respect to such subject matter.
|
||||
17. Definitions
|
||||
Whenever capitalized in this Agreement:
|
||||
“Authorized Users” means your employees and contractors, members of your organization or, if you
|
||||
are an educational institution, your faculty, staff and registered students, who (a) have a
|
||||
demonstrable need to know or use the SDK in order to develop and test Ultraleap Enabled
|
||||
Applications on your behalf and (b) each have written and binding agreements with you to protect
|
||||
against the unauthorized use and disclosure of the SDK consistent with the terms and conditions of
|
||||
this Agreement. Authorized Users do not include End Users.
|
||||
“End User” means your end user customer(s) or licensee(s).
|
||||
“Non-Redistributable Materials” means the Ultraleap Software, and any other code, files or
|
||||
materials that are not specifically designated in the SDK as made available for incorporation into
|
||||
Ultraleap Enabled Applications or that are specifically designated in the SDK as not subject to
|
||||
distribution.
|
||||
“SDK” means, collectively, the Ultraleap Redistributables, tools, APIs, sample code, software,
|
||||
documentation, other materials and any updates to the foregoing that may be provided or made
|
||||
available to you by Ultraleap in connection with this Agreement, via the Ultraleap developer portal or
|
||||
otherwise for use in connection with the Ultraleap development program to develop Ultraleap
|
||||
Enabled Applications.
|
||||
“Specialized Application” means an Ultraleap Enabled Application which does not fall within the
|
||||
permitted uses set out in this Agreement.
|
||||
“Ultraleap” “we” or “us” means Ultraleap Limited, a company registered in England with company
|
||||
number 08781720, with a principal place of business at The West Wing, Glass Wharf, Bristol, BS2 0EL,
|
||||
United Kingdom.
|
||||
“Ultraleap Hardware” means the Leap Motion Controller or Stereo IR 170, each being a device that
|
||||
detects and reads movements within a 3-D interaction space to precisely interact with and control
|
||||
software on a computing device, or an Ultraleap-authorized embedded optical module.
|
||||
“Ultraleap Redistributables” means any .lib code, .dll files, .so files, sample code, or other materials
|
||||
we specifically designate in the SDK as made available for incorporation into or distribution with
|
||||
Ultraleap Enabled Applications.
|
||||
“Ultraleap Software” means the Ultraleap core services application and related applications that
|
||||
interact with Ultraleap Hardware and an operating system to make motion control functionality
|
||||
available to Ultraleap Enabled Applications, and includes any Updates thereto.
|
||||
“Updates” means updates, upgrades, modifications, enhancements, revisions, new releases or new
|
||||
versions to the SDK that Ultraleap may make available to you in connection with this Agreement.
|
||||
Other capitalized terms used in this Agreement have the meaning given them elsewhere in this
|
||||
Agreement.
|
||||
18. Supplemental Terms Applicable to the Use of Image API
|
||||
18.1. Purpose. You and/or your Ultraleap Enabled Application may access the Image API and use
|
||||
image data available through the Image API only for the purpose of developing and testing
|
||||
Ultraleap Enabled Applications, and only for use with Ultraleap Hardware. You may not use the
|
||||
Image API to develop or aid development of competing motion tracking hardware or software.
|
||||
Any use of the Image API is subject to the terms of the Agreement.
|
||||
18.2. Data Protection.
|
||||
18.2.1. If you or your Ultraleap Enabled Application collects, uploads, stores, transmits, or
|
||||
shares images, videos, or other personal information available through the Image API,
|
||||
either through or in connection with your Ultraleap Enabled Application, you must
|
||||
expressly provide users with your privacy policy and adhere to it.
|
||||
18.2.2. You must obtain specific, opt-in consent from the user for any use that is beyond the
|
||||
limited and express purpose of your Ultraleap Enabled Application.
|
||||
18.2.3. You and your Ultraleap Enabled Application must use and store information collected
|
||||
form users securely and only for as long as it is required.
|
||||
18.2.4. You agree that you will protect the privacy and legal rights of users, and will comply with
|
||||
all applicable criminal, civil, and statutory privacy and data protection laws and
|
||||
regulations.
|
92
ml_lme_cvr/vendor/LeapSDK/README.md
vendored
Normal file
92
ml_lme_cvr/vendor/LeapSDK/README.md
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
# Ultraleap SDK
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## Package contents:
|
||||
|
||||
LeapSDK
|
||||
- docs
|
||||
* API reference documentation & guidelines.
|
||||
- include
|
||||
* API headers.
|
||||
- lib
|
||||
* dynamic API library and CMake scripts.
|
||||
- samples
|
||||
* Various samples demonstrating several different usages.
|
||||
- LICENSE.md
|
||||
* Ultraleap Tracking SDK license.
|
||||
- Uninstall.exe
|
||||
* Program to uninstall the LeapSDK application.
|
||||
|
||||
## Requirements:
|
||||
|
||||
1. Running requires
|
||||
* Ultraleap Tracking Software https://developer.leapmotion.com/get-started/
|
||||
|
||||
2. Building Samples requires
|
||||
* CMake 3.16.3+ (https://cmake.org/)
|
||||
* Microsoft Visual Studio 15+
|
||||
|
||||
## Installation:
|
||||
|
||||
1. Execute the LeapSDK installer.
|
||||
|
||||
2. Choose a suitable destination location on your computer.
|
||||
|
||||
3. Read and accept the Ultraleap Tracking SDK Agreement to use the Ultraleap SDK.
|
||||
|
||||
## Usage:
|
||||
|
||||
1. For CMake projects
|
||||
* Ensure LeapSDK is in a directory considered as a prefix by find_package.
|
||||
(https://cmake.org/cmake/help/v3.16/command/find_package.html)
|
||||
* Or : directly set LeapSDK_DIR to <install_dir>/LeapSDK/lib/cmake/LeapSDK
|
||||
* Or : Pass the LeapSDK's path to find_package with the PATHS option.
|
||||
* call find_package(LeapSDK 5 [PATHS ...]).
|
||||
* call target_link_libraries(<your project> PUBLIC|PRIVATE LeapSDK::LeapC).
|
||||
* Ensure LeapC.dll is in your dynamic library search path.
|
||||
* A popular option is to add a post-build step that copies it to your project's output directory.
|
||||
|
||||
2. For non-CMake projects
|
||||
* Use a C/C++ compiler such as MSVC, Clang or GCC.
|
||||
* Add LeapSDK/include to the compiler include search paths.
|
||||
* Either add a linker reference to LeapC.lib or dynamically load LeapC.dll.
|
||||
|
||||
## Building Samples:
|
||||
|
||||
1. Open CMake using LeapSDK/samples as the source directory
|
||||
|
||||
2. Select a build directory (often LeapSDK/samples/build) to use
|
||||
|
||||
3. Configure & Generate CMake with the generator of your choice
|
||||
* An example script would be :
|
||||
```powershell
|
||||
$env:BUILD_TYPE = 'Release'
|
||||
$env:REPOS_BUILD_ROOT = 'C:/build'
|
||||
$env:REPOS_INSTALL_ROOT = 'C:/Program Files'
|
||||
|
||||
cmake -j -S "C:/Program Files/Ultraleap/LeapSDK/samples" -B $env:REPOS_BUILD_ROOT/$env:BUILD_TYPE/LeapSDK/leapc_example `
|
||||
-DCMAKE_INSTALL_PREFIX="$env:REPOS_INSTALL_ROOT/leapc_example" `
|
||||
-DCMAKE_BUILD_TYPE="$env:BUILD_TYPE"
|
||||
|
||||
cmake --build $env:REPOS_BUILD_ROOT/$env:BUILD_TYPE/LeapSDK/leapc_example -j --config $env:BUILD_TYPE
|
||||
```
|
||||
|
||||
4. Open and build the CMake generated project files. For more help, see the CMake documentation.
|
||||
|
||||
## Resources:
|
||||
|
||||
1. Ultraleap For Developers Site (https://developer.leapmotion.com)
|
||||
provides examples, community forums, Ultraleap news, and documentation
|
||||
to help you to learn how to develop applications using the Ultraleap Tracking
|
||||
SDK.
|
||||
|
||||
2. C# and Unity bindings (https://github.com/leapmotion/UnityModules)
|
||||
|
||||
3. C++ bindings matching the old API (https://github.com/leapmotion/LeapCxx)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Copyright © 2012-2020 Ultraleap Ltd. All rights reserved.
|
||||
|
||||
Use subject to the terms of the Ultraleap Tracking SDK Agreement `LICENSE.md` next to this `README.md` file.
|
5292
ml_lme_cvr/vendor/LeapSDK/ThirdPartyNotices.md
vendored
Normal file
5292
ml_lme_cvr/vendor/LeapSDK/ThirdPartyNotices.md
vendored
Normal file
File diff suppressed because it is too large
Load diff
32
ml_lme_cvr/vendor/LeapSDK/lib/x64/LICENSE.protobuf
vendored
Normal file
32
ml_lme_cvr/vendor/LeapSDK/lib/x64/LICENSE.protobuf
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
Copyright 2008 Google Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Code generated by the Protocol Buffer compiler is owned by the owner
|
||||
of the input file used when generating it. This code is not
|
||||
standalone and requires a support library to be linked with it. This
|
||||
support library is itself covered by the above license.
|
BIN
ml_lme_cvr/vendor/LeapSDK/lib/x64/LeapC.dll
vendored
Normal file
BIN
ml_lme_cvr/vendor/LeapSDK/lib/x64/LeapC.dll
vendored
Normal file
Binary file not shown.
BIN
ml_lme_cvr/vendor/LeapSDK/lib/x64/LeapC.lib
vendored
Normal file
BIN
ml_lme_cvr/vendor/LeapSDK/lib/x64/LeapC.lib
vendored
Normal file
Binary file not shown.
25
ml_mods_cvr.sln
Normal file
25
ml_mods_cvr.sln
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28307.1738
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ml_lme_cvr", "ml_lme_cvr\ml_lme_cvr.csproj", "{83CC74B7-F444-40E1-BD06-67CEC995A919}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{83CC74B7-F444-40E1-BD06-67CEC995A919}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{83CC74B7-F444-40E1-BD06-67CEC995A919}.Debug|x64.Build.0 = Debug|x64
|
||||
{83CC74B7-F444-40E1-BD06-67CEC995A919}.Release|x64.ActiveCfg = Release|x64
|
||||
{83CC74B7-F444-40E1-BD06-67CEC995A919}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C7C6398E-220C-40C3-AE95-5690C9B2B3C3}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
Loading…
Add table
Add a link
Reference in a new issue