注:
この記事は、従来の WinRT ネイティブ API に関連しています。 新しいネイティブ アプリ プロジェクトの場合は、 OpenXR API を使用することをお勧めします。
HolographicSpace クラスは、ホログラフィックワールドへのポータルです。 イマーシブ レンダリングを制御し、カメラ データを提供し、空間推論 API へのアクセスを提供します。 UWP アプリの CoreWindow または Win32 アプリの HWND 用に作成します。
ホログラフィック空間を設定する
ホログラフィック空間オブジェクトの作成は、Windows Mixed Reality アプリを作成する最初の手順です。 従来の Windows アプリは、アプリケーション ビューのコア ウィンドウ用に作成された Direct3D スワップ チェーンにレンダリングされます。 このスワップ チェーンは、ホログラフィック UI のスレートに表示されます。 アプリケーションで 2D スレートではなくホログラフィックを表示するには、スワップ チェーンではなく、コア ウィンドウ用のホログラフィック空間を作成します。 このホログラフィック空間によって作成されたホログラフィック フレームを表示すると、アプリが全画面表示レンダリング モードになります。
Holographic DirectX 11 アプリ (ユニバーサル Windows) テンプレートから始まるUWP アプリについては、AppView.cppの SetWindow メソッドで次のコードを探します。
m_holographicSpace = HolographicSpace::CreateForCoreWindow(window);
BasicHologram Win32 サンプルから始まる 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 のホログラフィック空間を更新とレンダリングに使用します。
注:
以下のセクションメンション、ホログラフィック UWP アプリ テンプレートから開始したことを前提とする AppView::SetWindow などのテンプレートの関数名を示していますが、表示されるコード スニペットは UWP アプリと Win32 アプリ間で均等に適用されます。
次に、 AppMain クラスで SetHolographicSpace が担当するセットアップ プロセスについて説明します。
カメラ イベントのサブスクライブ、カメラ リソースの作成、削除
アプリのホログラフィック コンテンツはホログラフィック空間に存在し、シーン上の異なるパースペクティブを表す 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 を探して、m_cameraResources マップが DeviceResources によってどのように処理されるかを理解できます。
現時点では、AppMain と、アプリがホログラフィック カメラについて知るために行うセットアップに焦点を当てています。 これを念頭に置いて、次の 2 つの要件に注意することが重要です。
CameraAdded イベント ハンドラーの場合、アプリは非同期的に動作して、新しいホログラフィック カメラのリソースの作成とアセットの読み込みを完了できます。 この作業を完了するために複数のフレームを要するアプリは、遅延を要求し、非同期的に読み込んだ後に遅延を完了する必要があります。 PPL タスクを使用して非同期作業を実行できます。 アプリは、イベント ハンドラーを終了したとき、または遅延が完了したときに、すぐにそのカメラにレンダリングする準備ができていることを確認する必要があります。 イベント ハンドラーを終了するか、遅延を完了すると、アプリがそのカメラを含むホログラフィック フレームを受け取る準備ができていることがシステムに通知されます。
アプリが CameraRemoved イベントを受け取ったら、バック バッファーへのすべての参照を解放し、関数をすぐに終了する必要があります。 これには、レンダー ターゲット ビューと、 IDXGIResource への参照を保持する可能性があるその他のリソースが含まれます。 アプリでは、 CameraResources::ReleaseResourcesForBackBuffer に示すように、バック バッファーがレンダー ターゲットとしてアタッチされていないことも確認する必要があります。 速度を上げるために、アプリはバック バッファーを解放してから、タスクを起動して、カメラの他の破棄作業を非同期的に完了できます。 ホログラフィック アプリ テンプレートには、この目的で使用できる PPL タスクが含まれています。
注:
フレームに追加または削除されたカメラが表示されるタイミングを決定する場合は、 HolographicFrameAddedCameras プロパティと RemovedCameras プロパティを 使用します。
ホログラフィック コンテンツの参照フレームを作成する
HolographicSpace でレンダリングするには、アプリのコンテンツを 空間座標系 に配置する必要があります。 システムには、ホログラムの座標系を確立するために使用できる 2 つの主要な参照フレームが用意されています。
Windows Holographic には、2 種類の参照フレームがあります。デバイスにアタッチされた参照フレームと、デバイスがユーザーの環境を移動しても静止したままの参照フレームです。 ホログラフィック アプリ テンプレートでは、既定で固定参照フレームが使用されます。これは、ワールド ロックホログラムをレンダリングする最も簡単な方法の 1 つです。
静止した参照フレームは装置の現在の位置の近くの位置を安定させるように設計されている。 つまり、デバイスの周囲の領域について詳しく学習すると、デバイスから離れた座標がユーザーの環境に対してわずかにドリフトする可能性があります。 固定参照フレームを作成するには、 空間ステージから座標系を取得するか、既定の SpatialLocator を使用する方法の 2 つの方法があります。 イマーシブ ヘッドセット用のWindows Mixed Reality アプリを作成する場合、推奨される開始点は空間ステージです。 空間ステージでは、プレイヤーが着用するイマーシブ ヘッドセットの機能に関する情報も提供されます。 ここでは、既定の SpatialLocator を使用する方法を示します。
空間ロケーターは、Windows Mixed Reality デバイスを表し、デバイスのモーションを追跡し、その位置を基準として理解できる座標系を提供します。
From AppMain::OnHolographicDisplayIsAvailableChanged:
spatialLocator = SpatialLocator::GetDefault();
アプリの起動時に固定参照フレームを 1 回作成します。 これは、アプリの起動時に原点をデバイスの位置に配置して、ワールド座標系を定義することに似ています。 この参照フレームは、デバイスと共に移動しません。
AppMain::SetHolographicSpace から:
m_stationaryReferenceFrame =
m_spatialLocator.CreateStationaryFrameOfReferenceAtCurrentLocation();
すべての参照フレームは重力揃えです。つまり、y 軸はユーザーの環境に関連して "上" を指します。 Windows では "右利き" 座標系が使用されるため、–z 軸の方向は、参照フレームの作成時にデバイスが向いている "前方" 方向と一致します。
注:
アプリで個々のホログラムを正確に配置する必要がある場合は、 SpatialAnchor を 使用して、個々のホログラムを現実世界の位置に固定します。 たとえば、ユーザーが特別な関心を持つポイントを示す場合は、空間アンカーを使用します。 アンカー位置はドリフトしませんが、調整できます。 既定では、アンカーを調整すると、修正が発生した後の次のいくつかのフレームに対する位置が容易になります。 アプリケーションによっては、これが発生した場合は、調整を別の方法で処理する必要があります (たとえば、ホログラムが表示されなくなっているまで調整を遅延させるなど)。 RawCoordinateSystem プロパティと RawCoordinateSystemAdjusted イベントを使用すると、これらのカスタマイズが可能になります。
場所の変更されたイベントに対応する
ワールド ロックホログラムをレンダリングするには、デバイスがワールド内でそれ自体を見つける必要があります。 これは、環境条件のために常に可能であるとは限らず、その場合、追跡の中断を視覚的に示す可能性があります。 この視覚的表示は、デバイスにアタッチされた参照フレームを使用してレンダリングする必要があります。これは、ワールドに固定されるのではなくです。
アプリは、何らかの理由で追跡が中断された場合に通知を要求できます。 LocateabilityChanged イベントに登録して、デバイスがワールド内で自身を見つける能力がいつ変化するかを検出します。 AppMain::SetHolographicSpace から:
m_locatabilityChangedToken = m_spatialLocator.LocatabilityChanged(
std::bind(&HolographicApp6Main::OnLocatabilityChanged, this, _1, _2));
次に、このイベントを使用して、ホログラムをワールドに固定してレンダリングできないタイミングを判断します。