Пользовательские каналы данных с голографическим удаленным взаимодействием и API OpenXR
Используйте пользовательские каналы данных для отправки пользовательских данных через установленное подключение удаленного взаимодействия.
Важно!
Для пользовательских каналов данных требуется пользовательское удаленное приложение и пользовательское приложение проигрывателя. Это обеспечивает обмен данными между двумя пользовательскими приложениями.
Совет
Простой пример для пинг-понгов можно найти в примерах удаленного и проигрывателя в репозитории примеров голографического удаленного взаимодействия GitHub.
Раскомментируйте #define ENABLE_CUSTOM_DATA_CHANNEL_SAMPLE
файлы OpenXrProgramm.cpp и SamplePlayerMain.h, чтобы включить пример кода.
Примечание
Подробную спецификацию можно найти в репозитории примеров голографического удаленного взаимодействия на GitHub.
Создание пользовательского канала данных
Пользовательский канал данных определяется дескриптором XrRemotingDataChannelMSFT
:
XrRemotingDataChannelMSFT m_userDataChannel;
После успешной установки подключения можно создать новые каналы данных с помощью xrCreateRemotingDataChannelMSFT
функции :
XrRemotingDataChannelCreateInfoMSFT channelInfo{static_cast<XrStructureType>(XR_TYPE_REMOTING_DATA_CHANNEL_CREATE_INFO_MSFT)};
channelInfo.channelId = 0;
channelInfo.channelPriority = XR_REMOTING_DATA_CHANNEL_PRIORITY_LOW_MSFT;
CHECK_XRCMD(m_extensions.xrCreateRemotingDataChannelMSFT(m_instance.Get(), m_systemId, &channelInfo, &m_userDataChannel));
Пользовательские каналы данных можно создавать из проигрывателя и удаленного приложения, даже если среды выполнения отличаются.
Если канал данных создается на стороне игрока, удаленная сторона получает уведомление со структурой XrEventDataRemotingDataChannelCreatedMSFT
событий:
XrEventDataBuffer eventData{};
while (pollEvent(eventData))
{
switch (eventData.type)
{
case XR_TYPE_EVENT_DATA_REMOTING_DATA_CHANNEL_CREATED_MSFT:
{
auto channelCreatedEventData = reinterpret_cast<const XrEventDataRemotingDataChannelCreatedMSFT*>(&eventData);
m_userDataChannel = channelCreatedEventData->channel;
break;
}
}
}
Начальное XrRemotingDataChannelStatusMSFT
состояние после вызова xrCreateRemotingDataChannelMSFT
— XR_REMOTING_DATA_CHANNEL_STATUS_OPEN_PENDING_MSFT
.
После полного создания канала данных состояние канала переключается на XR_REMOTING_DATA_CHANNEL_STATUS_OPENED_MSFT
.
Структура XrEventDataRemotingDataChannelOpenedMSFT
событий помещается в очередь событий, когда состояние ранее созданного канала данных переключается с XR_REMOTING_DATA_CHANNEL_STATUS_OPEN_PENDING_MSFT
на XR_REMOTING_DATA_CHANNEL_STATUS_OPENED_MSFT
.
Получение состояния канала
Функцию xrGetRemotingDataChannelStateMSFT
можно использовать для запроса состояния канала данных:
XrRemotingDataChannelStateMSFT channelState{static_cast<XrStructureType>(XR_TYPE_REMOTING_DATA_CHANNEL_STATE_MSFT)};
CHECK_XRCMD(m_extensions.xrGetRemotingDataChannelStateMSFT(m_userDataChannel, &channelState));
Отправка данных
Если канал открыт, xrSendRemotingDataMSFT
функция используется для отправки данных на сторону игрока:
if (channelState.connectionStatus == XR_REMOTING_DATA_CHANNEL_STATUS_OPENED_MSFT) {
// Only send the packet if the send queue is smaller than 1MiB
if (channelState.sendQueueSize >= 1 * 1024 * 1024) {
return;
}
uint8_t data[] = {1};
XrRemotingDataChannelSendDataInfoMSFT sendInfo{
static_cast<XrStructureType>(XR_TYPE_REMOTING_DATA_CHANNEL_SEND_DATA_INFO_MSFT)};
sendInfo.data = data;
sendInfo.size = sizeof(data);
sendInfo.guaranteedDelivery = true;
CHECK_XRCMD(m_extensions.xrSendRemotingDataMSFT(m_userDataChannel, &sendInfo));
}
Примечание
Данные, отправляемые по пользовательскому каналу данных, используют пропускную способность с другими каналами данных, используемыми голографическим удаленным взаимодействием.
Получение данных
Каждый раз, когда данные поступают через канал данных, XrEventDataRemotingDataChannelDataReceivedMSFT
в очередь событий помещается структура событий.
Полученные пакеты можно получить с помощью xrRetrieveRemotingDataMSFT
функции :
XrEventDataBuffer eventData{};
while (pollEvent(eventData))
{
switch (eventData.type)
{
case XR_TYPE_EVENT_DATA_REMOTING_DATA_CHANNEL_DATA_RECEIVED_MSFT:
{
auto dataReceivedEventData = reinterpret_cast<const XrEventDataRemotingDataChannelDataReceivedMSFT*>(&eventData);
std::vector<uint8_t> packet(dataReceivedEventData->size);
uint32_t dataBytesCount;
CHECK_XRCMD(m_extensions.xrRetrieveRemotingDataMSFT(dataReceivedEventData->channel,
dataReceivedEventData->packetId,
static_cast<uint32_t>(packet.size()),
&dataBytesCount,
packet.data()));
break;
}
}
}
Уничтожение канала данных
Вы можете уничтожить канал данных с помощью xrDestroyRemotingDataChannelMSFT
:
CHECK_XRCMD(m_extensions.xrDestroyRemotingDataChannelMSFT(m_userDataChannel));
Дескриптор XrRemotingDataChannelMSFT
является недопустимым xrDestroyRemotingDataChannelMSFT
после вызова, и дескриптор канала данных не должен использоваться после этого.
объект XrEventDataRemotingDataChannelClosedMSFT
будет помещен в очередь событий в случае, если сторона игрока закроет или уничтожит канал данных.
Состояние канала данных переключается на XR_REMOTING_DATA_CHANNEL_STATUS_CLOSED_MSFT
.
Для закрытого канала данных дескриптор остается действительным XrRemotingDataChannelMSFT
.