2022-03-07 16:33:30 +00:00
|
|
|
using System.Collections;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using UnityEngine;
|
|
|
|
using UnityEngine.XR;
|
|
|
|
using UnityEngine.XR.Interaction.Toolkit;
|
|
|
|
using PDollarGestureRecognizer;
|
|
|
|
using System.IO;
|
|
|
|
using UnityEngine.Events;
|
|
|
|
|
|
|
|
public class GestureRecognizer : MonoBehaviour
|
|
|
|
{
|
2022-03-24 20:50:55 +00:00
|
|
|
//public InputDevice rightHandController;
|
2022-03-07 16:33:30 +00:00
|
|
|
public XRNode rightHandSource;
|
|
|
|
public InputHelpers.Button rightInputButton;
|
|
|
|
public InputHelpers.Button rightControlButton;
|
|
|
|
|
|
|
|
public float inputThreshold = 0.1f;
|
|
|
|
public Transform movementSource;
|
|
|
|
|
|
|
|
public float newPositionThresholdDistance = 0.05f;
|
|
|
|
public GameObject debugCubePrefab;
|
|
|
|
public bool creationMode = true;
|
|
|
|
public string newGestureName;
|
|
|
|
|
|
|
|
public float recognitionThreshold = 0.8f;
|
|
|
|
|
|
|
|
[System.Serializable]
|
|
|
|
public class UnityStringEvent : UnityEvent<string> { }
|
|
|
|
public UnityStringEvent OnRecognized;
|
|
|
|
|
|
|
|
private List<Gesture> trainingSet = new List<Gesture>();
|
|
|
|
private bool isMoving = false;
|
|
|
|
private List<Vector3> positionsList = new List<Vector3>();
|
|
|
|
|
|
|
|
// Start is called before the first frame update
|
|
|
|
void Start()
|
|
|
|
{
|
|
|
|
// Path = ..\AppData\LocalLow\DefaultCompany\Heroes of Hiis SCM
|
|
|
|
Debug.Log(Application.persistentDataPath);
|
|
|
|
string[] gestureFiles = Directory.GetFiles(Application.persistentDataPath, "*.xml");
|
|
|
|
foreach (var item in gestureFiles)
|
|
|
|
{
|
|
|
|
trainingSet.Add(GestureIO.ReadGestureFromFile(item));
|
|
|
|
}
|
|
|
|
foreach (var item in trainingSet)
|
|
|
|
{
|
|
|
|
Debug.Log(item.Name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update is called once per frame
|
|
|
|
void Update()
|
|
|
|
{
|
|
|
|
InputHelpers.IsPressed(InputDevices.GetDeviceAtXRNode(rightHandSource), rightInputButton, out bool isPressed, inputThreshold);
|
|
|
|
InputHelpers.IsPressed(InputDevices.GetDeviceAtXRNode(rightHandSource), rightControlButton, out bool isControlPressed, inputThreshold);
|
|
|
|
|
|
|
|
bool startGesture = isPressed && isControlPressed;
|
|
|
|
|
|
|
|
// Start the movement
|
|
|
|
if (!isMoving && startGesture)
|
|
|
|
{
|
|
|
|
StartMovement();
|
2022-03-24 20:50:55 +00:00
|
|
|
//StartCoroutine("Haptics");
|
2022-03-07 16:33:30 +00:00
|
|
|
}
|
|
|
|
// Ending the movement
|
|
|
|
else if (isMoving && !startGesture)
|
|
|
|
{
|
|
|
|
EndMovement();
|
2022-03-24 20:50:55 +00:00
|
|
|
//StopCoroutine("Haptics");
|
2022-03-07 16:33:30 +00:00
|
|
|
}
|
|
|
|
// Updating the movement
|
|
|
|
else if (isMoving && startGesture)
|
|
|
|
{
|
|
|
|
UpdateMovement();
|
|
|
|
}
|
|
|
|
}
|
2022-03-24 16:02:34 +00:00
|
|
|
// Still needs to be tested
|
2022-03-24 20:50:55 +00:00
|
|
|
//IEnumerator Haptics()
|
|
|
|
//{
|
|
|
|
// while (true)
|
|
|
|
// {
|
|
|
|
// rightHandController.SendHapticImpulse(0u, 0.7f, 0.2f);
|
|
|
|
// }
|
|
|
|
//}
|
2022-03-07 16:33:30 +00:00
|
|
|
|
|
|
|
void StartMovement()
|
|
|
|
{
|
|
|
|
Debug.Log("Movement started");
|
|
|
|
isMoving = true;
|
|
|
|
positionsList.Clear();
|
|
|
|
positionsList.Add(movementSource.position);
|
|
|
|
if (debugCubePrefab)
|
|
|
|
{
|
|
|
|
Destroy(Instantiate(debugCubePrefab, movementSource.position, Quaternion.identity), 3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void EndMovement()
|
|
|
|
{
|
|
|
|
Debug.Log("Movement ended");
|
|
|
|
isMoving = false;
|
|
|
|
|
|
|
|
// Create gesture from position list
|
|
|
|
Point[] pointArray = new Point[positionsList.Count];
|
|
|
|
for (int i = 0; i < positionsList.Count; i++)
|
|
|
|
{
|
|
|
|
Vector2 screenPoint = Camera.main.WorldToScreenPoint(positionsList[i]);
|
|
|
|
pointArray[i] = new Point(screenPoint.x, screenPoint.y, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
Gesture newGesture = new Gesture(pointArray);
|
|
|
|
|
|
|
|
// Add gesture to training set. (only for demo)
|
|
|
|
if (creationMode)
|
|
|
|
{
|
|
|
|
newGesture.Name = newGestureName;
|
|
|
|
trainingSet.Add(newGesture);
|
|
|
|
|
|
|
|
string fileName = Application.persistentDataPath + "/" + newGestureName + ".xml";
|
|
|
|
GestureIO.WriteGesture(pointArray, newGestureName, fileName);
|
|
|
|
}
|
|
|
|
// Recognize
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Result result = PointCloudRecognizer.Classify(newGesture, trainingSet.ToArray());
|
|
|
|
|
|
|
|
if (result.Score > recognitionThreshold)
|
|
|
|
{
|
|
|
|
OnRecognized.Invoke(result.GestureClass);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateMovement()
|
|
|
|
{
|
|
|
|
Vector3 lastPosition = positionsList[positionsList.Count - 1];
|
|
|
|
if (Vector3.Distance(movementSource.position, lastPosition) > newPositionThresholdDistance)
|
|
|
|
{
|
|
|
|
positionsList.Add(movementSource.position);
|
|
|
|
if (debugCubePrefab)
|
|
|
|
{
|
|
|
|
Destroy(Instantiate(debugCubePrefab, movementSource.position, Quaternion.identity), 3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|