Last active
October 14, 2016 21:12
-
-
Save mnstrspeed/1d95fcb23da23004a52dd39362ce4ff7 to your computer and use it in GitHub Desktop.
Motion capture recording and playback for SteamVR in Unity
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class MotionCapture : MonoBehaviour | |
{ | |
public SteamVR_TrackedObject Hmd; | |
public SteamVR_TrackedController Left; | |
public SteamVR_TrackedController Right; | |
private List<Stance> frames; | |
private bool recording; | |
[Serializable] | |
public struct OrientedPoint | |
{ | |
public Vector3 Position; | |
public Quaternion Rotation; | |
} | |
[Serializable] | |
public class Stance | |
{ | |
public OrientedPoint Hmd; | |
public OrientedPoint LeftHand; | |
public OrientedPoint RightHand; | |
} | |
[Serializable] | |
public class RecordedStance | |
{ | |
public Stance[] Frames; | |
} | |
public void Start() | |
{ | |
this.Left.TriggerClicked += TriggerClicked; | |
this.Right.TriggerClicked += TriggerClicked; | |
this.Left.TriggerUnclicked += TriggerUnclicked; | |
this.Right.TriggerUnclicked += TriggerUnclicked; | |
} | |
private void TriggerClicked(object sender, ClickedEventArgs e) | |
{ | |
this.StartCoroutine(this.Record( | |
Application.dataPath + "/stance" + DateTime.Now.Ticks + ".json")); | |
} | |
private IEnumerator Record(string savePath) | |
{ | |
this.recording = true; | |
this.frames = new List<Stance>(); | |
while (this.recording) | |
{ | |
yield return new WaitForFixedUpdate(); | |
this.frames.Add(this.GetStance()); | |
} | |
RecordedStance recording = new RecordedStance() | |
{ | |
Frames = this.frames.ToArray() | |
}; | |
File.WriteAllText(savePath, JsonUtility.ToJson(recording)); | |
Debug.Log("Saved to " + savePath); | |
} | |
private Stance GetStance() | |
{ | |
return new Stance() | |
{ | |
Hmd = new OrientedPoint() { Position = this.Hmd.transform.position, Rotation = this.Hmd.transform.rotation }, | |
LeftHand = new OrientedPoint() { Position = this.Left.transform.position, Rotation = this.Left.transform.rotation }, | |
RightHand = new OrientedPoint() { Position = this.Right.transform.position, Rotation = this.Right.transform.rotation }, | |
}; | |
} | |
private void TriggerUnclicked(object sender, ClickedEventArgs e) | |
{ | |
this.recording = false; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using UnityEngine; | |
using System.IO; | |
using UnityEditor; | |
using System.Collections; | |
[Serializable] | |
public class RecordedStance | |
{ | |
public MotionCapture.Stance[] Frames; | |
} | |
public class MotionCapturePlayback : MonoBehaviour | |
{ | |
public Transform Root; | |
public Transform Hmd; | |
public Transform LeftHand; | |
public Transform RightHand; | |
public bool Loop = true; | |
[SerializeField] | |
private RecordedStance recording; | |
private bool isPlaying; | |
public void Start() | |
{ | |
this.isPlaying = false; | |
if (this.recording.Frames.Length > 0) | |
{ | |
Debug.Log("Recording contains " + this.recording.Frames.Length + " frames"); | |
this.StartCoroutine(this.PlayRecording()); | |
} | |
else | |
{ | |
Debug.LogWarning("No recording loaded"); | |
} | |
} | |
[ContextMenu("Import recording")] | |
public void Import() | |
{ | |
string path = EditorUtility.OpenFilePanel("Select recording", Application.dataPath, "json"); | |
if (path.Length > 0) | |
{ | |
this.recording = JsonUtility.FromJson<RecordedStance>(File.ReadAllText(path)); | |
} | |
} | |
[ContextMenu("Show player height")] | |
public void ShowPlayerHeight() | |
{ | |
float height = this.recording.Frames[0].Hmd.Position.y; | |
Debug.Log(string.Format("Height: {0:0.000}", height)); | |
} | |
public IEnumerator PlayRecording() | |
{ | |
this.isPlaying = true; | |
do | |
{ | |
for (int i = 0; i < this.recording.Frames.Length && this.isPlaying; i++) | |
{ | |
yield return new WaitForFixedUpdate(); | |
Stance stance = this.recording.Frames[i]; | |
this.Hmd.transform.position = stance.Hmd.Position; | |
this.Hmd.transform.rotation = stance.Hmd.Rotation; | |
this.LeftHand.transform.position = stance.LeftHand.Position; | |
this.LeftHand.transform.rotation = stance.LeftHand.Rotation; | |
this.RightHand.transform.position = stance.RightHand.Position; | |
this.RightHand.transform.rotation = stance.RightHand.Rotation; | |
} | |
} | |
while (this.isPlaying && this.Loop); | |
// restarts recording if looping & not manually stopped | |
} | |
public void StopRecording() | |
{ | |
this.isPlaying = false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment