Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
LiveComparer.cs 4.30 KiB
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Leap;
using Leap.Unity;

public class LiveComparer : MonoBehaviour
{
	public GameObject frameScoreLabel = null;
	public GameObject totalScoreLabel = null;
	public Replay replay = null;
	public LeapServiceProvider LeapService = null;
	public float scoreOffset = 70.0f;
	public GameObject backgroundCircle = null;
	public int backGroundAngleOffset = 60;

	float acceptableScore = 150.0f;
	float totalScore = 0.0f;
	float frameScore = 0.0f;
	float sumScore = 0.0f;
	int lastFrame = -1;
	Vector3 leftPalmPosition = Vector3.zero;
	Vector4 leftPalmRotation = Vector3.zero;
	Vector3 rightPalmPosition = Vector3.zero;
	Vector4 rightPalmRotation = Vector3.zero;

	Vector3 offsetPosition = Vector3.zero;

	public void ResetScore()
	{
		//acceptableScore = frameScore - 1.0f;
		totalScore = 0.0f;
		frameScore = 0.0f;
		sumScore = 0.0f;
	}

	void Update ()
	{
		FetchPalmsCoordinates ();
		UpdateCircleRotation ();
		if (replay.currentFrame >= 0 && replay.currentFrame < 100)
		{
			if (replay.currentFrame == 0)
				UpdateOffsetPosition ();
			
			ComputeFrameScore ();

			if (replay.currentFrame != lastFrame)
			{
				lastFrame = replay.currentFrame;
				ComputeTotalScore ();
			}

			UpdateScoreLabels ();
		}
	}

	void UpdateCircleRotation ()
	{
		Vector4 rotOffs = replay.gestureToReplay.states [0].rotation;
		Vector4 rotCircle = leftPalmRotation - rotOffs;

		backgroundCircle.transform.rotation = new Quaternion(0, 0, 0, rotCircle.w);
		backgroundCircle.transform.Rotate(new Vector3(270, 0, 0)); //circle facing camera

		float degreesX = rotCircle.x * 360 / 3.14f;
		//float degreesY = rotCircle.y * 360 / 3.14f;
		//float degreesZ = rotCircle.z * 360 / 3.14f;
		backgroundCircle.transform.Rotate(new Vector3(0, degreesX, 0)); //angle from leap hand
		backgroundCircle.transform.Rotate(new Vector3(0, -backGroundAngleOffset, 0)); //offset for target
	}

	void UpdateOffsetPosition ()
	{
		offsetPosition = replay.gestureToReplay.states [replay.currentFrame].position - leftPalmPosition;
	}

	void ComputeFrameScore()
	{
		//for now we only consider the left hand
		frameScore = scoreOffset;
		float scoreFactor = 100.0f;

		Vector3 differencePosition = offsetPosition + leftPalmPosition - replay.gestureToReplay.states [replay.currentFrame].position;
		Vector4 differenceRotation = leftPalmRotation - replay.gestureToReplay.states [replay.currentFrame].rotation;
		Vector3 variancePosition = replay.gestureVariance.states [replay.currentFrame].position;
		Vector4 varianceRotation = replay.gestureVariance.states [replay.currentFrame].rotation;

		float scorePosition = variancePosition.magnitude - differencePosition.magnitude;
		float scoreRotation = varianceRotation.magnitude - differenceRotation.magnitude;

		frameScore += (scorePosition + scoreRotation) * scoreFactor;
	}

	void ComputeTotalScore()
	{
		sumScore += frameScore;
		if (replay.currentFrame != 0)
			totalScore = sumScore / (replay.currentFrame);
		else
			totalScore = 0;
	}

	void FetchPalmsCoordinates()
	{
		Frame frame = LeapService.CurrentFrame;
		foreach (Hand hand in frame.Hands)
		{
			if (hand.IsLeft)
			{
				leftPalmPosition = hand.PalmPosition.ToVector3 ();
				leftPalmRotation = new Vector3(hand.Rotation.x, hand.Rotation.y, hand.Rotation.z);
			}
			else
			{
				rightPalmPosition = hand.PalmPosition.ToVector3();
				rightPalmRotation = new Vector4(hand.Rotation.x, hand.Rotation.y, hand.Rotation.z, hand.Rotation.w);
			}
		}
	}

	void UpdateScoreLabels()
	{
		frameScoreLabel.GetComponent<Text> ().text = "frame score: " + frameScore.ToString ();
		totalScoreLabel.GetComponent<Text> ().text = "total score: " + totalScore.ToString ();

		if (replay.currentFrame == 0)
		{
			frameScoreLabel.GetComponent<Text> ().color = new Color (0.0f, 0.0f, 0.0f);
			totalScoreLabel.GetComponent<Text> ().color = new Color (0.0f, 0.0f, 0.0f);
		}
		else
		{
			//Debug.Log ("[UpdateScoreLabels] acc: " + acceptableScore);
			if (frameScore > 0)
				frameScoreLabel.GetComponent<Text> ().color = new Color (0.0f, 0.7f, 0.0f);
			else
				frameScoreLabel.GetComponent<Text> ().color = new Color (0.7f, 0.0f, 0.0f);
			if (totalScore > 0)
				totalScoreLabel.GetComponent<Text> ().color = new Color (0.0f, 0.7f, 0.0f);
			else
				totalScoreLabel.GetComponent<Text> ().color = new Color (0.7f, 0.0f, 0.0f);
		}
	}
}