Pobieranie 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 wymiany Direct3D utworzonym dla podstawowego okna widoku aplikacji. Ten łańcuch wymiany jest wyświetlany jako łupek w interfejsie użytkownika holograficznego. Aby widok aplikacji był wyświetlany holograficznie zamiast łupków 2D, utwórz przestrzeń holograficzną dla okna podstawowego zamiast łańcucha wymiany. Prezentowanie ramek holograficznych, które są tworzone przez tę przestrzeń holograficzną, umieszcza aplikację w trybie renderowania pełnoekranowego.

W przypadku aplikacji platformy UWProzpoczynającej się od szablonu Aplikacji Holographic DirectX 11 (uniwersalny system Windows) poszukaj tego kodu w metodzie SetWindow w pliku AppView.cpp:

m_holographicSpace = HolographicSpace::CreateForCoreWindow(window);

Jeśli tworzysz aplikację Win32, zaczynając od przykładu BasicHologram Win32, zapoznaj się z przykładem App::CreateWindowAndHolographicSpace . Następnie można przekonwertować go na immersywny HWND, tworząc skojarzona przestrzeń 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 przestrzeni holograficznej 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 pobrać pewne 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 bufory tylne dla każdej kamery holograficznej. Jeśli chcesz zobaczyć, co ta funkcja robi pod maską, znajdziesz ją w pliku DeviceResources.cpp.
  • Funkcja DeviceResources::InitializeUsingHolographicSpace pokazuje, jak uzyskać kartę, wyszukując identyfikator LUID i jak wybrać kartę domyślną, gdy nie określono preferowanej karty.
  • Klasa główna aplikacji używa przestrzeni holograficznej z elementu AppView::SetWindow lub App::CreateWindowAndHolographicSpace do 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, ale widoczne fragmenty kodu będą stosowane równomiernie w aplikacjach platformy UWP i Win32.

Następnie omówimy proces instalacji, 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 jeden aparat holograficzny, który 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 bufora wstecznego. Ten kod można zobaczyć w funkcji DeviceResources::SetHolographicSpace o nazwie AppView::SetWindow przed utworzeniem przez aplikację ramek holograficznych:

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.

Z obszaru 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ływ 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 zrozumieć, jak mapa m_cameraResources jest obsługiwana przez usługę DeviceResources.

W tej chwili koncentrujemy się na aplikacji AppMain i konfiguracji, którą robi, aby umożliwić aplikacji poznanie kamer holograficznych. Mając to na uwadze, należy wziąć pod uwagę następujące dwa wymagania:

  1. 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 pracy asynchronicznej. Aplikacja musi mieć pewność, że jest gotowa do renderowania do tej kamery od razu po zamknięciu programu 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.

  2. Gdy aplikacja odbiera zdarzenie CameraRemoved , musi zwolnić wszystkie odwołania do bufora wstecznego i od razu zamknąć funkcję. Obejmuje to widoki docelowe renderowania i wszelkie inne zasoby, które mogą zawierać odwołanie do źródła IDXGIResource. Aplikacja musi również upewnić się, że bufor wsteczny nie jest dołączony jako element docelowy renderowania, jak pokazano w temacie 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 usuwania aparatu. Szablon aplikacji holograficznej zawiera zadanie PPL, którego można użyć do tego celu.

Uwaga

Jeśli chcesz określić, kiedy na ramce pojawi się dodana lub usunięta kamera, użyj właściwości HolographicFrameAddedCameras i RemovedCameras .

Tworzenie ramki referencyjnej dla 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 systemu 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 nieruchomej ramki odniesienia; 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 ramy odniesienia: uzyskanie układu współrzędnych z etapu przestrzennego lub użycie domyślnego obiektu SpatialLocator. Jeśli tworzysz aplikację Windows Mixed Reality dla immersywnych zestawów nagłownych, zalecanym punktem wyjścia jest etap przestrzenny. Etap przestrzenny zawiera również informacje o możliwościach immersyjnego zestawu nagłownego 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 zapewnia układy współrzędnych, które można zrozumieć w stosunku do jego lokalizacji.

Z elementu AppMain::OnHolographicDisplayIsAvailableChanged:

spatialLocator = SpatialLocator::GetDefault();

Utwórz nieruchomą ramkę odniesienia po uruchomieniu aplikacji. Jest to analogia do definiowania systemu współrzędnych świata z początkiem umieszczonym na pozycji urządzenia podczas uruchamiania 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 z grawitacją, co oznacza, że osi y "w górę" w odniesieniu do środowiska użytkownika. Ponieważ system Windows używa "praworęcznych" systemów współrzędnych, kierunek osi –z pokrywa się z kierunkiem "do przodu", z którym urządzenie jest skierowane podczas tworzenia ramki odniesienia.

Uwaga

Jeśli aplikacja wymaga dokładnego umieszczania poszczególnych hologramów, użyj elementu SpatialAnchor , aby zakotwiczyć pojedynczy hologram w pozycji w świecie rzeczywistym. Na przykład należy użyć kotwicy przestrzennej, gdy użytkownik wskazuje punkt, który ma być interesujący. Położenia kotwicy nie dryfują, ale można je dostosować. Domyślnie, gdy kotwica jest dostosowywana, ułatwia jej położenie 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ści RawCoordinateSystem i RawCoordinateSystemAdjusted umożliwiają te dostosowania.

Reagowanie na zdarzenia zmiany lokalizacyjne

Renderowanie na świecie zablokowanych hologramów wymaga, aby urządzenie mogło się znaleźć na świecie. Może to nie zawsze być możliwe ze względu na warunki środowiskowe, a jeśli tak, użytkownik może spodziewać się wizualnego wskazania przerwy w śledzeniu. To wskazanie wizualne musi być renderowane przy użyciu ramek referencyjnych dołączonych do urządzenia zamiast nieruchomych na świecie.

Aplikacja może zażądać powiadomienia, jeśli śledzenie zostanie przerwane z jakiegokolwiek powodu. Zarejestruj się, aby uzyskać zdarzenie LocatabilityChanged, aby wykryć, kiedy urządzenie może zlokalizować się w ś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.

Zobacz też