Compartilhar via


Como obter um HolographicSpace

Observação

Este artigo está relacionado às APIs nativas herdadas do WinRT. Para novos projetos de aplicativos nativos, recomendamos usar a API OpenXR.

A classe HolographicSpace é o seu portal para o mundo holográfico. Ele controla a renderização imersiva, fornece dados de câmera e fornece acesso a APIs de raciocínio espacial. Você criará um para o CoreWindow do aplicativo UWP ou o HWND do aplicativo Win32.

Configurar o espaço holográfico

Criar o objeto de espaço holográfico é a primeira etapa para criar seu aplicativo Windows Mixed Reality. Os aplicativos tradicionais do Windows são renderizados em uma cadeia de troca do Direct3D criada para a janela principal do modo de exibição do aplicativo. Essa cadeia de troca é exibida em uma faixa na interface do usuário holográfica. Para fazer com que seu aplicativo seja exibido holográfico em vez de uma faixa 2D, crie um espaço holográfico para sua janela principal em vez de uma cadeia de troca. A apresentação de quadros holográficos criados por esse espaço holográfico coloca seu aplicativo no modo de renderização de tela inteira.

Para um aplicativo UWP a partir do modelo de Aplicativo Holográfico DirectX 11 (Universal do Windows), procure este código no método SetWindow em AppView.cpp:

m_holographicSpace = HolographicSpace::CreateForCoreWindow(window);

Se você estiver criando um aplicativo Win32 a partir do exemplo BasicHologram Win32, examine App::CreateWindowAndHolographicSpace para obter um exemplo de HWND. Em seguida, você pode convertê-lo em um HWND imersivo criando um HolographicSpace associado:

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

Depois de obter um HolographicSpace para o UWP CoreWindow ou o HWND Win32, o HolographicSpace pode lidar com câmeras holográficas, criar sistemas de coordenadas e fazer renderização holográfica. O espaço holográfico atual é usado em vários locais no modelo DirectX:

  • A classe DeviceResources precisa obter algumas informações do objeto HolographicSpace para criar o dispositivo Direct3D. Essa é a ID do adaptador DXGI associada à exibição holográfica. A classe HolographicSpace usa o dispositivo Direct3D 11 do aplicativo para criar e gerenciar recursos baseados em dispositivo, como os buffers traseiros para cada câmera holográfica. Se você estiver interessado em ver o que essa função faz nos bastidores, você a encontrará em DeviceResources.cpp.
  • A função DeviceResources::InitializeUsingHolographicSpace demonstra como obter o adaptador pesquisando o LUID – e como escolher um adaptador padrão quando nenhum adaptador preferencial é especificado.
  • A classe principal do aplicativo usa o espaço holográfico de AppView::SetWindow ou App::CreateWindowAndHolographicSpace para atualizações e renderização.

Observação

Embora as seções abaixo mencionem nomes de função do modelo, como AppView::SetWindow , que pressupõem que você começou a partir do modelo de aplicativo UWP holográfico, os snippets de código que você vê serão aplicados igualmente em aplicativos UWP e Win32.

Em seguida, vamos nos aprofundar no processo de instalação pelo qual SetHolographicSpace é responsável na classe AppMain.

Assine eventos de câmera, crie e remova recursos de câmera

O conteúdo holográfico do seu aplicativo reside em seu espaço holográfico e é exibido por meio de uma ou mais câmeras holográficas, que representam diferentes perspectivas sobre a cena. Agora que você tem o espaço holográfico, pode receber dados para câmeras holográficas.

Seu aplicativo precisa responder a eventos CameraAdded criando todos os recursos específicos para essa câmera. Um exemplo desse recurso é a exibição de destino de renderização do buffer traseiro. Você pode ver esse código na função DeviceResources::SetHolographicSpace , chamada por AppView::SetWindow antes que o aplicativo crie quadros holográficos:

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

Seu aplicativo também precisa responder a eventos CameraRemoved liberando recursos que foram criados para essa câmera.

De DeviceResources::SetHolographicSpace:

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

Os manipuladores de eventos devem concluir algum trabalho para manter a renderização holográfica fluindo sem problemas e a renderização do aplicativo. Leia o código e os comentários para obter os detalhes: você pode procurar OnCameraAdded e OnCameraRemoved em sua classe principal para entender como o mapa m_cameraResources é tratado por DeviceResources.

No momento, estamos focados no AppMain e na configuração que ele faz para permitir que seu aplicativo saiba sobre câmeras holográficas. Com isso em mente, é importante observar os dois requisitos a seguir:

  1. Para o manipulador de eventos CameraAdded , o aplicativo pode trabalhar de forma assíncrona para concluir a criação de recursos e o carregamento de ativos para a nova câmera holográfica. Os aplicativos que usam mais de um quadro para concluir esse trabalho devem solicitar um adiamento e concluí-lo após o carregamento de forma assíncrona. Uma tarefa PPL pode ser usada para fazer trabalho assíncrono. Seu aplicativo deve garantir que ele esteja pronto para renderizar para essa câmera imediatamente quando sair do manipulador de eventos ou quando concluir o adiamento. Sair do manipulador de eventos ou concluir o adiamento informa ao sistema que seu aplicativo agora está pronto para receber quadros holográficos com essa câmera incluída.

  2. Quando o aplicativo recebe um evento CameraRemoved , ele deve liberar todas as referências ao buffer traseiro e sair da função imediatamente. Isso inclui exibições de destino de renderização e qualquer outro recurso que possa conter uma referência ao IDXGIResource. O aplicativo também deve garantir que o buffer traseiro não esteja anexado como um destino de renderização, conforme mostrado em CameraResources::ReleaseResourcesForBackBuffer. Para ajudar a acelerar as coisas, seu aplicativo pode liberar o buffer traseiro e, em seguida, iniciar uma tarefa para concluir de forma assíncrona qualquer outro trabalho de desmontagem para a câmera. O modelo de aplicativo holográfico inclui uma tarefa PPL que você pode usar para essa finalidade.

Observação

Se você quiser determinar quando uma câmera adicionada ou removida aparece no quadro, use as propriedades HolographicFrame AddedCameras e RemovedCameras .

Criar um quadro de referência para seu conteúdo holográfico

O conteúdo do aplicativo deve ser posicionado em um sistema de coordenadas espaciais para ser renderizado no HolographicSpace. O sistema fornece dois quadros de referência primários, que você pode usar para estabelecer um sistema de coordenadas para seus hologramas.

Há dois tipos de quadros de referência no Windows Holographic: quadros de referência anexados ao dispositivo e quadros de referência que permanecem estacionários à medida que o dispositivo se move pelo ambiente do usuário. O modelo de aplicativo holográfico usa um quadro de referência estacionário por padrão; Essa é uma das maneiras mais simples de renderizar hologramas bloqueados pelo mundo.

Os quadros de referência estacionários são projetados para estabilizar posições próximas à localização atual do dispositivo. Isso significa que as coordenadas mais distantes do dispositivo podem variar um pouco em relação ao ambiente do usuário à medida que o dispositivo aprende mais sobre o espaço ao seu redor. Há duas maneiras de criar um quadro de referência estacionário: adquirir o sistema de coordenadas do estágio espacial ou usar o SpatialLocator padrão. Se você estiver criando um aplicativo Windows Mixed Reality para headsets imersivos, o ponto de partida recomendado será o estágio espacial. O estágio espacial também fornece informações sobre os recursos do fone de ouvido imersivo usado pelo jogador. Aqui, mostramos como usar o SpatialLocator padrão.

O localizador espacial representa o dispositivo Windows Mixed Reality e rastreia o movimento do dispositivo e fornece sistemas de coordenadas que podem ser entendidos em relação à sua localização.

De AppMain::OnHolographicDisplayIsAvailableChanged:

spatialLocator = SpatialLocator::GetDefault();

Crie o quadro de referência estacionário uma vez quando o aplicativo for iniciado. Isso é análogo à definição de um sistema de coordenadas mundiais, com a origem colocada na posição do dispositivo quando o aplicativo é iniciado. Esse quadro de referência não se move com o dispositivo.

De AppMain::SetHolographicSpace:

m_stationaryReferenceFrame =
    m_spatialLocator.CreateStationaryFrameOfReferenceAtCurrentLocation();

Todos os quadros de referência são alinhados à gravidade, o que significa que o eixo y aponta "para cima" em relação ao ambiente do usuário. Como o Windows usa sistemas de coordenadas "destros", a direção do eixo –z coincide com a direção "para frente" que o dispositivo está voltado quando o quadro de referência é criado.

Observação

Quando seu aplicativo exigir o posicionamento preciso de hologramas individuais, use um SpatialAnchor para ancorar o holograma individual a uma posição no mundo real. Por exemplo, use uma âncora espacial quando o usuário indicar que um ponto é de interesse especial. As posições de ancoragem não se desviam, mas podem ser ajustadas. Por padrão, quando uma âncora é ajustada, ela facilita sua posição nos próximos quadros após a correção. Dependendo do seu aplicativo, quando isso ocorrer, talvez você queira lidar com o ajuste de uma maneira diferente (por exemplo, adiando-o até que o holograma esteja fora de exibição). A propriedade RawCoordinateSystem e os eventos RawCoordinateSystemAdjusted permitem essas personalizações.

Responder a eventos alterados de localização

A renderização de hologramas bloqueados pelo mundo requer que o dispositivo se localize no mundo. Isso nem sempre é possível devido às condições ambientais e, em caso afirmativo, o usuário pode esperar uma indicação visual da interrupção do rastreamento. Essa indicação visual deve ser renderizada usando quadros de referência conectados ao dispositivo, em vez de estacionários para o mundo.

Seu aplicativo pode solicitar uma notificação se o rastreamento for interrompido por qualquer motivo. Registre-se no evento LocatabilityChanged para detectar quando a capacidade do dispositivo de se localizar no mundo muda. De AppMain::SetHolographicSpace:

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

Em seguida, use esse evento para determinar quando os hologramas não podem ser renderizados estacionários para o mundo.

Confira também