Ottenere un HolographicSpace

Nota

Questo articolo si riferisce alle API native WinRT legacy. Per i nuovi progetti di app native, è consigliabile usare l'API OpenXR.

La classe HolographicSpace è il portale nel mondo olografico. Controlla il rendering immersivo, fornisce i dati della fotocamera e fornisce l'accesso alle API di ragionamento spaziale. Ne creerai uno per coreWindow dell'app UWP o per il modulo HWND dell'app Win32.

Configurare lo spazio olografico

La creazione dell'oggetto spazio olografico è il primo passaggio per rendere l'app di Windows Realtà mista. Le app di Windows tradizionali eseguono il rendering in una catena di scambio Direct3D creata per la finestra principale della visualizzazione dell'applicazione. Questa catena di scambio viene visualizzata in uno slate nell'interfaccia utente olografica. Per rendere la visualizzazione dell'applicazione olografica anziché uno slate 2D, creare uno spazio olografico per la finestra principale anziché una catena di scambio. La presentazione di fotogrammi olografici creati da questo spazio olografico inserisce l'app in modalità di rendering a schermo intero.

Per un'app UWP a partire dal modello App Holographic DirectX 11 (Windows universale), cercare questo codice nel metodo SetWindow in AppView.cpp:

m_holographicSpace = HolographicSpace::CreateForCoreWindow(window);

Se stai creando un'app Win32 a partire dall'esempio BasicHologram Win32, guarda App::CreateWindowAndHolographicSpace per un esempio HWND. È quindi possibile convertirlo in un HWND immersivo creando un HolographicSpace associato:

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);
}

Dopo aver ottenuto un HolographicSpace per UWP CoreWindow o Win32 HWND, HolographicSpace può gestire fotocamere olografiche, creare sistemi di coordinate ed eseguire il rendering olografico. Lo spazio olografico corrente viene usato in più posizioni nel modello DirectX:

  • La classe DeviceResources deve ottenere alcune informazioni dall'oggetto HolographicSpace per creare il dispositivo Direct3D. Si tratta dell'ID scheda DXGI associato alla visualizzazione olografica. La classe HolographicSpace usa il dispositivo Direct3D 11 dell'app per creare e gestire risorse basate su dispositivo, ad esempio i buffer indietro per ogni fotocamera olografica. Se si è interessati a vedere cosa fa questa funzione sotto le quinte, lo si troverà in DeviceResources.cpp.
  • La funzione DeviceResources::InitializeUsingHolographicSpace illustra come ottenere l'adattatore cercando il LUID e come scegliere una scheda predefinita quando non viene specificata alcuna scheda preferita.
  • La classe principale dell'app usa lo spazio olografico di AppView::SetWindow o App::CreateWindowAndHolographicSpace per aggiornamenti e rendering.

Nota

Mentre le sezioni seguenti menzionano i nomi delle funzioni del modello come AppView::SetWindow che presuppongono che sia stato avviato dal modello di app UWP olografica, i frammenti di codice visualizzati verranno applicati equamente nelle app UWP e Win32.

Si esaminerà quindi il processo di configurazione per cui SetHolographicSpace è responsabile nella classe AppMain.

Sottoscrivere eventi della fotocamera, creare e rimuovere le risorse della fotocamera

Il contenuto olografico dell'app si trova nello spazio olografico e viene visualizzato tramite una o più fotocamere olografiche, che rappresentano prospettive diverse sulla scena. Ora che hai lo spazio olografico, puoi ricevere i dati per le fotocamere olografiche.

L'app deve rispondere agli eventi CameraAdded creando tutte le risorse specifiche della fotocamera. Un esempio di tale risorsa è la visualizzazione di destinazione di rendering del buffer nascosto. È possibile visualizzare questo codice nella funzione DeviceResources::SetHolographicSpace , chiamata da AppView::SetWindow prima che l'app crei qualsiasi frame olografico:

m_cameraAddedToken = m_holographicSpace.CameraAdded(
    std::bind(&AppMain::OnCameraAdded, this, _1, _2));

L'app deve anche rispondere agli eventi CameraRemoved rilasciando le risorse create per la fotocamera.

Da DeviceResources::SetHolographicSpace:

m_cameraRemovedToken = m_holographicSpace.CameraRemoved(
    std::bind(&AppMain::OnCameraRemoved, this, _1, _2));

I gestori eventi devono completare alcune operazioni per mantenere il flusso uniforme del rendering olografico e il rendering dell'app. Leggere il codice e i commenti per i dettagli: è possibile cercare OnCameraAdded e OnCameraRemoved nella classe principale per comprendere come la mappa m_cameraResources viene gestita da DeviceResources.

Al momento, ci concentriamo su AppMain e sulla configurazione che fa per consentire all'app di conoscere le fotocamere olografiche. Tenendo presente questo aspetto, è importante prendere nota dei due requisiti seguenti:

  1. Per il gestore eventi CameraAdded , l'app può funzionare in modo asincrono per completare la creazione di risorse e il caricamento di asset per la nuova fotocamera olografica. Le app che accettano più fotogrammi per completare questo lavoro devono richiedere un differire e completare il differire dopo il caricamento asincrono. Un'attività PPL può essere usata per eseguire operazioni asincrone. L'app deve assicurarsi che sia pronta per il rendering immediatamente alla fotocamera quando esce dal gestore eventi o quando completa il differire. Uscire dal gestore eventi o completare il differimento indica al sistema che l'app è ora pronta per ricevere fotogrammi olografici con la fotocamera inclusa.

  2. Quando l'app riceve un evento CameraRemoved , deve rilasciare immediatamente tutti i riferimenti al buffer nascosto e uscire dalla funzione. Sono incluse le visualizzazioni di destinazione di rendering e qualsiasi altra risorsa che potrebbe contenere un riferimento all'OGGETTO IDXGIResource. L'app deve anche assicurarsi che il buffer nascosto non sia collegato come destinazione di rendering, come illustrato in CameraResources::ReleaseResourcesForBackBuffer. Per velocizzare le operazioni, l'app può rilasciare il buffer nascosto e quindi avviare un'attività per completare in modo asincrono qualsiasi altro lavoro di disinstallazione per la fotocamera. Il modello di app olografica include un'attività PPL che è possibile usare a questo scopo.

Nota

Se vuoi determinare quando viene visualizzata una fotocamera aggiunta o rimossa nel fotogramma, usa le proprietà HolographicFrame AddedCameras e RemovedCameras .

Creare un frame di riferimento per il contenuto olografico

Il contenuto dell'app deve essere posizionato in un sistema di coordinate spaziali per il rendering in HolographicSpace. Il sistema fornisce due fotogrammi principali di riferimento, che è possibile usare per stabilire un sistema di coordinate per gli ologrammi.

Esistono due tipi di frame di riferimento in Windows Holographic: frame di riferimento collegati al dispositivo e frame di riferimento che rimangono fissi mentre il dispositivo passa attraverso l'ambiente dell'utente. Il modello di app olografica usa un frame di riferimento fisso per impostazione predefinita; questo è uno dei modi più semplici per eseguire il rendering degli ologrammi bloccati dal mondo.

I frame di riferimento stazionari sono progettati per stabilizzare le posizioni vicino alla posizione corrente del dispositivo. Ciò significa che le coordinate più lontane dal dispositivo possono derivare leggermente rispetto all'ambiente dell'utente mentre il dispositivo apprende di più sullo spazio intorno. Esistono due modi per creare un frame di riferimento fisso: acquisire il sistema di coordinate dalla fase spaziale o usare l'oggetto SpatialLocator predefinito. Se stai creando un'app di Windows Realtà mista per visori VR immersive, il punto di partenza consigliato è la fase spaziale. La fase spaziale fornisce anche informazioni sulle funzionalità del visore VR immersive indossato dal giocatore. Qui viene illustrato come usare l'oggetto SpatialLocator predefinito.

Il localizzatore spaziale rappresenta il dispositivo Windows Realtà mista e tiene traccia del movimento del dispositivo e fornisce sistemi di coordinate comprensibili rispetto alla posizione.

Da AppMain::OnHolographicDisplayIsAvailableChanged:

spatialLocator = SpatialLocator::GetDefault();

Creare il frame di riferimento fisso una volta all'avvio dell'app. Questo è analogo alla definizione di un sistema di coordinate globale, con l'origine posizionata nella posizione del dispositivo all'avvio dell'app. Questo frame di riferimento non si sposta con il dispositivo.

Da AppMain::SetHolographicSpace:

m_stationaryReferenceFrame =
    m_spatialLocator.CreateStationaryFrameOfReferenceAtCurrentLocation();

Tutti i fotogrammi di riferimento sono allineati alla gravità, ovvero l'asse y punta "su" rispetto all'ambiente dell'utente. Poiché Windows usa sistemi di coordinate "destrorse", la direzione dell'asse –z coincide con la direzione "avanti" rivolta al dispositivo quando viene creato il frame di riferimento.

Nota

Quando l'app richiede un posizionamento preciso di singoli ologrammi, usa spatialAnchor per ancorare l'ologramma singolo a una posizione nel mondo reale. Ad esempio, usare un ancoraggio spaziale quando l'utente indica un punto di interesse speciale. Le posizioni di ancoraggio non si allontanano, ma possono essere regolate. Per impostazione predefinita, quando un ancoraggio viene regolato, semplifica la posizione in posizione sui diversi fotogrammi successivi dopo che si è verificata la correzione. A seconda dell'applicazione, quando si verifica questo problema, è possibile gestire la regolazione in modo diverso ,ad esempio rinviandolo fino a quando l'ologramma non è visualizzato. La proprietà RawCoordinateSystem e gli eventi RawCoordinateSystemAdjusted abilitano queste personalizzazioni.

Rispondere agli eventi modificati di individuabilità

Per il rendering degli ologrammi bloccati al mondo, il dispositivo deve individuarsi nel mondo. Ciò potrebbe non essere sempre possibile a causa di condizioni ambientali e, in tal caso, l'utente potrebbe aspettarsi un'indicazione visiva dell'interruzione del rilevamento. È necessario eseguire il rendering di questa indicazione visiva usando i frame di riferimento collegati al dispositivo, invece di essere stazionari al mondo.

L'app può richiedere di ricevere una notifica se il rilevamento viene interrotto per qualsiasi motivo. Registrarsi per l'evento LocatabilityChanged per rilevare quando la capacità del dispositivo di individuarsi nel mondo cambia. Da AppMain::SetHolographicSpace:

m_locatabilityChangedToken = m_spatialLocator.LocatabilityChanged(
    std::bind(&HolographicApp6Main::OnLocatabilityChanged, this, _1, _2));

Usare quindi questo evento per determinare quando non è possibile eseguire il rendering degli ologrammi nel mondo.

Vedi anche