Commit 3958d258 authored by 16이상민's avatar 16이상민

Refactoring class 'TrackManager' and 'MotionView'.

parent b5ddc19c
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Windows.Kinect;
using System.Linq;
public class MotionView : MonoBehaviour {
Pair<float, MotionState> _Recent;
public GameObject CoordinateMapperManager;
CoordinateMapperManager _coordinateMapperManager;
KinectModule.IBody[] body;
CameraSpacePoint spineMidRecent,
handLeftRecent,
handRightRecent,
kneeLeftBase,
kneeRightBase;
bool IsInitialized;
public Pair<float, MotionState> Recent
{ get { return _Recent; } }
public class MotionView : MonoBehaviour
{
IEnumerable<KinectModule.IBody> body;
MotionDiscriminator discriminator = new MotionDiscriminator();
// Use this for initialization
void Start ()
{
_Recent = new Pair<float, MotionState>
{
first = 0,
second = MotionState.UNKNOWN
};
if(CoordinateMapperManager == null)
return;
_coordinateMapperManager
= CoordinateMapperManager.GetComponent<CoordinateMapperManager>();
body = _coordinateMapperManager.BodyBuffer;
IsInitialized = false;
body = GameObject.Find("Managers").GetComponent<CoordinateMapperManager>().BodyBuffer;
discriminator.Preset(body.ToList()[0]);
}
// Update is called once per frame
void Update ()
{
_Recent.first += Time.deltaTime;
_Recent.second = DetermineState();
InputManager.Instance.CurrentMotionState = _Recent.second;
InputManager.Instance.CurrentMotionState = DetermineState();
}
MotionState DetermineState()
{
if (body == null)
{
IsInitialized = false;
return MotionState.UNKNOWN;
}
int idx;
for(idx = 0; idx < body.Length; ++idx)
if (body[idx] != null && body[idx].IsTracked)
break;
if(idx == body.Length || body[idx].Joints == null)
return MotionState.UNKNOWN;
if (!IsInitialized)
{
kneeLeftBase = body[idx].Joints[JointType.KneeLeft ].Position;
kneeRightBase = body[idx].Joints[JointType.KneeRight].Position;
}
IsInitialized = true;
CameraSpacePoint head = body[idx].Joints[JointType.Head ].Position,
handLeft = body[idx].Joints[JointType.HandLeft ].Position,
handRight = body[idx].Joints[JointType.HandRight ].Position,
spineShoulder = body[idx].Joints[JointType.SpineShoulder].Position,
spineMid = body[idx].Joints[JointType.SpineMid ].Position,
elbowLeft = body[idx].Joints[JointType.ElbowLeft ].Position,
elbowRight = body[idx].Joints[JointType.ElbowRight ].Position,
kneeLeft = body[idx].Joints[JointType.KneeLeft ].Position,
kneeRight = body[idx].Joints[JointType.KneeRight ].Position;
MotionState s = MotionState.UNKNOWN;
// Clap
if (Distance(handLeft, handRight) > 0.3f
&& spineShoulder.Y < handLeft.Y && spineShoulder.Y < handRight.Y)
s |= MotionState.CLAP_PREPARE;
if (Distance(handLeft, handRight) < 0.1f
&& spineShoulder.Y < handLeft.Y && spineShoulder.Y < handRight.Y)
s |= MotionState.CLAP_DONE;
// Jump
if (spineMid.Y - spineMidRecent.Y < 0.05f)
s |= MotionState.JUMP_PREPARE;
if (spineMid.Y > spineMidRecent.Y)
s |= MotionState.JUMP_DONE;
// Push Up
if (head.Y < handLeft.Y && head.Y < handRight.Y)
s |= MotionState.HURRAY;
if (handLeft.Y - handLeftRecent.Y > 0)
s |= MotionState.HAND_MOVE_UP_LEFT;
if (handLeft.Y - handLeftRecent.Y < 0)
s |= MotionState.HAND_MOVE_DOWN_LEFT;
if (handRight.Y - handRightRecent.Y > 0)
s |= MotionState.HAND_MOVE_UP_RIGHT;
if (handRight.Y - handRightRecent.Y < 0)
s |= MotionState.HAND_MOVE_DOWN_RIGHT;
// Guard
if (handLeft.Y > elbowLeft.Y
&& Mathf.Abs(elbowLeft.X - spineMid.X) < 0.5f)
s |= MotionState.GUARD_BASE_LEFT;
if (handRight.Y > elbowRight.Y
&& Mathf.Abs(elbowRight.X - spineMid.X) < 0.5f)
s |= MotionState.GUARD_BASE_RIGHT;
// Hand Up
if (handLeft.Y - head.Y > 0.2)
s |= MotionState.HAND_UP_LEFT;
if (handRight.Y - head.Y > 0.2)
s |= MotionState.HAND_UP_RIGHT;
// Hand Down
if (handLeft.Y < spineMid.Y)
s |= MotionState.HAND_DOWN_LEFT;
if (handRight.Y > spineMid.Y)
s |= MotionState.HAND_DOWN_RIGHT;
// Jesus
if (Mathf.Min(handLeft.Y, handRight.Y) > spineShoulder.Y
&& Mathf.Abs(handLeft.X - head.X) >= 0.5f
&& Mathf.Abs(handRight.X - head.X) >= 0.5f)
s |= MotionState.JESUS;
// Headphone
if (Mathf.Abs(handLeft.X - head.X) < 0.2f
&& Mathf.Abs(handLeft.Z - head.Z) < 0.2f)
s |= MotionState.HEADPHONE_LEFT;
if (Mathf.Abs(handRight.X - head.X) < 0.2f
&& Mathf.Abs(handRight.Z - head.Z) < 0.2f)
s |= MotionState.HEADPHONE_RIGHT;
// On The Table
if (kneeLeft.Y - kneeLeftBase.Y >= 0.5f
|| kneeRight.Y - kneeRightBase.Y >= 0.5f)
s |= MotionState.ON_THE_TABLE;
spineMidRecent = spineMid;
handLeftRecent = handLeft;
handRightRecent = handRight;
return s;
}
var tracked = body.Where(x => x != null && x.IsTracked).ToList();
if (tracked.Count() == 0 || tracked[0].Joints == null)
{
discriminator.Initialize();
return MotionState.UNKNOWN;
}
float Distance(CameraSpacePoint a, CameraSpacePoint b)
{
return Mathf.Sqrt(Mathf.Pow(a.X - b.X, 2.0f) +
Mathf.Pow(a.Y - b.Y, 2.0f) +
Mathf.Pow(a.Z - b.Z, 2.0f));
}
discriminator.Update(tracked[0]);
return discriminator.Motion;
}
}
[System.Flags]
[Flags]
public enum MotionState : uint
{
UNKNOWN = 0x00000,
......@@ -187,8 +63,276 @@ public enum MotionState : uint
ON_THE_TABLE = 0x80000
}
public class Pair<T1, T2>
internal class MotionDiscriminator
{
public T1 first;
public T2 second;
DistItvExtractor extractor;
bool initialized = true;
private MotionState _Motion;
public MotionState Motion
{ get { return _Motion; } }
public void Preset(KinectModule.IBody body)
{
CameraSpacePoint KneeLeftBase = body.Joints[JointType.KneeLeft ].Position,
KneeRightBase = body.Joints[JointType.KneeRight].Position;
extractor = new DistItvExtractor((KneeLeftBase.Y + KneeRightBase.Y) / 2);
Initialize();
}
public void Initialize()
{
_Motion = MotionState.UNKNOWN;
initialized = true;
}
public void Update(KinectModule.IBody body)
{
extractor.Extract(body);
Determine();
initialized = false;
}
float Distance(CameraSpacePoint a, CameraSpacePoint b)
{
return Mathf.Sqrt(Mathf.Pow(a.X - b.X, 2.0f) +
Mathf.Pow(a.Y - b.Y, 2.0f) +
Mathf.Pow(a.Z - b.Z, 2.0f));
}
void Determine()
{
Clap();
Jump();
HandMove();
GuardBase();
HandUp();
HandDown();
Jesus();
Headphone();
OnTheTable();
}
void Clap()
{
const float distPrepare = 0.3f, distDone = 0.1f;
if (extractor.DistHandBaseSpineShoulder <= 0.0f)
return;
if (extractor.DistHand > distPrepare)
_Motion |= MotionState.CLAP_PREPARE;
else if (extractor.DistHand < distDone)
_Motion |= MotionState.CLAP_DONE;
}
void Jump()
{
const float distPrepare = 0.05f, distDone = 0.0f;
if (initialized)
return;
if (extractor.DistSpine < distPrepare)
_Motion |= MotionState.JUMP_PREPARE;
else if (extractor.DistSpine > distDone)
_Motion |= MotionState.JUMP_DONE;
}
void HandMove()
{
if (initialized || extractor.DistHandBaseHead <= 0.0f)
return;
if (extractor.DistHandLeft > 0)
_Motion |= MotionState.HAND_MOVE_UP_LEFT;
else if (extractor.DistHandLeft < 0)
_Motion |= MotionState.HAND_MOVE_DOWN_LEFT;
if (extractor.DistHandRight > 0)
_Motion |= MotionState.HAND_MOVE_UP_RIGHT;
else if (extractor.DistHandRight < 0)
_Motion |= MotionState.HAND_MOVE_DOWN_RIGHT;
}
void GuardBase()
{
const float distBase = 0.5f;
if (extractor.DistHandBaseElbow_Left > 0.0f &&
extractor.ItvElbowBaseSpineMid_Left < distBase)
_Motion |= MotionState.GUARD_BASE_LEFT;
if (extractor.DistHandBaseElbow_Right > 0.0f &&
extractor.ItvElbowBaseSpineMid_Right < distBase)
_Motion |= MotionState.GUARD_BASE_RIGHT;
}
void HandUp()
{
const float distUp = 0.2f;
if (extractor.DistHandBaseHead_Left > distUp)
_Motion |= MotionState.HAND_UP_LEFT;
if (extractor.DistHandBaseHead_Right > distUp)
_Motion |= MotionState.HAND_UP_RIGHT;
}
void HandDown()
{
if (extractor.DistHandBaseSpineMid_Left < 0.0f)
_Motion |= MotionState.HAND_DOWN_LEFT;
if (extractor.DistHandBaseSpineMid_Right < 0.0f)
_Motion |= MotionState.HAND_DOWN_RIGHT;
}
void Jesus()
{
const float distJesus = 0.5f;
if (extractor.DistHandBaseSpineShoulder > 0.0f && extractor.ItvHandBaseHead >= distJesus)
_Motion |= MotionState.JESUS;
}
void Headphone()
{
const float itvDepth = 0.2f, itvEar = 0.2f;
if (extractor.ItvHandBaseHead_LeftEar < itvEar &&
extractor.ItvHandBaseHead_LeftDepth < itvDepth)
_Motion |= MotionState.HEADPHONE_LEFT;
if (extractor.ItvHandBaseHead_RightEar < itvEar &&
extractor.ItvHandBaseHead_RightDepth < itvDepth)
_Motion |= MotionState.HEADPHONE_RIGHT;
}
void OnTheTable()
{
const float distTable = 0.5f;
if (extractor.DistKneeBaseTable >= distTable)
_Motion |= MotionState.ON_THE_TABLE;
}
}
internal class DistItvExtractor
{
CameraSpacePoint Head,
HandLeft,
HandRight,
SpineShoulder,
SpineMid,
ElbowLeft,
ElbowRight,
KneeLeft,
KneeRight,
SpineMidRecent,
HandLeftRecent,
HandRightRecent;
float Table;
public float DistHandBaseSpineShoulder{ get; private set; }
public float DistHand{ get; private set; }
public float DistSpine{ get; private set; }
public float DistHandBaseHead{ get; private set; }
public float DistHandLeft{ get; private set; }
public float DistHandRight{ get; private set; }
public float DistHandBaseElbow_Left{ get; private set; }
public float DistHandBaseElbow_Right{ get; private set; }
public float DistHandBaseHead_Left{ get; private set; }
public float DistHandBaseHead_Right{ get; private set; }
public float DistHandBaseSpineMid_Left{ get; private set; }
public float DistHandBaseSpineMid_Right{ get; private set; }
public float DistKneeBaseTable{ get; private set; }
public float ItvElbowBaseSpineMid_Left{ get; private set; }
public float ItvElbowBaseSpineMid_Right{ get; private set; }
public float ItvHandBaseHead{ get; private set; }
public float ItvHandBaseHead_LeftEar{ get; private set; }
public float ItvHandBaseHead_RightEar{ get; private set; }
public float ItvHandBaseHead_LeftDepth{ get; private set; }
public float ItvHandBaseHead_RightDepth{ get; private set; }
public DistItvExtractor(float table)
{
Table = table;
}
public void Extract(KinectModule.IBody body)
{
UpdatePosition(body);
UpdateDistItv();
SaveRecent();
}
void UpdatePosition(KinectModule.IBody body)
{
Head = body.Joints[JointType.Head ].Position;
HandLeft = body.Joints[JointType.HandLeft ].Position;
HandRight = body.Joints[JointType.HandRight ].Position;
SpineShoulder = body.Joints[JointType.SpineShoulder].Position;
SpineMid = body.Joints[JointType.SpineMid ].Position;
ElbowLeft = body.Joints[JointType.ElbowLeft ].Position;
ElbowRight = body.Joints[JointType.ElbowRight ].Position;
KneeLeft = body.Joints[JointType.KneeLeft ].Position;
KneeRight = body.Joints[JointType.KneeRight ].Position;
}
void SaveRecent()
{
SpineMidRecent = SpineMid;
HandLeftRecent = HandLeft;
HandRightRecent = HandRight;
}
void UpdateDistItv()
{
DistHandBaseSpineShoulder = Mathf.Min(HandLeft.Y, HandRight.Y) - SpineShoulder.Y;
DistHand = Distance(HandLeft, HandRight);
DistSpine = SpineMid.Y - SpineMidRecent.Y;
DistHandBaseHead = Mathf.Min(HandLeft.Y, HandRight.Y) - Head.Y;
DistHandLeft = HandLeft.Y - HandLeftRecent.Y;
DistHandRight = HandRight.Y - HandRightRecent.Y;
DistHandBaseElbow_Left = HandLeft.Y - ElbowLeft.Y;
DistHandBaseElbow_Right = HandRight.Y - ElbowRight.Y;
DistHandBaseHead_Left = HandLeft.Y - Head.Y;
DistHandBaseHead_Right = HandRight.Y - Head.Y;
DistHandBaseSpineMid_Left = HandLeft.Y - SpineMid.Y;
DistHandBaseSpineMid_Right = HandRight.Y - SpineMid.Y;
DistKneeBaseTable = Mathf.Min(KneeLeft.Y, KneeRight.Y) - Table;
ItvElbowBaseSpineMid_Left = Mathf.Abs(ElbowLeft.X - SpineMid.X);
ItvElbowBaseSpineMid_Right = Mathf.Abs(ElbowRight.X - SpineMid.X);
ItvHandBaseHead = Mathf.Min(Mathf.Abs(HandLeft.X - Head.X), Mathf.Abs(HandLeft.X - Head.X));
ItvHandBaseHead_LeftEar = Mathf.Abs(HandLeft.X - Head.X);
ItvHandBaseHead_RightEar = Mathf.Abs(HandRight.X - Head.X);
ItvHandBaseHead_LeftDepth = Mathf.Abs(HandLeft.Z - Head.Z);
ItvHandBaseHead_RightDepth = Mathf.Abs(HandRight.Z - Head.Z);
}
float Distance(CameraSpacePoint a, CameraSpacePoint b)
{
return Mathf.Sqrt(Mathf.Pow(a.X - b.X, 2.0f) +
Mathf.Pow(a.Y - b.Y, 2.0f) +
Mathf.Pow(a.Z - b.Z, 2.0f));
}
}
\ No newline at end of file
using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class TrackManager : MonoBehaviour {
......@@ -21,41 +19,22 @@ public class TrackManager : MonoBehaviour {
[SerializeField]
Texture2D[] backgrounds;
private int currentBackgroundIndex = 0;
private int textureID = 0;
Texture buffer;
public Text Artist;
public Text BPM;
private GameObject selectedTrackItem = null;
private void TrackBrowse()
{
currentBackgroundIndex = (currentBackgroundIndex + 1) % 2;
trackList.GetComponent<RawImage>().texture = backgrounds[currentBackgroundIndex];
if (selectedTrackItem != null)
selectedTrackItem.GetComponentInChildren<Text>().color = Color.white;
selectedTrackItem = trackList.transform.GetChild(2).gameObject;
selectedTrackItem.GetComponentInChildren<Text>().color = Color.black;
if (selectedTrackItem == null)
return;
Artist.text = "Artist :" + selectedTrackItem.gameObject.GetComponent<TrackInfoHolder>().trackInfo.Artist.ToString();
BPM.text = "BPM :" + selectedTrackItem.gameObject.GetComponent<TrackInfoHolder>().trackInfo.BPM.ToString();
for (int i = 0; i < trackInfo.transform.childCount; i++)
Destroy(trackInfo.transform.GetChild(i).gameObject);
foreach (string trackItem in selectedTrackItem.gameObject.GetComponent<TrackInfoHolder>().trackInfo.TrackList)
{
Instantiate(trackInfoItemPrefab, trackInfo.transform).GetComponent<Text>().text = trackItem;
}
}
private GameObject selected = null;
// Use this for initialization
void Start()
{
LoadTracks();
StretchTrackInfoList(GenerateTrackInfos())
.ToList()
.ForEach(x => MakeTrackObject(x));
TrackBrowse();
}
......@@ -78,35 +57,60 @@ public class TrackManager : MonoBehaviour {
if (InputManager.Instance.IsButtonPressed)
StartTrack();
}
void LoadTracks()
IEnumerable<TrackInfo> GenerateTrackInfos()
{
return new DirectoryInfo("Assets/Tracks")
.GetFiles("*.bpe", SearchOption.AllDirectories)
.Select(s => new TrackInfo(s));
}
IEnumerable<TrackInfo> StretchTrackInfoList(IEnumerable<TrackInfo> tracks)
{
foreach (TrackInfo track in LoadTrackInfos())
{
var trackItem = Instantiate(trackItemPrefab, trackList.transform);
var stretched = Enumerable.Empty<TrackInfo>();
Enumerable.Range(0, 1 + (4 / tracks.Count()))
.ToList()
.ForEach(x => stretched.Concat(tracks));
trackItem.AddComponent<TrackInfoHolder>().trackInfo = track;
}
return stretched;
}
void MakeTrackObject(TrackInfo info)
{
Instantiate(trackItemPrefab, trackList.transform)
.AddComponent<TrackInfoHolder>().trackInfo = info;
}
List<TrackInfo> LoadTrackInfos()
private void TrackBrowse()
{
var files = new DirectoryInfo("Assets/Tracks").GetFiles("*.bpe", SearchOption.AllDirectories);
trackList.GetComponent<RawImage>().texture = backgrounds[(textureID ^= 1)];
if (selected != null)
selected.GetComponentInChildren<Text>().color = Color.white;
selected = trackList.transform.GetChild(2).gameObject;
selected.GetComponentInChildren<Text>().color = Color.black;
var tracks = files.Select(s => new TrackInfo(s)).ToList();
while (tracks.Count() < 5)
tracks.AddRange(tracks);
var info = selected.GetComponent<TrackInfoHolder>().trackInfo;
return tracks;
Artist.text = "Artist :" + info.Artist.ToString();
BPM.text = "BPM :" + info.BPM .ToString();
trackInfo.GetComponentsInChildren<Transform>()
.ToList()
.ForEach(x => Destroy(x));
info.TrackList
.ForEach(x => Instantiate(trackInfoItemPrefab, trackInfo.transform)
.GetComponent<Text>()
.text = x);
}
public void StartTrack()
{
// TODO: disable start button if nothing selected
var holder = selectedTrackItem.GetComponent<TrackInfoHolder>();
GameManager.Instance.CurrentTrack = holder.trackInfo;
GameManager.Instance.CurrentTrack = selected.GetComponent<TrackInfoHolder>().trackInfo;
Destroy(GetComponent<InputManager>());
Destroy(this);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment