HolographicSpace を入手する
Note
この記事は、従来のWinRTネイティブAPIに関連します。 新しいネイティブ アプリ プロジェクトの場合は、OpenXR API を使用することをお勧めします。
HolographicSpaceクラスは、ホログラフィック世界への入り口です。 イマーシブレンダリングを制御し、カメラデータを提供し、空間的推論APIへのアクセス権を与えます。 UWPアプリのCoreWindowまたはWin32アプリのHWNDのために1つ作成します。
ホログラフィックスペースをセットアップします。
ホログラフィックスペースオブジェクトの作成は、Windows Mixed Realityアプリを作り出すための最初のステップです。 従来のWindowsアプリは、アプリケーションビューのコアウィンドウのために作成されたDirect3Dスワップチェーンにレンダリングされます。 このスワップチェーンは、ホログラフィックUI内のスレートに表示されます。 アプリケーションビューを2Dスレートではなくホログラフィックにするには、スワップチェーンではなく、コアウィンドウのためのホログラフィックスペースを作成します。 このホログラフィックスペースで作成されたホログラフィックフレームを表示すると、アプリを全画面レンダリングモードにします。
Holographic DirectX 11 App (ユニバーサル Windows) テンプレートから AppView.cppの SetWindow メソッドで次のコードを探します。
m_holographicSpace = HolographicSpace::CreateForCoreWindow(window);
Win32 アプリをビルドする場合は BasicHologram Win32 サンプルから始めて、HWND の例については、App::CreateWindowAndHolographicSpace を参照してください。 次に、関連付けられたHolographicSpaceを作成することで、それをイマーシブHWNDに変換できます。
void App::CreateWindowAndHolographicSpace(HINSTANCE hInstance, int nCmdShow)
{
// Store the instance handle in our class variable.
m_hInst = hInstance;
// Create the window for the HolographicSpace.
hWnd = CreateWindowW(
m_szWindowClass,
m_szTitle,
WS_VISIBLE,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
nullptr,
nullptr,
hInstance,
nullptr);
if (!hWnd)
{
winrt::check_hresult(E_FAIL);
}
{
// Use WinRT factory to create the holographic space.
using namespace winrt::Windows::Graphics::Holographic;
winrt::com_ptr<IHolographicSpaceInterop> holographicSpaceInterop =
winrt::get_activation_factory<HolographicSpace, IHolographicSpaceInterop>();
winrt::com_ptr<ABI::Windows::Graphics::Holographic::IHolographicSpace> spHolographicSpace;
winrt::check_hresult(holographicSpaceInterop->CreateForWindow(
hWnd, __uuidof(ABI::Windows::Graphics::Holographic::IHolographicSpace),
winrt::put_abi(spHolographicSpace)));
if (!spHolographicSpace)
{
winrt::check_hresult(E_FAIL);
}
// Store the holographic space.
m_holographicSpace = spHolographicSpace.as<HolographicSpace>();
}
// The DeviceResources class uses the preferred DXGI adapter ID from the holographic
// space (when available) to create a Direct3D device. The HolographicSpace
// uses this ID3D11Device to create and manage device-based resources such as
// swap chains.
m_deviceResources->SetHolographicSpace(m_holographicSpace);
// The main class uses the holographic space for updates and rendering.
m_main->SetHolographicSpace(hWnd, m_holographicSpace);
// Show the window. This will activate the holographic view and switch focus
// to the app in Windows Mixed Reality.
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
}
UWP CoreWindow用またはWin32 HWND用のHolographicSpaceを取得すると、HolographicSpaceはホログラフィックカメラを処理し、座標系を作成し、ホログラフィックレンダリングを実行できます。 現在のホログラフィックスペースは、DirectXテンプレートの複数の場所で使用されます。
- DeviceResourcesクラスは、Direct3Dデバイスを作成するために、HolographicSpaceオブジェクトから情報をいくつか取得する必要があります。 これは、ホログラフィックディスプレイに関連付けられるDXGIアダプターIDです。 HolographicSpaceクラスは、アプリのDirect3D 11デバイスを使用して、各ホログラフィックカメラ用のバックバッファーなどのデバイスベースのリソースを作成し管理します。 この関数の内部処理については、DeviceResources.cppを参照してください。
- 関数DeviceResources::InitializeUsingHolographicSpaceは、LUIDを検索することでアダプターを取得する方法と、優先アダプターが指定されていない場合に既定のアダプターを選択する方法を示します。
- アプリのメインクラスは、更新とレンダリングのために AppView::SetWindowまたはApp::CreateWindowAndHolographicSpaceからのホログラフィックスペースを使用します。
Note
以下のセクションでは、ホログラフィックUWPアプリテンプレートから開始したことを前提として、AppView::SetWindowなどのテンプレートの関数名について言及しますが、表示されるコードスニペットは、UWPアプリとWin32アプリの間でも同様に適用されます。
次に、SetHolographicSpaceがAppMainクラスで役割を果たすセットアッププロセスについて説明します。
カメライベントをサブスクライブし、カメラリソースを作成し削除します。
アプリのホログラフィックコンテンツはホログラフィックスペースに存在し、1つ以上のホログラフィックカメラを介して表示され、シーン上のさまざまなパースペクティブを表します。 ここで、ホログラフィックスペースが作成されたため、ホログラフィックカメラ用のデータを受信できます。
アプリは、そのカメラに固有の任意のリソースを作成することで、CameraAddedイベントに応答する必要があります。 そのリソースの一例として、バックバッファーレンダーターゲットビューがあります。 このコードは、アプリがホログラフィックフレームを作成する前にAppView::SetWindowで呼び出されるDeviceResources::SetHolographicSpace関数で見つかることができます。
m_cameraAddedToken = m_holographicSpace.CameraAdded(
std::bind(&AppMain::OnCameraAdded, this, _1, _2));
また、そのカメラのために作成されたリソースを解放することで、CameraRemovedイベントに応答する必要もあります。
DeviceResources::SetHolographicSpaceから:
m_cameraRemovedToken = m_holographicSpace.CameraRemoved(
std::bind(&AppMain::OnCameraRemoved, this, _1, _2));
ホログラフィックレンダリングが円滑に行われ、アプリが完全にレンダリングされるようにするには、イベントハンドラーは一部の作業を完了する必要があります。 詳細については、コードとコメントをご覧ください。メインクラスでOnCameraAddedとOnCameraRemovedを探し、DeviceResourcesによってm_cameraResourcesマップがどのように処理されるかを理解できます。
ここでは、AppMainと、アプリがホログラフィックカメラを認識することを可能にするセットアップに焦点を合わせます。 この点を考慮して、次の2つの要件に注意することが重要です。
CameraAddedイベントハンドラーでは、アプリは非同期で動作して、新しいホログラフィックカメラのためにリソースの作成とアセットの読み込みを完了できます。 この処理を完了するために複数のフレームを使用するアプリは、遅延を要求し、非同期でロードした後に遅延を完了する必要があります。 PPLタスクは、非同期作業を実行するために使用できます。 アプリは、イベントハンドラーを終了するとき、または遅延を完了するときに、すぐにそのカメラにレンダリングする準備ができていることを確認する必要があります。 イベントハンドラーを終了するか、または遅延を完了すると、アプリがそのカメラを含むホログラフィックフレームを受信する準備ができていることをシステムに通知します。
アプリがCameraRemovedイベントを受信するとき、バックバッファーへのすべての参照をリリースし、すぐに関数を終了する必要があります。 これには、レンダーターゲットビュー、およびIDXGIResourceへの参照を保持する可能性のあるその他のリソースが含まれます。 CameraResources::ReleaseResourcesForBackBufferに示すように、アプリはまた、バックバッファーがレンダーターゲットとしてアタッチされていないことも確認する必要があります。 処理速度を上げるために、アプリはバックバッファーを解放してから、カメラに対する他の破棄作業を非同期的に完了するタスクを起動できます。 ホログラフィックアプリテンプレートには、この目的で使用できるPPLタスクが含まれます。
Note
追加または削除されたカメラがフレームにいつ表示されるかを確認するには、 HolographicFrame AddedCameras および RemovedCameras プロパティを使用します。
ホログラフィックコンテンツの参照フレームを作成します。
アプリのコンテンツは、HolographicSpaceにレンダリングされる空間座標系に配置される必要があります。 システムは、ホログラムの座標系を確立するために使用できる2つの主要な参照フレームを提供します。
Windows Holographicには、2種類の参照フレームがあり、それらは、デバイスに接続された参照フレームと、デバイスがユーザーの環境内を移動しても静止したままの参照フレームです。 ホログラフィックアプリテンプレートは、既定で静止参照フレームを使用し、これは、世界ロックされたホログラムをレンダリングする最も簡単な方法の1つです。
静止参照フレームは、デバイスの現在の場所の近くに位置を安定させるように設計されます。 これは、デバイスが周囲の空間についてより多くを学習するため、デバイスから離れた座標がユーザーの環境に対してわずかにドリフトする可能性があることを意味します。 静止参照フレームを作成するには、空間ステージから座標系を取得する方法と、既定のSpatialLocatorを使用する方法の2つがあります。 イマーシブヘッドセット用のWindows Mixed Realityアプリを作成している場合、推奨される開始点は空間ステージです。 空間ステージは、プレーヤーによって装着されるイマーシブヘッドセットの機能に関する情報も提供します。 ここでは、既定のSpatialLocatorの使用方法について説明します。
空間ロケーターはWindows Mixed Realityデバイスを表し、デバイスの動作を追跡し、その場所に関連して理解できる座標系を提供します。
AppMain::OnHolographicDisplayIsAvailableChangedから:
spatialLocator = SpatialLocator::GetDefault();
アプリの起動時に、静止参照フレームを1回作成します。 これは、アプリの起動時に原点がデバイスの位置に配置された、世界座標系の定義に類似します。 この参照フレームは、デバイスと共に移動しません。
AppMain::SetHolographicSpaceから:
m_stationaryReferenceFrame =
m_spatialLocator.CreateStationaryFrameOfReferenceAtCurrentLocation();
すべての参照フレームは重力によって整列され、すなわち、y軸はユーザーの環境に対して「上」を指します。 Windowsが「右手」座標系を使用するため、–z軸の方向は、参照フレームが作成されたときにデバイスが向いている「前方」方向と一致します。
Note
アプリが個々のホログラムを正確に配置する必要がある場合、SpatialAnchorを使用して、個々のホログラムを実世界の位置に固定します。 たとえば、ユーザーが特に関心のあるポイントを指定する場合、空間アンカーを使用します。 アンカー位置はドリフトしませんが、調整可能です。 既定では、アンカーを調整するとき、修正が発生した後に、その位置を次の複数のフレームに簡単に配置できます。 アプリケーションによっては、これが発生するとき、(たとえば、ホログラムが非表示になるまで遅延させることで)異なるの手段で調整を処理したい場合があります。 RawCoordinateSystemプロパティとRawCoordinateSystemAdjustedイベントは、これらのカスタマイズを有効にします。
ロケータビリティが変更されたイベントに応答します。
世界ロックされたホログラムをレンダリングして、デバイス自体をこの世界に位置決めする必要があります。 これは、環境条件のために常に可能であるとは限らず、その場合、ユーザーは追跡の中断を視覚的に示すことを予想できます。 この視覚的表示は、世界に静止するのではなく、デバイスに接続されている参照フレームを使用してレンダリングする必要があります。
アプリは、何らかの理由で追跡が中断された場合、通知を要求できます。 LocatabilityChangedイベントに登録して、デバイスがこの世界内で自体を位置決めする能力が変化するときを検出します。 AppMain::SetHolographicSpaceから:
m_locatabilityChangedToken = m_spatialLocator.LocatabilityChanged(
std::bind(&HolographicApp6Main::OnLocatabilityChanged, this, _1, _2));
次に、このイベントを使用して、ホログラムをこの世界に静止してレンダリングできないタイミングを判断します。