Получение HolographicSpace

Примечание

Эта статья относится к устаревшим собственным API WinRT. Для новых проектов собственных приложений рекомендуется использовать API OpenXR.

Класс HolographicSpace — это портал для голографического мира. Он управляет иммерсивной отрисовкой, предоставляет данные камеры и предоставляет доступ к API пространственного обоснования. Вы создадите его для приложения UWP CoreWindow или HWND приложения Win32.

Настройка голографического пространства

Создание голографического пространственного объекта — это первый шаг в создании приложения Windows Mixed Reality. Традиционные приложения Windows отрисовываются в цепочке буферов Direct3D, созданной для основного окна представления приложения. Эта цепочка буферов отображается на сланце в голографическом пользовательском интерфейсе. Чтобы приложение просматривало голографический, а не двухd-лист, создайте голографическое пространство для основного окна вместо цепочки буферов. Представление голографических кадров, созданных этим голографическим пространством, переводит приложение в полноэкранный режим отрисовки.

Для приложения UWP, начиная с шаблона Holographic DirectX 11 App (universal Windows), найдите этот код в методе SetWindow в AppView.cpp:

m_holographicSpace = HolographicSpace::CreateForCoreWindow(window);

Если вы создаете приложение Win32, начиная с примера BasicHologram Win32, ознакомьтесь с примером HWND в app::CreateWindowAndHolographicSpace . Затем вы можете преобразовать его в иммерсивный HWND, создав связанный 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);
}

Получив HolographicSpace для UWP CoreWindow или Win32 HWND, HolographicSpace сможет обрабатывать голографические камеры, создавать системы координат и выполнять голографическую отрисовку. Текущее голографическое пространство используется в нескольких местах в шаблоне DirectX:

  • Класс DeviceResources должен получить некоторые сведения из объекта HolographicSpace, чтобы создать устройство Direct3D. Это идентификатор адаптера DXGI, связанный с голографическим дисплеем. Класс HolographicSpace использует устройство Direct3D 11 приложения для создания ресурсов на основе устройств, таких как задние буферы для каждой голографической камеры, и управления ими. Если вы хотите узнать, что делает эта функция под капотом, вы найдете ее в DeviceResources.cpp.
  • Функция DeviceResources::InitializeUsingHolographicSpace демонстрирует, как получить адаптер путем поиска LUID и как выбрать адаптер по умолчанию, если предпочтительный адаптер не указан.
  • Класс main приложения использует голографическое пространство из AppView::SetWindow или App::CreateWindowAndHolographicSpace для обновлений и отрисовки.

Примечание

Хотя в разделах ниже упоминание имена функций из шаблона, например AppView::SetWindow, которые предполагают, что вы начали работу с голографического шаблона приложения UWP, фрагменты кода, которые вы видите, будут одинаково применяться к приложениям UWP и Win32.

Далее мы рассмотрим процесс настройки, за который отвечает SetHolographicSpace в классе AppMain.

Подписка на события камеры, создание и удаление ресурсов камеры

Голографическое содержимое приложения находится в голографическом пространстве и просматривается с помощью одной или нескольких голографических камер, которые представляют различные перспективы на сцене. Теперь, когда у вас есть голографическое пространство, вы можете получать данные для голографических камер.

Ваше приложение должно реагировать на события CameraAdded , создавая ресурсы, относящиеся к этой камере. Примером такого ресурса является представление целевого объекта отрисовки заднего буфера. Этот код можно увидеть в функции DeviceResources::SetHolographicSpace , вызываемой AppView::SetWindow , прежде чем приложение создаст голографические кадры:

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 в классе main, чтобы понять, как карта m_cameraResources обрабатывается DeviceResources.

Сейчас мы сосредоточимся на AppMain и настройке, которую он делает, чтобы ваше приложение знало о голографических камерах. Учитывая это, важно учитывать следующие два требования:

  1. Для обработчика событий CameraAdded приложение может асинхронно завершить создание ресурсов и загрузку ресурсов для новой голографической камеры. Приложения, которые занимают более одного кадра для выполнения этой работы, должны запрашивать отсрочку и завершать отсрочку после асинхронной загрузки. Для выполнения асинхронной работы можно использовать задачу PPL . Ваше приложение должно быть готово к отрисовке на этой камере сразу после выхода из обработчика событий или завершения отсрочки. Выход из обработчика событий или завершение отсрочки сообщает системе, что ваше приложение теперь готово к приему голографических кадров с включенной камерой.

  2. Когда приложение получает событие CameraRemoved , оно должно освободить все ссылки на задний буфер и сразу же выйти из функции. Сюда входят целевые представления отрисовки и любой другой ресурс, который может содержать ссылку на IDXGIResource. Приложение также должно убедиться, что задний буфер не подключен в качестве целевого объекта отрисовки, как показано в CameraResources::ReleaseResourcesForBackBuffer. Чтобы ускорить работу, приложение может освободить задний буфер, а затем запустить задачу, чтобы асинхронно завершить любую другую работу по сносу камеры. Шаблон голографического приложения включает задачу PPL, которую можно использовать для этой цели.

Примечание

Если вы хотите определить, когда добавленная или удаленная камера отображается в кадре, используйте свойства HolographicFrameAddedCameras и RemovedCameras .

Создание эталонной системы для голографического содержимого

Содержимое приложения должно быть размещено в системе пространственных координат для отрисовки в HolographicSpace. Система предоставляет два основных опорных кадра, которые можно использовать для создания системы координат для голограмм.

В Windows Holographic существует два типа опорных кадров: опорные кадры, подключенные к устройству, и опорные кадры, которые остаются неподвижными при перемещении устройства через среду пользователя. В шаблоне голографического приложения по умолчанию используется неподвижная опорная рамка; это один из самых простых способов отрисовки голограмм, заблокированных во всем мире.

Стационарные опорные кадры предназначены для стабилизации позиций вблизи текущего расположения устройства. Это означает, что координаты от устройства могут немного отклоняться относительно среды пользователя, так как устройство узнает больше о пространстве вокруг него. Существует два способа создания стационарной системы отсчета: получить систему координат из пространственного этапа или использовать пространственный указатель по умолчанию. Если вы создаете приложение Windows Mixed Reality для иммерсивных гарнитур, рекомендуемой отправной точкой является пространственный этап. Пространственный этап также предоставляет сведения о возможностях иммерсивной гарнитуры, которую носит игрок. Здесь мы покажем, как использовать SpatialLocator по умолчанию.

Пространственный указатель представляет Windows Mixed Reality устройство и отслеживает движение устройства и предоставляет системы координат, которые можно понять относительно его расположения.

Из AppMain::OnHolographicDisplayIsAvailableChanged:

spatialLocator = SpatialLocator::GetDefault();

Создайте неподвижную опорную рамку один раз при запуске приложения. Это аналогично определению мировой системы координат, при этом источник помещается в положение устройства при запуске приложения. Эта опорная рамка не перемещается вместе с устройством.

Из AppMain::SetHolographicSpace:

m_stationaryReferenceFrame =
    m_spatialLocator.CreateStationaryFrameOfReferenceAtCurrentLocation();

Все опорные кадры выровнены по гравитации, что означает, что ось Y указывает "вверх" по отношению к среде пользователя. Так как Windows использует "праворукие" системы координат, направление оси –z совпадает с направлением вперед, к которым устройство обращено при создании опорной рамки.

Примечание

Если приложению требуется точное размещение отдельных голограмм, используйте SpatialAnchor для привязки отдельной голограммы к позиции в реальном мире. Например, используйте пространственную привязку, когда пользователь указывает, что точка представляет особый интерес. Положения привязки не смещения, но их можно корректировать. По умолчанию, когда привязка корректируется, она облегчает ее положение в течение следующих нескольких кадров после исправления. В зависимости от приложения, когда это происходит, может потребоваться обрабатывать корректировку другим способом (например, откладывая ее до тех пор, пока голограмма не выйдет из виду). Свойства RawCoordinateSystem и События RawCoordinateSystemAdjusted позволяют выполнять эти настройки.

Реагирование на события изменения locatability

Для отрисовки заблокированных во всем мире голограмм требуется, чтобы устройство располагалось в мире. Это может быть не всегда возможно из-за условий окружающей среды, и если да, пользователь может ожидать визуальное указание прерывания отслеживания. Это визуальное указание должно отображаться с помощью опорных кадров, прикрепленных к устройству, а не стационарных к миру.

Приложение может запросить уведомление, если отслеживание прерывается по какой-либо причине. Зарегистрируйтесь для получения события LocatabilityChanged, чтобы определить, когда изменяется возможность устройства найти себя в мире. Из AppMain::SetHolographicSpace:

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

Затем используйте это событие, чтобы определить, когда голограммы не могут быть отрисованы в неподвижном состоянии.

См. также раздел