本日はMRTK調査枠です。
MRTKでは[Input Recording Service]と呼ばれる機能が実装されています。
[Input Recording Service]はユーザーの動きを記録・保存する機能で[Input Simulation Service]を用いてUnityエディタ内で再生することができます。
今回はこれを勉強しながらアプリ内でユーザーの動きを録画してみます。
その①はドキュメントを読み解きながら各サービスの概要をつかみました。
その②では実際にアプリで記録を行いUnityエディタ内で再生を行いました。
今回はコードを読み解きながらどのようなデータを記録しているのか見ていきます。
〇InputRecordingControls
記録を行う際に呼び出されるコンポーネントは
Mixed Reality Toolkit Foundation/SDK/Features/UX/Scripts/Utilities内の[InputRecordingControls.cs]の[StartRecording()]になります。
public void StartRecording() { eyeGazeProvider = CoreServices.InputSystem.EyeGazeProvider; IsRecording = true; frameRate = InputRecordingProfile.FrameRate; frameInterval = 1f / frameRate; nextFrame = Time.time + frameInterval; if (UseBufferTimeLimit) { PruneBuffer(); } if (!unlimitedRecordingStartTime.HasValue) { unlimitedRecordingStartTime = Time.time; } OnRecordingStarted?.Invoke(); }
ここではフレームレートなどを定義し[IsRecording]をTrueに変えています。
これにより[LateUpdate]無いの処理が走り[RecordKeyframe()]が実行されます。
public override void LateUpdate() { if (IsEnabled && IsRecording && Time.time > nextFrame) { EndTime = Time.time; nextFrame += frameInterval * (Mathf.Floor((Time.time - nextFrame) * frameRate) + 1f); if (UseBufferTimeLimit) { PruneBuffer(); } RecordKeyframe(); } }
[RecordKeyframe()]で実際の記録が行われています。
ここで各Inputごとの処理関数を実行しています。例えばHandTrackingの記録を行う場合[RecordInputHandData(Handedness.Left)]が実行されます。
private void RecordKeyframe() { float time = Time.time; var profile = InputRecordingProfile; recordingBuffer.NewKeyframe(time); if (profile.RecordHandData) { RecordInputHandData(Handedness.Left); RecordInputHandData(Handedness.Right); } MixedRealityPose cameraPose; if (profile.RecordCameraPose && CameraCache.Main) { cameraPose = new MixedRealityPose(CameraCache.Main.transform.position, CameraCache.Main.transform.rotation); recordingBuffer.SetCameraPose(cameraPose); } else { cameraPose = new MixedRealityPose(Vector3.zero, Quaternion.identity); } if (profile.RecordEyeGaze) { if (eyeGazeProvider != null) { recordingBuffer.SetGazeRay(eyeGazeProvider.LatestEyeGaze); } else { recordingBuffer.SetGazeRay(new Ray(cameraPose.Position, cameraPose.Forward)); } } }
[RecordInputHandData]を見ていきます。
private void RecordInputHandData(Handedness handedness) { float time = Time.time; var profile = InputRecordingProfile; var hand = HandJointUtils.FindHand(handedness); ... if (isTracked) { for (int i = 0; i < ArticulatedHandPose.JointCount; ++i) { if (hand.TryGetJoint((TrackedHandJoint)i, out MixedRealityPose jointPose)) { recordingBuffer.SetJointPose(handedness, (TrackedHandJoint)i, jointPose); } } } }
ここで記録を行っている部分は次の一行になります。
recordingBuffer.SetJointPose(handedness, (TrackedHandJoint)i, jointPose);
SetJointPoseではHandTrackingによって取得される各Jointが記録されていることがわかります。
以上でRecordServiceを読み解いていきました。
実際はバイナリーデータで書き出されるためもう少し読み解いていきたいです。