NRPhotoCapture, NRVideoCapture を読み解いてみる
概要
RGBCamera-Capture と RGBCamera-Record を理解すると NRPhotoCapture クラスと NRVideoCapture クラスが主要クラスだということが分かります。 NRPhotoCapture, NRVideoCapture の両クラスの動作を理解することで RGBCamera への理解が深まると考え、これらのソースコードを解読してみます。 個人的な読解結果であるため誤りが含まれている可能性があることをご了承ください。
目次
確認環境
- NRSDK 1.2.1
解説
拾い読み
例のごとく、NRPhotoCapture を拾い読みすると、以下が要点になるのかなと思います。
- NRPhotoCapture
- CreateAsync
- StartPhotoModeAsync
- FrameCaptureContext.StartCaptureMode(CameraParameters)
- CameraParameters の camMode は PhotoMode に設定される
- CaptureBehaviourBase インスタンスを生成する
- camMode が PhotoMode の場合は NRCaptureBehaviour (Record/Prefabs/NRCaptureBehaviour)
- IEncoder インスタンスを生成する
- camMode が PhotoMode の場合は ImageEncoder
- Config(CameraParameters) を行う
- FrameBlender インスタンスを生成する
- CaptureBehaviourBase.CaptureCamera, IEncoder, CameraParameters で初期化する
- FrameProvider.OnUpdate に CaptureBehaviourBase.OnFrame を登録する
- FrameCaptureContext.StartCapture()
- IEncoder.Start()
- FrameProvider.Play()
- FrameCaptureContext.StartCaptureMode(CameraParameters)
- TakePhotoAsync
- NRCaptureBehaviour.DoAsyn
- CaptureTask インスタンスを生成して、CameraParameters を設定する
- SystemInfo.supportsAsyncGPUReadback が true の場合、ImageEncoder.Commit(CaptureTask)
- 非同期実行で画像データが取得されて CaptureTask.OnReceive が呼ばれる
- false の場合、ImageEncoder.Encode(CaptureTask)
- RenderTexture を使用して Texture2D から画像データが取得されて CaptureTask.OnReceive が呼ばれる
- OnReceive では PhotoCaptureFrame インスタンスが生成される
- NRCaptureBehaviour.DoAsyn
- StopPhotoModeAsync
- FrameCaptureContext.StopCaptureMode()
- FrameCaptureContext.Release() を呼び出す
- FrameCaptureContext.StopCaptureMode()
- Dispose
- FrameCaptureContext.Release()
- FrameProvider.OnUpdate から CaptureBehaviourBase.OnFrame を削除する
- FrameProvider.Release()
- FrameBlender.Dispose()
- IEncoder.Release()
- Destroy(CaptureBehaviourBase)
- FrameCaptureContext を破棄する
- FrameCaptureContext.Release()
- NRCaptureBehaviour
- ImageEncoder の Commit, Encode により画像データを取得する
- OnFrame では
- NRFrame.GetHeadPoseByTime に成功した場合に RGBCameraRig の localPosition, localRotation を更新する
- FrameBlender.OnFrame を呼び出す
- ImageEncoder
- 画像データを取得する
- FrameBlender
- OnFrame で BlendMode (RGBOnly/VirtualOnly/Blend/WidescreenBlend) に応じて Blit を行い画像データを作る
- 作った画像データは ImageEncoder に渡される
- OnFrame で BlendMode (RGBOnly/VirtualOnly/Blend/WidescreenBlend) に応じて Blit を行い画像データを作る
- RGBCameraFrameProvider
- NRRGBCamTexture を使う
- Play, Pause, Stop で NRRGBCamTexture の Play, Pause, Stop を呼び出す
- NRRGBCamTexture.OnUpdate に AbstractFrameProvider.OnUpdate を登録する
- NRRGBCamTexture を使う
- EditorFrameProvider
- AbstractFrameProvider.OnUpdate に毎フレーム RGBTextureFrame を渡す
- RGBTextureFrame.texture に Texture2D (Record/Textures/captureDefault) を設定する
- AbstractFrameProvider.OnUpdate に毎フレーム RGBTextureFrame を渡す
同様に、NRVideoCapture を拾い読みすると、以下が要点になるのかなと思います。
- NRVideoCapture
- CreateAsync
- NRVideoCapture インスタンスを生成する
- 他は NRPhotoCapture と同様
- StartVideoModeAsync
- FrameCaptureContext.StartCaptureMode(CameraParameters)
- CameraParameters の camMode は VideoMode に設定される
- CameraParameters の hologramOpacity は 1 に設定される
- 他は NRPhotoCapture と同様だが、camMode が異なるため以下が異なる
- NRCaptureBehaviour は NRRecordBehaviour (Record/Prefabs/NRRecorderBehaviour) になる
- IEncoder は VideoEncoder になる
- FrameCaptureContext.StartCaptureMode(CameraParameters)
- StartRecordingAsync
- IsRecording が true の場合は UnknownError とする (Unknown なんだ...)
- NRRecordBehaviour.SetOutPutPath を行う
- FrameCaptureContext.StartCapture()
- NRPhotoCapture と同様
- IsRecording を true にする
- StopRecordingAsync
- IsRecording が false の場合は UnknownError とする (Unknown なんだ...)
- FrameCaptureContext.StopCapture()
- IEncoder.Stop()
- FrameProvider.Stop()
- IsRecording を false にする
- StopVideoModeAsync
- NRPhotoCapture と同様
- Dispose
- NRPhotoCapture と同様
- CreateAsync
要点の整理
NRPhotoCapture, NRVideoCapture の基本的な使い方は似ています。以下の 5 つに分類して理解します。
- CreateAsync
- Start[Photo/Video]ModeAsync
- TakePhotoAsync or [Start/Stop]RecordingAsync
- Stop[Photo/Video]ModeAsync
- Dispose
CreateAsync
引数は showHolograms と callback の 2 つです。 showHolograms は使用されていません。 callback は処理が終了するときに呼び出されます。 非同期処理ではありません。 callback が呼び出されてから CreateAsync が終了します。
CreateAsync は NRPhotoCapture, NRVideoCapture インスタンスを生成します。 この時、FrameCaptureContext インスタンスを生成して設定します。 更に、FrameProvider (AbstractFrameProvider のサブクラス) インスタンスを生成して FrameCaptureContext インスタンスに設定します。 つまり、下記の階層構造になります。
- NR[Photo/Video]Capture
- FrameCaptureContext
- FrameProvider
- FrameCaptureContext
FrameProvider は実行環境により異なります。 Unity Editor では EditorFrameProvider、それ以外では RGBCameraFrameProvider が使われます。
Start[Photo/Video]ModeAsync
引数には CameraParameters, callback が渡されます。 Video では AudioState が追加で渡されます。 CameraParameters は諸々の場面で使用されます。 callback は処理が終了するときに呼び出されます。 非同期処理ではありません。 callback が呼び出されてから Start[Photo/Video]ModeAsync が終了します。 AudioState は使用されていません。
Start[Photo/Video]ModeAsync では PhotoMode/VideoMode で FrameCaptureContext を初期化します。 FrameCaptureContext.StartCaptureMode(CameraParameters) を呼び出し、以下に続くいくつかの処理を行います。
CameraParameters の値をいくつか上書きします。 Photo/Video に応じて、CameraParameters.camMode の値を PhotoMode/VideoMode で上書きします。 Video の時のみ、CameraParameters.hologramOpacity を 1 に上書きします。
Behaviour (CaptureBehaviourBase のサブクラス) インスタンス、Encoder (IEncoder を実装) インスタンス、FrameBlender インスタンスを生成します。 Behaviour と Encoder は Photo/Video により生成するインスタンスが異なります。
- Photo
- NRCaptureBehaviour (Record/Prefabs/NRCaptureBehaviour)
- ImageEncoder
- Video
- NRRecordBehaviour (Record/Prefabs/NRRecorderBehaviour)
- VideoEncoder
FrameProvider.OnUpdate に CaptureBehaviourBase.OnFrame を登録します。 FrameProvider.OnUpdate が呼び出されたときに Behaviour の OnFrame が呼び出される様になります。
終了時点では、階層構造は下記に更新されています。
- NR[Photo/Video]Capture
- FrameCaptureContext
- FrameProvider
- Behaviour
- Encoder
- FrameBlender
- FrameCaptureContext
Photo の時のみ、FrameCaptureContext.StartCaptureMode() に続いて FrameCaptureContext.StartCapture() を呼び出します。 FrameCaptureContext.StartCapture の説明は StartRecordingAsync を参照してください。
Stop[Photo/Video]ModeAsync
引数には callback が渡されます。 callback は処理が終了するときに呼び出されます。 非同期処理ではありません。 callback が呼び出されてから Stop[Photo/Video]ModeAsync が終了します。
Stop[Photo/Video]ModeAsync では FrameCaptureContext を無効化します。 FrameCaptureContext.StopCaptureMode() を呼び出すことで行われます。
StopCaptureMode では FrameCaptureContext.Release() を呼び出します。 Release では以下を無効化します。
- FrameProvider
- Behaviour
- Encoder
- FrameBlender
また、FrameProvider.OnUpdate から CaptureBehaviourBase.OnFrame を削除します。
(Photo の時は FrameCaptureContext.StopCapture() を呼び出した方が良いと思うけどやっていない。)
Dispose
引数はありません。他とは違い Async が付かないため明確に同期呼び出しでの使用を想定していると思われます。
Dispose では FrameCaptureContext.Release() を呼び出した後に、FrameCaptureContext インスタンスを破棄します。 Release の処理内容は Stop[Photo/Video]ModeAsync を参照してください。
撮影/録画
StartRecordingAsync
引数には filename と callback が渡されます。 callback は処理が終了するときに呼び出されます。 非同期処理ではありません。 callback が呼び出されてから StartRecordingAsync が終了します。 録画中に呼び出したり、処理中に例外が発生すると callback に UnknownError が渡されます。
StartRecordingAsync では FrameCaptureContext.StartCapture() を呼び出して、録画を開始します。 StartCapture では、Encoder を開始(Start)し、FrameProvider を再生状態に(Play)します。
StartCapture の呼び出し前には NRRecordBehaviour に filename を設定します。 NRRecordBehaviour では設定された filename を VideoEncoder.EncodeConfig に設定します。
StopRecordingAsync
引数には callback が渡されます。 callback は処理が終了するときに呼び出されます。 非同期処理ではありません。 callback が呼び出されてから StopRecordingAsync が終了します。 未録画時に呼び出したり、処理中に例外が発生すると callback に UnknownError が渡されます。
StopRecordingAsync では FrameCaptureContext.StopCapture() を呼び出して、録画を停止します。 StopCapture では、Encoder を停止(Stop)し、FrameProvider を停止状態に(Stop)します。
TakePhotoAsync
引数のパターンが 2 種類あります。 filename と PhotoCaptureFileOutputFormat を指定するパターンと、指定しないパターンです。 いずれの場合も callback が渡されます。 filename を指定するパターンでは callback が使用されません。 filename を指定しないパターンでは画像が取得できたときに callback が呼ばれます。 SystemInfo.supportsAsyncGPUReadback が true の場合は非同期処理、false の場合は同期処理になります。
TakePhotoAsync は引数のパターンにより処理方法が異なります。
filename を指定するパターンでは、NRCaptureBehaviour.Do を呼び出します。 Do では ImageEncoder.Encode(width, height, captureFormat) を呼び出します。 Encode により画像データが取得し、ファイルに書き出します。
filename を指定しないパターンでは、NRCaptureBehaviour.DoAsyn を呼び出します。 DoAsyn では CaptureTask インスタンスを生成し、CaptureTask に応じた画像データ取得の処理を行います。 CaptureTask には OnReceive 関数を設定して、画像データの取得が完了した場合の処理を指定します。 OnReceive 関数は画像データが得られたときに PhotoCaptureFrame インスタンスを生成し、callback を呼び出します。 PhotoCaptureFrame は callback の引数として渡されます。
CaptureTask は SystemInfo.supportsAsyncGPUReadback の値により処理方法が異なります。
supportsAsyncGPUReadback が true の場合、CaptureTask をキューに積んで非同期に処理を行います。 CaptureTask は Update のタイミングで処理されます。 UnityEngine.Rendering.AsyncGPUReadbackRequest を使用して画像データを取得します。 画像データ (Texture2D) が取得されると OnReceive を呼び出します。 呼び出す際に CaptureTask.CaptureFormat に従って JPG/PNG にエンコードしたデータが渡されます。
supportsAsyncGPUReadback が false の場合、ImageEncoder.Encode(width, height, captureFormat) を呼び出します。 width, height, captureFormat は CaptureTask から取得します。 Encode により画像データが取得されたら OnReceive を呼び出します。 呼び出す際に Encode で得たデータが渡されます。
ImageEncoder.Encode は filename を指定するパターンと filename を指定せずに supportsAsyncGPUReadback が false の場合に呼び出されます。 Encode では FrameBlender.OnFrame で生成された RenderTexture から得られた画像データ (Texture2D) を CaptureTask.CaptureFormat に従って JPG/PNG にエンコードします。 FrameBlender.OnFrame については次に説明します。
FrameBlender
FrameBlender.OnFrame では BlendMode (RGBOnly/VirtualOnly/Blend/WidescreenBlend) に応じて Texture を Blit します。 OnFrame は引数に RGBTextureFrame を受け取ります。 Blit した結果の RenderTexture は Encoder に設定(Commit)されます。
FrameBlender.OnFrame は CaptureBehaviourBase.OnFrame から呼ばれます。 CaptureBehaviourBase.OnFrame は FrameProvider.OnUpdate に登録されるため、FrameProvider.OnUpdate が呼び出されたときに FrameBlender.OnFrame が呼ばれることになります。
FrameProvider.OnUpdate は引数に RGBTextureFrame を受け取っており、これが FrameBlender.OnFrame の引数になります。
RGBCameraFrameProvider
Unity Editor 以外で動かした場合に使われる FrameProvider です。 NRRGBCamTexture を使って RGBTextureFrame を取得します。
FrameCaptureContext の操作に応じて以下の様に NRRGBCamTexture の操作が使われます。
| FrameCaptureContext | RGBCameraFrameProvider | NRRGBCamTexture |
|---|---|---|
| StartCapture | Play | Play |
| StopCapture | Stop | Pause |
| Release | Release | Stop |
NRRGBCamTexture では NRRgbCamera.GetRGBFrame を呼び出して RGBTextureFrame を取得しています。 この RGBTextureFrame が FrameProvider.OnUpdate を呼ぶときに渡されます。
FrameProvider.OnUpdate は NRKernalUpdater.OnUpdate が呼ばれて NRRGBCamTexture.OnUpdate が呼ばれたときに呼ばれます。 OnUpdate, OnFrame の呼び出し関係を整理すると下記の様になります。
NRKernalUpdater.OnUpdate
NRRGBCamTexture.OnUpdate
RGBCameraFrameProvider.OnUpdate
Behaviour.OnFrame
FrameBlender.OnFrame
Encoder.Commit
EditorFrameProvider
Unity Editor で動かした場合に使われる FrameProvider です。 RGBTextureFrame インスタンスを生成し、インスタンスに Texture2D (Record/Textures/captureDefault) を設定します。
コルーチンで FrameProvider.OnUpdate を呼んでいます。その際に生成した RGBTextureFrame を渡します。 但し、isPlay が true のときのみ呼ばれます。isPlay は FrameCaptureContext の操作に応じて以下の様に設定されます。
| FrameCaptureContext | EditorFrameProvider | isPlay |
|---|---|---|
| StartCapture | Play | true |
| StopCapture | Stop | false |
| Release | Release | false |
NRFrame.GetTrackables を読み解いてみる
概要
ImageTracking の仕組みを理解するために NRFrame.GetTrackables を読み解いてみます。 個人的な読解結果であるため誤りが含まれている可能性があることをご了承ください。
目次
確認環境
- NRSDK 1.2.1
解説
拾い読み
NRFrame.GetTrackables から続く処理を拾い読みしました。以下が要点かと思います。
- NRFrame.GetTrackables
- NRTrackableManager.GetTrackables
- UpdateTrackables を呼び出す
- m_AllTrackables を m_NewTrackables と m_OldTrackables に振り分ける
- NRTrackableManager.UpdateTrackables
- trackablelist_handle = NativeTrackable.CreateTrackableList()
- NativeTracking.UpdateTrackables(trackablelist_handle, trackable_type)
- trackable_type : TrackableType (BASE/PLANE/IMAGE)
- count = NativeTrackable.GetSize(trackablelist_handle)
- count 回繰り返す
- trackable_handle = NativeTrackable.AcquireItem(trackablelist_handle, index)
- Create(trackable_handle, m_NativeInterface) を呼び出す
- NativeTrackable.DestroyTrackableList
- NRTrackableManager.Create
- NRTrackableManager.GetTrackables
ここまで読んで、TrackingImageDatabase (ScriptableObject) は何に使われているのか疑問に思いました。 TrackingImageDatabase が関連している処理を探して読んでいくと、NRSessionBehaviour から始まる処理で使用されていることがわかりました。 一連の処理では以下が要点になると思います。
- NRSessionBehaviour
- NRSessionManager.CreateSession
- NRDevice.Init
- NativeInterface.NativeTracking.Create
- NativeApi.NRTrackingCreate(ref m_TrackingHandle)
- NativeInterface.TrackingHandle = m_TrackingHandle
- NativeAPI.NativeTracking.SetTrackingMode(TrackingMode)
- DeployData
- database = SessionConfig.TrackingImageDatabase
- ZipUtility.UnzipFile(database.RawData, database.TrackingImageDataOutPutPath, NativeConstants.ZipKey)
- TrackingImageDataOutPutPath は [Application.persistentDataPath]/TrackingImageData/
- NRSessionManager.StartSession
- SetAppSettings(SessionConfig.OptimizedRendering)
- NativeAPI.NativeTracking.Start()
- NativeApi.NRTrackingStart
- NativeAPI.NativeHeadTracking.Create()
- NativeApi.NRHeadTrackingCreate
- NRSessionManager.SetConfiguration
- NativeConfigration.UpdateConfig
- NativeApi.NRConfigCreate(m_NativeInterface.TrackingHandle, ref m_ConfigHandle)
- m_ConfigHandle が 0 の場合のみ行う
- NRSessionConfig.ImageTrackingMode が DISABLE の場合
- NativeTrackableImage.DestroyDataBase(m_DatabaseHandle)
- m_DatabaseHandle が 0 以外の場合のみ行う
- NativeTrackableImage.DestroyDataBase(m_DatabaseHandle)
- NRSessionConfig.ImageTrackingMode が ENABLE の場合
- m_DatabaseHandle = NativeTrackableImage.CreateDataBase()
- NativeTrackableImage.LoadDataBase(m_DatabaseHandle, TrackingImageDataPath)
- TrackingImageDataPath : NRSessionConfig.TrackingImageDatabase.TrackingImageDataPath
- [Application.persistentDataPath]/TrackingImageData/[DB_GUID] ディレクトリ
- TrackingImageDataPath : NRSessionConfig.TrackingImageDatabase.TrackingImageDataPath
- NativeApi.NRConfigSetTrackableImageDatabase(m_NativeInterface.TrackingHandle, m_ConfigHandle, m_DatabaseHandle)
- NativeApi.NRConfigCreate(m_NativeInterface.TrackingHandle, ref m_ConfigHandle)
- NativeConfigration.UpdateConfig
- NRSessionManager.CreateSession
要点を整理する
NRFrame.GetTrackable
NRFrame.GetTrackable の API は以下の様になっており、引数 trackables には検出した結果を格納する List、引数 filter には結果を絞り込む条件を指定します。
void NRFrame.GetTrackable<T>(List<T> trackables, NRTrackableQueryFilter filter) where T : NRTrackable
NRTrackableQueryFilter は All と New の 2 種類です。 NRTrackable のサブクラスは NRTrackableImage と NRTrackablePlane があり、T にはいずれかを指定します。
NRFrame.GetTrackable では、NRTrackableManager.GetTrackables を呼び出しています。引数は NRFrame.GetTrackables と同じです。 NRTrackableManager.GetTrackables では以下を行います。
- NRTrackableManager.UpdateTrackables を呼び出して AllTrackables (List<NRTrackable>) を更新する
- AllTrackables に新しく追加された NRTrackable を NewTrackables (List<NRTrackable>) に格納する
- filter が All であれば AllTrackables の NRTrackable を trackables に格納する
- filter が New であれば NewTrackables の NRTrackable を trackables に格納する
NRTrackableManager.UpdateTrackables では、Native API を呼び出して AllTrackables を更新します。 UpdateTrackables の引数には TrackableType が渡されます。 TrackableType は型パラメータの T から決定されます。 T が NRTrackableImage の場合は TrackableType は TRACKABLE_IMAGE、T が NRTrackablePlane の場合は TrackableType は TRACKABLE_PLANE になります。
NRTrackableManager.UpdateTrackables は以下の疑似コードの様に Native API を呼び出します。
void UpdateTrackables(TrackableType trackable_type)
{
UInt64 trackable_list_handle;
int list_size;
NRTrackableListCreate(session_handle, ref trackable_list_handle);
NRTrackingUpdateTrackables(session_handle, trackable_type, trackable_list_handle);
NRTrackableListGetSize(session_handle, trackable_list_handle, ref list_size);
for (int index = 0; index < list_size; index++)
{
UInt64 trackable_handle;
TrackableType out_trackable_type;
NRTrackableListAcquireItem(session_handle, trackable_list_handle, index, ref trackable_handle);
NRTrackableGetType(session_handle, trackable_handle, ref out_trackable_type);
if (out_trackable_type == TRACKABLE_PLANE) AllTrackables.Add(NRTrackablePlane(trackable_handle));
if (out_trackable_type == TRACKABLE_IMAGE) AllTrackables.Add(NRTrackableImage(trackable_handle));
}
NRTrackableListDestroy(session_handle, trackable_list_handle);
}
上記のコードにおいて、session_handle は NativeInterface.TrackingHandle です。 NativeInterface.TrackingHandle は NRSessionManager.CreateSession の過程で設定されます。 これについては後ほど説明します。
以上で、NRFrame.GetTrackable から始まる一連の処理は終了です。 Native API を使用して ImageTracking を行っていることが分かります。
ImageTracking に関連する初期化処理
ここまで TrackingImageDatabase (ScriptableObject) は全く登場しませんでした。 ImageTracking には不要なのでしょうか? これについては NRSessionManager の Awake, Start の処理を見ていくことで理解が深まります。
NRSessionManager の Awake, Start では NRSessionManager の CreateSession, StartSession, SetConfiguration を呼び出しています。 これらの過程では以下に示す ImageTracking に関連する初期化処理が行われています。
- NativeInterface.TrackingHandle の初期化
TrackingHandle の値は Native API から取得されます。 疑似コードで示すと以下の様になります。
UInt64 tracking_handle; NRTrackingCreate(ref tracking_handle); NativeInterface.TrackingHandle = tracking_handle;
- TrackingImageDatabase データの展開
TrackingImageDatabase データは SessionConfig.TrackingImageDatabase.RawData に byte[] として保持しています。 この RawData は zip アーカイブのデータになっており、unzip して [Application.persistentDataPath]/TrackingImageData/ に展開されます。
- ImageTracking の有効化/無効化
SessionConfig.ImageTrackingMode が ENABLE の場合には ImageTracking を以下の疑似コードの処理で有効化します。 session_handle は NativeInterface.TrackingHandle で、trackable_image_database_directory は SessionConfig.TrackingImageDatabase.TrackingImageDataPath です。 TrackingImageDataPath は [Application.persistentDataPath]/TrackingImageData/[DB_GUID]/ です。
UInt64 config_handle; UInt64 trackable_image_database_handle; NRConfigCreate(session_handle, ref config_handle); NRTrackableImageDatabaseCreate(session_handle, ref trackable_image_database_handle); NRTrackableImageDatabaseLoadDirectory(session_handle, trackable_image_database_handle, trackable_image_database_directory); NRConfigSetTrackableImageDatabase(session_handle, config_handle, trackable_image_database_handle);
SessionConfig.ImageTrackingMode が DISABLE の場合には ImageTracking を以下の疑似コードの処理で無効化します。 session_handle は NativeInterface.TrackingHandle で、trackable_image_database_handle は有効化した時の値、trackable_image_database_handle は 0 です。
UInt64 config_handle; NRConfigCreate(session_handle, ref config_handle); NRTrackableImageDatabaseDestroy(session_handle, trackable_image_database_handle); NRConfigSetTrackableImageDatabase(session_handle, config_handle, trackable_image_database_handle);
以上で、初期化処理は終了です。TrackingImageDatabase のデータは RawData に保持しており、unzip した上で Load しています。
TrackingImageDatabaseInspector を読み解いてみる
概要
TrackingImageDatabase の生成を理解するために TrackingImageDatabaseInspector を読み解いてみます。 個人的な読解結果であるため誤りが含まれている可能性があることをご了承ください。
目次
確認環境
- NRSDK 1.2.1
- macOS 10.15
解説
拾い読み
ざっくりと TrackingImageDatabaseInspector を拾い読みすると、以下が要点になるのかなと思います。
- TrackingImageDatabaseInspector
- NRTrackingImageDatabase のインスペクターを表示する際
- UpdateDatabaseQuality を呼び出す
- BuildImage を呼び出す
- 出力先は [Application.persistentDataPath]/TrackingImageData/[DB_GUID]/markers.json
- TrackingImageDatabasePreprocessBuild の OnPreprocessBuild が実行される際
- BuildDataBase を呼び出す
- BuildImage を呼び出す
- 出力先は [Application.persistentDataPath]/TrackingImageData/[DB_GUID]/markers.json
- m_UpdatedQualityScores (JsonData) を更新する
- UpdateDatabaseQuality を呼び出す
- 呼び出した次に NRTrackingImageDatabase の BuildIfNeeded を呼び出す
- BuildIfNeeded では
- [Application.persistentDataPath]/TrackingImageData/[DB_GUID]/markers.json を読み込み
- [Application.persistentDataPath]/TrackingImageData/[DB_GUID]/markers.dat に書き込み
- [Application.persistentDataPath]/TrackingImageData/[DB_GUID] を [Application.persistentDataPath]/TrackingImageData/[DB_GUID]_zipFile にアーカイブ
- zip のバイナリを NRTrackingImageDatabase の m_RawData に保持する
- BuildIfNeeded では
- BuildImage を呼び出す
- BuildDataBase を呼び出す
- UpdateDatabaseQuality
- m_UpdatedQualityScores (JsonData) の内容を NRTrackingImageDatabaseEntry に設定する
- NRTrackingImageDatabaseEntry の Quality, Width, Height を設定する
- m_UpdatedQualityScores (JsonData) の内容を NRTrackingImageDatabaseEntry に設定する
- BuildImage
trackableImageTools_[os] -image_path="[imagePath]" -save_dir="[outPath]" -width="[imageWidth]"を ShellHelper.RunCommand で実行する
- NRTrackingImageDatabase のインスペクターを表示する際
要点の整理
拾い読んだ内容を整理すると、インスペクター表示やビルドを行う際に TrackingImageData ディレクトリに追跡対象画像の学習結果を保存していると思われます。 macOS では /Users/[Account]/Library/Application Support/DefaultCompany/[Project]/TrackingImageData/[DB_GUID]/ ディレクトリに保存されます。
TrackingImageData/[DB_GUID] ディレクトリの内容は以下の様になっています。
. ├── Data │ ├── nreal_city.fset │ ├── nreal_city.fset3 │ ├── nreal_city.iset │ ├── nreal_snake.fset │ ├── nreal_snake.fset3 │ ├── nreal_snake.iset │ ├── nreal_trib.fset │ ├── nreal_trib.fset3 │ └── nreal_trib.iset ├── markers.dat └── markers.json
さらに、markers.json と makers.dat の内容は以下の様になっています。
{
"is_use_world_cam" : 0,
"list" : [ "nreal_city", "nreal_snake", "nreal_trib" ],
"nreal_city" : {
"filter" : 50,
"info" : "20200422212420_30.72_1.79_2_2",
"physical_height" : 396.87496948242188,
"physical_width" : 396.87496948242188,
"train_score" : 70.502113342285156,
"type" : "NFT"
},
"nreal_snake" : {
"filter" : 50,
"info" : "20200422212420_30.72_1.79_2_2",
"physical_height" : 396.87496948242188,
"physical_width" : 396.87496948242188,
"train_score" : 64.339988708496094,
"type" : "NFT"
},
"nreal_trib" : {
"filter" : 50,
"info" : "20200422212420_30.72_1.79_2_2",
"physical_height" : 396.87496948242188,
"physical_width" : 396.87496948242188,
"train_score" : 68.515426635742188,
"type" : "NFT"
},
"pixel_format" : "MONO8",
"track_thread_num" : 8
}
# Number of markers 3 ./Data/nreal_city NFT FILTER 50 MARKER_WIDTH 396.874969482422 MARKER_HEIGHT 396.874969482422 ./Data/nreal_snake NFT FILTER 50 MARKER_WIDTH 396.874969482422 MARKER_HEIGHT 396.874969482422 ./Data/nreal_trib NFT FILTER 50 MARKER_WIDTH 396.874969482422 MARKER_HEIGHT 396.874969482422
そして、markers.json を生成するために以下のコマンドを実行しています。
trackableImageTools_[os] -image_path="[imagePath]" -save_dir="[outPath]" -width="[imageWidth]"
- os : osx/win/linux
- imagePath : Texture のパス
- outPath : TrackingImageData/[DB_GUID] ディレクトリのパス
- imageWidth : 画像の幅 [m]
ビルド時には、NRTrackingImageDatabase の BuildIfNeeded にて markers.json を markers.dat に変換し、TrackingImageData/[DB_GUID] ディレクトリ zip ファイル ([DB_GUID]_zipFile) にアーカイブしています。
また、NRTrackingImageDatabase は ScriptableObject であり以下の情報を保持しています。
- RawData : byte[]
- zip ファイルのバイナリデータ
- Images : List
- Name : string
- Width : float
- Height : float
- Quality : string
- TextureGUID : string
NRSDK の Native API を整理する
概要
NRSDK の Script から DllImport している部分を抽出しました。DLL 毎、ファイル毎に階層化して API を羅列します。 なお、nreal-examples/NativeApiFinder.cs at master · nosix/nreal-examples · GitHub を使って抽出しています。
目次
確認環境
- NRSDK 1.2.1
Native API
kernel32
NativeEmulator.cs
- bool FreeLibrary
- IntPtr hModule
NativeInterface.cs
- bool SetDllDirectory
- string lpPathName
NativeConstants.NRNativeLibrary
NativeEmulator.cs
NativeResult NRSIMTrackingCreate
- ref UInt64 out_tracking_handle
NativeResult NRSIMTrackingSetHeadTrackingPose
- UInt64 tracking_handle
- ref NativeVector3f position
- ref NativeVector4f rotation
NativeResult NRSIMTrackingUpdateTrackableImageData
- UInt64 tracking_handle
- ref NativeVector3f center_pos
- ref NativeVector4f center_rotation
- float extent_x
- float extent_z
- UInt32 identifier
- int state
NativeResult NRSIMTrackingUpdateTrackablePlaneData
- UInt64 tracking_handle
- ref NativeVector3f center_pos
- ref NativeVector4f center_rotation
- float extent_x
- float extent_z
- UInt32 identifier
- int state
NativeResult NRSIMControllerCreate
- ref UInt64 out_controller_handle
NativeResult NRSIMControllerDestroyAll
NativeResult NRSIMControllerSetTimestamp
- UInt64 controller_handle
- UInt64 timestamp
NativeResult NRSIMControllerSetPosition
- UInt64 controller_handle
- ref NativeVector3f position
NativeResult NRSIMControllerSetRotation
- UInt64 controller_handle
- ref NativeVector4f rotation
NativeResult NRSIMControllerSetAccelerometer
- UInt64 controller_handle
- ref NativeVector3f accel
NativeResult NRSIMControllerSetButtonState
- UInt64 controller_handle
- Int32 buttonState
NativeResult NRSIMControllerSetIsTouching
- UInt64 controller_handle
- bool isTouching
NativeResult NRSIMControllerSetTouchPoint
- UInt64 controller_handle
- ref NativeVector3f point
NativeResult NRSIMControllerSubmit
- UInt64 controller_handle
NRDevice.cs
- NativeResult NRSDKInitSetAndroidActivity
- IntPtr android_activity
NativeCamera.cs
NativeResult NRRGBCameraImageGetRawData
- UInt64 rgb_camera_handle
- UInt64 rgb_camera_image_handle
- ref IntPtr out_image_raw_data
- ref UInt32 out_image_raw_data_size
NativeResult NRRGBCameraImageGetResolution
- UInt64 rgb_camera_handle
- UInt64 rgb_camera_image_handle
- ref NativeResolution out_image_resolution
NativeResult NRRGBCameraImageGetHMDTimeNanos
- UInt64 rgb_camera_handle
- UInt64 rgb_camera_image_handle
- ref UInt64 out_image_hmd_time_nanos
NativeResult NRRGBCameraCreate
- ref UInt64 out_rgb_camera_handle
NativeResult NRRGBCameraDestroy
- UInt64 rgb_camera_handle
NativeResult NRRGBCameraSetCaptureCallback
- UInt64 rgb_camera_handle
- NRRGBCameraImageCallback image_callback
- UInt64 userdata
NativeResult NRRGBCameraSetImageFormat
- UInt64 rgb_camera_handle
- CameraImageFormat format
NativeResult NRRGBCameraStartCapture
- UInt64 rgb_camera_handle
NativeResult NRRGBCameraStopCapture
- UInt64 rgb_camera_handle
NativeResult NRRGBCameraImageDestroy
- UInt64 rgb_camera_handle
- UInt64 rgb_camera_image_handle
NativeConfigration.cs
NativeResult NRConfigCreate
- UInt64 session_handle
- ref UInt64 out_config_handle
NativeResult NRConfigDestroy
- UInt64 session_handle
- UInt64 config_handle
NativeResult NRConfigGetTrackablePlaneFindingMode
- UInt64 session_handle
- UInt64 config_handle
- ref TrackablePlaneFindingMode out_trackable_plane_finding_mode
NativeResult NRConfigSetTrackablePlaneFindingMode
- UInt64 session_handle
- UInt64 config_handle
- TrackablePlaneFindingMode trackable_plane_finding_mode
NativeResult NRConfigGetTrackableImageDatabase
- UInt64 session_handle
- UInt64 config_handle
- ref UInt64 out_trackable_image_database_handle
NativeResult NRConfigSetTrackableImageDatabase
- UInt64 session_handle
- UInt64 config_handle
- UInt64 trackable_image_database_handle
NativeController.cs
NativeResult NRControllerCreate
- ref UInt64 out_controller_handle
NativeResult NRControllerStart
- UInt64 controller_handle
NativeResult NRControllerPause
- UInt64 controller_handle
NativeResult NRControllerResume
- UInt64 controller_handle
NativeResult NRControllerStop
- UInt64 controller_handle
NativeResult NRControllerDestroy
- UInt64 controller_handle
NativeResult NRControllerGetCount
- UInt64 controller_handle
- ref int out_controller_count
NativeResult NRControllerGetAvailableFeatures
- UInt64 controller_handle
- int controller_index
- ref uint out_controller_available_features
NativeResult NRControllerGetType
- UInt64 controller_handle
- int controller_index
- ref ControllerType out_controller_type
NativeResult NRControllerRecenter
- UInt64 controller_handle
- int controller_index
NativeResult NRControllerStateCreate
- UInt64 controller_handle
- int controller_index
- ref UInt64 out_controller_state_handle
NativeResult NRControllerStateUpdate
- UInt64 controller_state_handle
NativeResult NRControllerStateDestroy
- UInt64 controller_state_handle
NativeResult NRControllerHapticVibrate
- UInt64 controller_handle
- int controller_index
- Int64 duration
- float frequency
- float amplitude
NativeResult NRControllerStateGetConnectionState
- UInt64 controller_state_handle
- ref ControllerConnectionState out_controller_connection_state
NativeResult NRControllerStateGetBatteryLevel
- UInt64 controller_state_handle
- ref int out_controller_battery_level
NativeResult NRControllerStateGetCharging
- UInt64 controller_state_handle
- ref int out_controller_charging
NativeResult NRControllerStateGetPose
- UInt64 controller_state_handle
- ref NativeMat4f out_controller_pose
NativeResult NRControllerStateGetGyro
- UInt64 controller_state_handle
- ref NativeVector3f out_controller_gyro
NativeResult NRControllerStateGetAccel
- UInt64 controller_state_handle
- ref NativeVector3f out_controller_accel
NativeResult NRControllerStateGetMag
- UInt64 controller_state_handle
- ref NativeVector3f out_controller_mag
NativeResult NRControllerStateGetButtonState
- UInt64 controller_state_handle
- ref uint out_controller_button_state
NativeResult NRControllerStateGetButtonUp
- UInt64 controller_state_handle
- ref uint out_controller_button_up
NativeResult NRControllerStateGetButtonDown
- UInt64 controller_state_handle
- ref uint out_controller_button_down
NativeResult NRControllerStateTouchState
- UInt64 controller_state_handle
- ref uint out_controller_touch_state
NativeResult NRControllerStateGetTouchUp
- UInt64 controller_state_handle
- ref uint out_controller_touch_up
NativeResult NRControllerStateGetTouchDown
- UInt64 controller_state_handle
- ref uint out_controller_touch_down
NativeResult NRControllerStateGetTouchPose
- UInt64 controller_state_handle
- ref NativeVector2f out_controller_touch_pose
NativeResult NRControllerSetHeadPose
- UInt64 controller_handle
- ref NativeMat4f out_controller_pose
NativeHeadTracking.cs
NativeResult NRHeadTrackingCreate
- UInt64 tracking_handle
- ref UInt64 outHeadTrackingHandle
NativeResult NRTrackingGetHMDTimeNanos
- UInt64 tracking_handle
- ref UInt64 out_hmd_time_nanos
NativeResult NRHeadTrackingGetRecommendPredictTime
- UInt64 tracking_handle
- UInt64 head_tracking_handle
- ref UInt64 out_predict_time_nanos
NativeResult NRHeadTrackingAcquireTrackingPose
- UInt64 sessionHandle
- UInt64 head_tracking_handle
- UInt64 hmd_time_nanos
- ref UInt64 out_tracking_pose_handle
NativeResult NRTrackingPoseGetPose
- UInt64 tracking_handle
- UInt64 tracking_pose_handle
- ref NativeMat4f out_pose
NativeResult NRTrackingPoseGetTrackingReason
- UInt64 tracking_handle
- UInt64 tracking_pose_handle
- ref LostTrackingReason out_tracking_reason
NativeResult NRTrackingPoseDestroy
- UInt64 tracking_handle
- UInt64 tracking_pose_handle
NativeResult NRHeadTrackingDestroy
- UInt64 tracking_handle
- UInt64 head_tracking_handle
NativeHMD.cs
NativeResult NRHMDCreate
- ref UInt64 out_hmd_handle
NativeResult NRHMDGetEyePoseFromHead
- UInt64 hmd_handle
- int eye
- ref NativeMat4f outEyePoseFromHead
NativeResult NRHMDGetEyeFov
- UInt64 hmd_handle
- int eye
- ref NativeFov4f out_eye_fov
NativeResult NRHMDGetEyeResolution
- UInt64 hmd_handle
- int eye
- ref NativeResolution out_eye_resolution
NativeResult NRHMDDestroy
- UInt64 hmd_handle
NativeMultiDisplay.cs
NativeResult NRDisplayCreate
- ref UInt64 out_display_handle
NativeResult NRDisplayPause
- UInt64 display_handle
NativeResult NRDisplayResume
- UInt64 display_handle
NativeResult NRDisplaySetMainDisplayTexture
- UInt64 display_handle
- IntPtr controller_texture
NativeResult NRDisplayDestroy
- UInt64 display_handle
NativePlane.cs
NativeResult NRTrackablePlaneGetType
- UInt64 session_handle
- UInt64 trackable_handle
- ref TrackablePlaneType out_plane_type
NativeResult NRTrackablePlaneGetCenterPose
- UInt64 session_handle
- UInt64 trackable_handle
- ref NativeMat4f out_center_pose
NativeResult NRTrackablePlaneGetExtentX
- UInt64 session_handle
- UInt64 trackable_handle
- ref float out_extent_x
NativeResult NRTrackablePlaneGetExtentZ
- UInt64 session_handle
- UInt64 trackable_handle
- ref float out_extent_z
NativeResult NRTrackablePlaneGetPolygonSize
- UInt64 session_handle
- UInt64 trackable_handle
- ref int out_polygon_size
NativeResult NRTrackablePlaneGetPolygon
- UInt64 session_handle
- UInt64 trackable_handle
- IntPtr out_polygon
NativeRenderring.cs
NativeResult NRRenderingCreate
- ref UInt64 out_rendering_handle
NativeResult NRRenderingStart
- UInt64 rendering_handle
NativeResult NRRenderingDestroy
- UInt64 rendering_handle
NativeResult NRRenderingPause
- UInt64 rendering_handle
NativeResult NRRenderingResume
- UInt64 rendering_handle
NativeResult NRRenderingInitSetAndroidSurface
NativeResult NRRenderingDoRender
- UInt64 rendering_handle
- IntPtr left_eye_texture
- IntPtr right_eye_texture
- ref NativeMat4f head_pose
NativeTrackable.cs
NativeResult NRTrackableListCreate
- UInt64 session_handle
- ref UInt64 out_trackable_list_handle
NativeResult NRTrackableListDestroy
- UInt64 session_handle
- UInt64 out_trackable_list_handle
NativeResult NRTrackableListGetSize
- UInt64 session_handle
- UInt64 trackable_list_handle
- ref int out_list_size
NativeResult NRTrackableListAcquireItem
- UInt64 session_handle
- UInt64 trackable_list_handle
- int index
- ref UInt64 out_trackable
NativeResult NRTrackableGetIdentifier
- UInt64 session_handle
- UInt64 trackable_handle
- ref UInt32 out_identifier
NativeResult NRTrackableGetType
- UInt64 session_handle
- UInt64 trackable_handle
- ref TrackableType out_trackable_type
NativeResult NRTrackableGetTrackingState
- UInt64 session_handle
- UInt64 trackable_handle
- ref TrackingState out_tracking_state
NativeTrackableImage.cs
NativeResult NRTrackableImageDatabaseCreate
- UInt64 session_handle
- ref UInt64 out_trackable_image_database_handle
NativeResult NRTrackableImageDatabaseDestroy
- UInt64 session_handle
- UInt64 trackable_image_database_handle
NativeResult NRTrackableImageDatabaseLoadDirectory
- UInt64 session_handle
- UInt64 trackable_image_database_handle
- string trackable_image_database_directory
NativeResult NRTrackableImageGetCenterPose
- UInt64 session_handle
- UInt64 trackable_handle
- ref NativeMat4f out_center_pose
NativeResult NRTrackableImageGetExtentX
- UInt64 session_handle
- UInt64 trackable_handle
- ref float out_extent_x
NativeResult NRTrackableImageGetExtentZ
- UInt64 session_handle
- UInt64 trackable_handle
- ref float out_extent_z
NativeTracking.cs
NativeResult NRTrackingCreate
- ref UInt64 out_tracking_handle
NativeResult NRTrackingInitSetTrackingMode
- UInt64 tracking_handle
- TrackingMode tracking_mode
NativeResult NRTrackingStart
- UInt64 tracking_handle
NativeResult NRTrackingDestroy
- UInt64 tracking_handle
NativeResult NRTrackingPause
- UInt64 tracking_handle
NativeResult NRTrackingResume
- UInt64 tracking_handle
NativeResult NRTrackingRecenter
- UInt64 tracking_handle
NativeResult NRTrackingUpdateTrackables
- UInt64 tracking_handle
- TrackableType trackable_type
- UInt64 out_trackable_list_handle
NativeVersion.cs
- NativeResult NRGetVersion
- ref NRVersion out_version
NRNativeEncodeLibrary
NativeEncoder.cs
int HWEncoderCreate
- ref UInt64 out_encoder_handle
int HWEncoderStart
- UInt64 encoder_handle
int HWEncoderSetConfigration
- UInt64 encoder_handle
- string config
int HWEncoderUpdateSurface
- UInt64 encoder_handle
- IntPtr texture_id
- UInt64 time_stamp
int HWEncoderStop
- UInt64 encoder_handle
int HWEncoderDestroy
- UInt64 encoder_handle
TrackingImageDatabase の生成を理解する
概要
ImageTracking を行うためには予め NRKernalSessionConfig に追跡対象を登録した TrackingImageDatabase (NRTrackingImageDatabase) を設定する必要があります。 TrackingImageDatabase は Unity Editor で生成します。 この記事では、TrackingImageDatabase の生成方法を説明し、生成を行っているソースコードを解読してみます。 個人的な読解結果であるため誤りが含まれている可能性があることをご了承ください。
目次
確認環境
- NRSDK 1.2.1
解説
TrackingImageDatabase の生成方法
TrackingImageDatabase を生成する手順は以下のとおりです。
- Texture を用意する
- Requirements は要注意
- JPEG (コードを読むと PNG にも対応している様子)
- grayscale or RGB color
- 150 dpi
- The dimensions of printed reference images < 1m2
- well-distributed feature points
- low degrees of self-similarity
- Adobe Photoshop よりは Adobe Illustrator で書き出すことを推奨
- Requirements は要注意
- Texture を選択する
- 複数登録する場合は複数選択する
- コンテキストメニュー Create/NRSDK/TrackingImageDatabase を選択する
- TrackingImageDatabase が生成される
TrackingImageDatabase を生成しているソースコードを解読する
TrackingImageDatabase を行っている Script は TrackingImageDatabaseContextMenu です。 TrackingImageDatabaseContextMenu では以下の処理を行っています。
- MenuItem に Assets/Create/NRSDK/TrackingImageDatabase を追加する
- 選択した ImagePath を取得する
- サポート対象となる ImagePath が指定されたときのみ以下を行う
- NRTrackingImageDatabase (ScriptableObject) を生成する
- 各 ImagePath に対して、NRTrackingImageDatabaseEntry を生成する
- imageName, Texture2D を指定
- NRTrackingImageDatabaseEntry を imageName 順に並べ替え
- NRTrackingImageDatabase に NRTrackingImageDatabaseEntry を追加する
- NRTrackingImageDatabase を TrackingImageDatabase.asset として保存する
NRTrackingImageDatabase
NRTrackImageDatabase は ScriptableObject です。 Unity Editor で NRTrackingImageDatabaseEntry を登録し、実機で動かす場合には NRTrackingImageDatabaseEntry の参照だけを行います。 そのため、Add, RemoveAt, NRTrackingImageDatabaseEntry の set などの編集 API は Unity Editor のときのみ有効になっています。 また、NRTrackingImageDatabaseEntry の Width, Heigh, Quality を編集する処理は含まれていません。 これらの処理は TrackingImageDatabaseInspector で行っています。
NRTrackingImageDatabaseEntry
以下を保持する構造体です。
- Name : string
- Width : float
- Height : float
- Quality : string
- TextureGUID : string
TrackingImageDatabaseContextMenu では、Name と Texture を指定して生成しています。 Texture 自身を保持せずに Texture の識別子 TextureGUID を保持して、Texture を求められた際には Texture を Load しています。 Width, Height, Quality は 0 や空文字列が設定されます。
RGBCamera-Record を読み解いてみる
概要
RGBCamera-Capture を読み解いてみる - NOSIX に引き続き、 RGB Camera の使い方を理解するために、 サンプルとして提供されている RGBCamera-Record (Scene) のソースコードを解読してみます。 個人的な読解結果であるため誤りが含まれている可能性があることをご了承ください。
目次
確認環境
- NRSDK 1.2.1
解説
RGBCamera-Capture を読み解いてみる - NOSIX と重複している内容は省略しています。
Video Capture に関連するのは VideoCaptureExample (GameObject) の部分です。 PlaneDetector, Canvas は Video Capture には関係ありません。 そのため、これらの説明は省略します。
Video Capture を行うためには NRVideoCapture を使います。 録画した Video は StartRecordingAsync の引数で指定する Path に保存されます。 また、Previewer の Texture に NRVideoCapture の PreviewTexture を設定することでプレビューを行っています。
Hierarchy
- RGBCamera-Record (Scene)
- NRCameraRig (Perfab)
- NRInput (Prefab)
- NRLogo (Prefab)
- Directional Light : 上から差し込むライト
- [C] Light
- VideoCaptureExample
- [C] VideoCapture2LocalExample
- Previewer (Prefab)
- PlaneDetector
- [C] PlaneDetector
- [C] HelloMRController
- Canvas
Scripts
VideoCaptureExample の Scripts
- VideoCapture2LocalExample (in Demos/Record/Scripts/VideoCapture2LocalExample)
- Inspector での設定項目
- Previewer
- 起動時に NRVideoCapture インスタンスを生成する
- NRVideoCapture.CreateAsync を使う
- startBtn 押下時に NRVideoCapture.StartVideoModeAsync を行う
- Previewer.SetData で NRVideoCapture.PreviewTexture と再生中を設定する
- CameraParameters で Camera 設定を行う
- NRVideoCapture.SupportedResolutions で有効な resolution を取得して CameraParameters に使う
- NRVideoCapture.GetSupportedFrameRatesForResolution で有効な frame rate を取得して CameraParameters に使う
- NRVideoCapture.AudioState.ApplicationAndMicAudio を設定する
- Start に成功した時、NRVideoCapture.StartRecordingAsync を行う
- 保存先の Path を指定する
- stopBtn 押下時に NRVideoCapture.StopRecordingAsync を行う
- Previewer.SetData で NRVideoCapture.PreviewTexture と停止中を設定する
- Stop に成功した時、NRVideoCapture.StopVideoModeAsync を行う
- Inspector での設定項目
PlaneDetector の Scripts
RGBCamera-Capture を読み解いてみる
概要
RGBCamera を読み解いてみる - NOSIX に引き続き、 RGB Camera の使い方を理解するために、 サンプルとして提供されている RGBCamera-Capture (Scene) のソースコードを解読してみます。 個人的な読解結果であるため誤りが含まれている可能性があることをご了承ください。
目次
確認環境
- NRSDK 1.2.1
解説
RGBCamera を読み解いてみる - NOSIX と重複している内容は省略しています。
このサンプルは以下の 2 つの機能のサンプルになっています。これらは同時に使わずに別々に使うことができます。
- PhotoCapture
- Previewer
PhotoCapture は静止画の Texture2D を取得する機能です。 このサンプルでは、Trigger ボタン (マウスの左ボタンクリックで Emulate される) で静止画が撮影され、目の前に静止画が表示されます。 また、目の前に表示するだけではなく Previewer にも表示します。 PhotoCaptureExample (Script) で処理方法は確認できます。 NRPhotoCapture クラスを使うことで実現しています。
Previewer は撮影した画像 (Texture2D) をプレビューする機能です。 このサンプルでは、App ボタン (Emulator では Space キーでも可) でプレビューの On/Off を切り替えます。 Previewer を On にすると右手コントローラーの付近にプレビューが表示されます。 Previewer を Off にすると Raycast の Laser と Reticle が表示されます。 Previewer (Prefab) を追加して、Previewer.SetData をいずれかの Script から呼び出して使用します。 このサンプルでは、PhotoCaptureExample (Script) で静止画を撮影した際に Previewer.SetData を呼び出してプレビューを更新しています。 Previewer には State Icon があり、再生中は緑、停止中は赤になります。 この再生中の状態も Previewer.SetData で設定します。 このサンプルでは、停止中に設定されることがないため赤に変わりません。
Hierarchy
RGBCamera-Capture (Scene)
- NRCameraRig (Perfab)
- NRInput (Prefab)
- NRLogo (Prefab)
- [C] AutoRotate : Mesh を回転させる
- offset
- nreal_logo
- [C] Mesh Renderer
- nreal_logo
- PhotoCaptureExample
- [C] PhotoCaptureExample
- Previewer (Prefab)
- Directional Light : 上から差し込むライト
- [C] Light
-
- [C] Canvas
- [C] NRPreviewer
- Root : Rotation X で 90 度回転している (Laser と水平)
- PreviewScreen
- [C] RawImage
- StateIcon
- [C] Image
- PreviewScreen
Scripts
PhotoCaptureExample の Scripts
- PhotoCaptureExample (in Demos/Record/Scripts/PhotoCaptureExample)
- Inspector での設定項目
- Previewer
- 起動時に RGB Camera を Activate する
- Trigger ボタン、もしくは、T キーで、写真を撮影する
- Home ボタン、もしくは、Q キーで、RGB Camera を Deactivate する
- App ボタン、もしくは、O キーで、RGB Camera を Activate する
- NRPhotoCapture が生成されているならば、Previewer.SetData を呼び出し、Previerwer に Texture2D と状態を設定する
- Deactivate しても Previewer の状態は変更されない
- Deactivate すると NRPhotoCapture が破棄されて Previewer.SetData が呼び出されなくなるため
- Deactivate しても Previewer の状態は変更されない
- Activate の手順は
- Deactivate の手順は
- NRPhotoCapture.StopPhotoModeAsync を呼び出す
- 完了通知コールバックで、NRPhotoCapture.Dispose()
- 写真を撮影する手順は
- NRPhotoCapture.TakePhotoAsync を呼び出す
- 撮影成功すると PhotoCaptureFrame インスタンスが得られる
- PhotoCaptureFrame.UploadImageDataToTexture で Texture2D を更新する
- 撮影した画像の Quad を生成して、目の前に表示する
- NRSessionManager から NRHMDPoseTracker を取得し、Center Camera の位置を取得する
- Center Camera の前方に Quad の位置を設定する
- Quad の Material に Texture2D を設定する
- Inspector での設定項目
Previewer の Scripts
- NRPreviewer (in Scripts/Capture)
- Inspector での設定項目
- Root
- Preview Screen : PreviewScreen (RawImage)
- State Icon : StateIcon (Image)
- Is Bind To Controller : true
- App ボタン、もしくは、Space キーで以下を切り替える
- Controller の Laser, Reticle 表示
- Root (GameObject) の表示
- Is Bind To Controller が true ならば、Controller (Right) の ModelAnchor から forward 方向に 0.3 の位置に Previewer (GameObject) を表示する
- false ならば、Unity Editor で設定した位置になる
- Inspector での設定項目