Uzyskiwanie przestrzeni holograficznej
Uwaga
Ten artykuł dotyczy starszych natywnych interfejsów API winRT. W przypadku nowych projektów aplikacji natywnych zalecamy używanie interfejsu API OpenXR.
Klasa HolographicSpace jest portalem w świecie holograficznym. Steruje renderowaniem immersywnym, udostępnia dane aparatu i zapewnia dostęp do interfejsów API rozumowania przestrzennego. Utworzysz jedną dla podstawowego systemu Windows aplikacji platformy uniwersalnej systemu Windows lub HWND aplikacji Win32.
Konfigurowanie przestrzeni holograficznej
Tworzenie obiektu przestrzeni holograficznej jest pierwszym krokiem w tworzeniu aplikacji Windows Mixed Reality. Tradycyjne aplikacje systemu Windows są renderowane w łańcuchu zamiany Direct3D utworzonym dla podstawowego okna widoku aplikacji. Ten łańcuch wymiany jest wyświetlany na łupku w interfejsie użytkownika holograficznego. Aby utworzyć widok holograficzny aplikacji, a nie łupek 2D, utwórz przestrzeń holograficzną dla okna podstawowego zamiast łańcucha wymiany. Prezentowanie ramek holograficznych tworzonych przez tę przestrzeń holograficzną powoduje przełączenie aplikacji w tryb renderowania pełnoekranowego.
W przypadku aplikacji platformy UWP rozpoczynającej się od szablonu aplikacji Holographic DirectX 11 (uniwersalnego systemu Windows) poszukaj tego kodu w metodzie SetWindow w AppView.cpp:
m_holographicSpace = HolographicSpace::CreateForCoreWindow(window);
Jeśli tworzysz aplikację Win32, zaczynając od przykładu BasicHologram Win32, zapoznaj się z tematem App::CreateWindowAndHolographicSpace dla przykładu HWND. Następnie można przekonwertować go na immersywny HWND, tworząc skojarzony holographicspace:
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);
}
Po uzyskaniu holographicspace dla systemu UWP CoreWindow lub Win32 HWND HolographicSpace może obsługiwać kamery holograficzne, tworzyć układy współrzędnych i wykonywać renderowanie holograficzne. Bieżąca przestrzeń holograficzna jest używana w wielu miejscach w szablonie DirectX:
- Klasa DeviceResources musi uzyskać informacje z obiektu HolographicSpace w celu utworzenia urządzenia Direct3D. Jest to identyfikator karty DXGI skojarzony z wyświetlaczem holograficznym. Klasa HolographicSpace używa urządzenia Direct3D 11 aplikacji do tworzenia zasobów opartych na urządzeniach i zarządzania nimi, takich jak wsteczne dla każdej kamery holograficznej. Jeśli chcesz zobaczyć, co ta funkcja robi pod maską, znajdziesz ją w DeviceResources.cpp.
- Funkcja DeviceResources::InitializeUsingHolographicSpace pokazuje, jak uzyskać adapter, wyszukując identyfikator LUID i jak wybrać kartę domyślną, gdy nie określono preferowanej karty.
- Główna klasa aplikacji używa przestrzeni holograficznej z elementu AppView::SetWindow lub App::CreateWindowAndHolographicSpace na potrzeby aktualizacji i renderowania.
Uwaga
W poniższych sekcjach wymieniono nazwy funkcji z szablonu, takie jak AppView::SetWindow , które zakładają, że rozpoczęto od szablonu aplikacji holograficznej platformy UWP, widoczne fragmenty kodu będą stosowane równie w aplikacjach platformy UWP i Win32.
Następnie przejdziemy do procesu konfiguracji, za który odpowiada SetHolographicSpace w klasie AppMain.
Subskrybowanie zdarzeń aparatu, tworzenie i usuwanie zasobów aparatu
Zawartość holograficzna twojej aplikacji znajduje się w przestrzeni holograficznej i jest oglądana przez co najmniej jedną kamerę holograficzną, która reprezentuje różne perspektywy na scenie. Teraz, gdy masz przestrzeń holograficzną, możesz odbierać dane dla kamer holograficznych.
Aplikacja musi reagować na zdarzenia CameraAdded , tworząc wszystkie zasoby specyficzne dla tego aparatu. Przykładem takiego zasobu jest widok docelowy renderowania buforu wstecznego. Ten kod można zobaczyć w funkcji DeviceResources::SetHolographicSpace o nazwie AppView::SetWindow , zanim aplikacja utworzy dowolne ramki holograficzne:
m_cameraAddedToken = m_holographicSpace.CameraAdded(
std::bind(&AppMain::OnCameraAdded, this, _1, _2));
Aplikacja musi również reagować na zdarzenia CameraRemoved , zwalniając zasoby utworzone dla tego aparatu.
W obszarze DeviceResources::SetHolographicSpace:
m_cameraRemovedToken = m_holographicSpace.CameraRemoved(
std::bind(&AppMain::OnCameraRemoved, this, _1, _2));
Programy obsługi zdarzeń muszą wykonać pewną pracę, aby zapewnić bezproblemowe przepływy renderowania holograficznego, a renderowanie aplikacji w ogóle. Przeczytaj kod i komentarze, aby uzyskać szczegółowe informacje: możesz wyszukać elementy OnCameraAdded i OnCameraRemoved w klasie głównej, aby dowiedzieć się, jak mapa m_cameraResources jest obsługiwana przez deviceResources.
W tej chwili koncentrujemy się na aplikacji AppMain i konfiguracji, która umożliwia aplikacji poznanie kamer holograficznych. Mając to na uwadze, należy wziąć pod uwagę następujące dwa wymagania:
W przypadku programu obsługi zdarzeń CameraAdded aplikacja może działać asynchronicznie, aby zakończyć tworzenie zasobów i ładowanie zasobów dla nowej kamery holograficznej. Aplikacje, które zajmują więcej niż jedną ramkę, aby ukończyć tę pracę, powinny zażądać odroczenia i zakończyć odroczenie po asynchronicznym ładowaniu. Zadanie PPL może służyć do wykonywania asynchronicznej pracy. Aplikacja musi mieć pewność, że jest gotowa do renderowania do tego aparatu od razu po zakończeniu obsługi zdarzeń lub zakończeniu odroczenia. Zamknięcie programu obsługi zdarzeń lub ukończenie odroczenia informuje system, że aplikacja jest teraz gotowa do odbierania ramek holograficznych z dołączonym aparatem.
Gdy aplikacja odbierze zdarzenie CameraRemoved , musi zwolnić wszystkie odwołania do buforu wstecznego i zamknąć funkcję od razu. Obejmuje to renderowanie widoków docelowych i wszelkie inne zasoby, które mogą zawierać odwołanie do identyfikatora IDXGIResource. Aplikacja musi również upewnić się, że bufor wsteczny nie jest dołączony jako element docelowy renderowania, jak pokazano w artykule CameraResources::ReleaseResourcesForBackBuffer. Aby przyspieszyć pracę, aplikacja może zwolnić bufor wsteczny, a następnie uruchomić zadanie w celu asynchronicznego zakończenia każdej innej pracy dla aparatu. Szablon aplikacji holograficznej zawiera zadanie PPL, którego można użyć w tym celu.
Uwaga
Jeśli chcesz określić, kiedy zostanie wyświetlona dodana lub usunięta kamera na ramce, użyj właściwości HolographicFrame AddedCameras i RemovedCameras .
Tworzenie ramki odwołania do zawartości holograficznej
Zawartość aplikacji musi być umieszczona w układzie współrzędnych przestrzennych, który ma być renderowany w holographicspace. System udostępnia dwie podstawowe ramki odwołania, których można użyć do ustanowienia układu współrzędnych dla hologramów.
Istnieją dwa rodzaje ramek referencyjnych w systemie Windows Holographic: ramki referencyjne dołączone do urządzenia i ramki referencyjne, które pozostają nieruchome, gdy urządzenie przechodzi przez środowisko użytkownika. Szablon aplikacji holograficznej domyślnie używa stacjonarnej ramki referencyjnej; jest to jeden z najprostszych sposobów renderowania hologramów zablokowanych na świecie.
Nieruchome ramy odniesienia są przeznaczone do stabilizacji pozycji w pobliżu bieżącej lokalizacji urządzenia. Oznacza to, że współrzędne dalej od urządzenia mogą nieznacznie dryfować względem środowiska użytkownika, ponieważ urządzenie dowie się więcej o przestrzeni wokół niego. Istnieją dwa sposoby tworzenia nieruchomej ramki odwołania: uzyskiwanie układu współrzędnych z etapu przestrzennego lub użycie domyślnego obiektu SpatialLocator. Jeśli tworzysz aplikację Windows Mixed Reality dla immersyjnych zestawów nagłownych, zalecanym punktem wyjścia jest etap przestrzenny. Etap przestrzenny zawiera również informacje o możliwościach immersyjnego zestawu słuchawkowego noszonego przez odtwarzacz. W tym miejscu pokazano, jak używać domyślnego obiektu SpatialLocator.
Lokalizator przestrzenny reprezentuje urządzenie Windows Mixed Reality i śledzi ruch urządzenia i udostępnia systemy współrzędnych, które można zrozumieć w stosunku do jego lokalizacji.
Z appMain::OnHolographicDisplayIsAvailableChanged:
spatialLocator = SpatialLocator::GetDefault();
Utwórz nieruchomą ramkę referencyjną po uruchomieniu aplikacji. Jest to analogiczne do definiowania systemu współrzędnych świata, ze źródłem umieszczonym na pozycji urządzenia po uruchomieniu aplikacji. Ta ramka referencyjna nie przenosi się z urządzeniem.
Z obszaru AppMain::SetHolographicSpace:
m_stationaryReferenceFrame =
m_spatialLocator.CreateStationaryFrameOfReferenceAtCurrentLocation();
Wszystkie ramki odwołania są wyrównane powagę, co oznacza, że oś y wskazuje "w górę" w odniesieniu do środowiska użytkownika. Ponieważ system Windows używa układów współrzędnych "praworęcznych", kierunek osi –z pokrywa się z kierunkiem "do przodu", na którym znajduje się urządzenie po utworzeniu ramki odniesienia.
Uwaga
Gdy aplikacja wymaga dokładnego umieszczania poszczególnych hologramów, użyj obiektu SpatialAnchor , aby zakotwiczyć pojedynczy hologram w pozycji w świecie rzeczywistym. Na przykład użyj kotwicy przestrzennej, gdy użytkownik wskazuje, że punkt jest szczególnie interesujący. Położenia zakotwiczenia nie dryfują, ale można je dostosować. Domyślnie, gdy kotwica jest dostosowywana, ułatwia jego położenie w miejscu na kolejnych kilku ramkach po wystąpieniu korekty. W zależności od aplikacji, gdy tak się stanie, możesz chcieć obsłużyć korektę w inny sposób (np. odroczyć ją, dopóki hologram nie będzie wyświetlany). Właściwość RawCoordinateSystem i zdarzenia RawCoordinateSystemAdjusted umożliwiają te dostosowania.
Reagowanie na zdarzenia zmiany lokalizacyjne
Renderowanie na świecie zablokowanych hologramów wymaga, aby urządzenie mogło znaleźć się na świecie. Może to nie zawsze być możliwe ze względu na warunki środowiskowe, a jeśli tak, użytkownik może oczekiwać wizualnego wskazania przerwy w śledzeniu. To wskazanie wizualne musi być renderowane przy użyciu ramek referencyjnych dołączonych do urządzenia, a nie stacjonarnych na świecie.
Aplikacja może zażądać powiadomienia, jeśli śledzenie zostanie przerwane z jakiegokolwiek powodu. Zarejestruj się, aby zarejestrować zdarzenie LocatabilityChanged, aby wykryć, kiedy urządzenie może zlokalizować się na świecie. Z obszaru AppMain::SetHolographicSpace:
m_locatabilityChangedToken = m_spatialLocator.LocatabilityChanged(
std::bind(&HolographicApp6Main::OnLocatabilityChanged, this, _1, _2));
Następnie użyj tego zdarzenia, aby określić, kiedy hologramy nie mogą być renderowane nieruchomo na świecie.