Skip to content

Instantly share code, notes, and snippets.

@mnstrspeed
Last active October 14, 2016 21:12
Show Gist options
  • Save mnstrspeed/1d95fcb23da23004a52dd39362ce4ff7 to your computer and use it in GitHub Desktop.
Save mnstrspeed/1d95fcb23da23004a52dd39362ce4ff7 to your computer and use it in GitHub Desktop.
Motion capture recording and playback for SteamVR in Unity
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;
}
}
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