Heroes_of_Hiis/Assets/Project Files/Scripts/JonasB/GestureRecognizer.cs

137 lines
4.1 KiB
C#

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
{
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();
}
// Ending the movement
else if (isMoving && !startGesture)
{
EndMovement();
}
// Updating the movement
else if (isMoving && startGesture)
{
UpdateMovement();
}
}
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);
}
}
}
}