日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Hololens2-OpenXR开发(二)-实现通讯

發(fā)布時間:2023/11/27 生活经验 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hololens2-OpenXR开发(二)-实现通讯 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Writing a Holographic Remoting Remote app using the OpenXR API

本文是根據官方示例的學習筆記

https://docs.microsoft.com/en-us/windows/mixed-reality/develop/native/holographic-remoting-create-remote-openxr

解釋名詞:
runtime: 不同廠商根據OpenXR標準實現的設備,如Hololens,Oculus

1. 導入XR開發(fā)相關函數(EnableRemotingXR)

bool EnableRemotingXR() {wchar_t executablePath[MAX_PATH];if (GetModuleFileNameW(NULL, executablePath, ARRAYSIZE(executablePath)) == 0) {return false;}std::filesystem::path filename(executablePath);filename = filename.replace_filename("RemotingXR.json");if (std::filesystem::exists(filename)) {SetEnvironmentVariableW(L"XR_RUNTIME_JSON", filename.c_str());return true;}return false;
}

2. 初始化遠程通訊環(huán)境 (PrepareRemotingEnvironment)

 void PrepareRemotingEnvironment() {if (!m_options.secureConnection) {return;}if (m_options.authenticationToken.empty()) {throw std::logic_error("Authentication token must be specified for secure connections.");}if (m_options.listen) {if (m_options.certificateStore.empty() || m_options.subjectName.empty()) {throw std::logic_error("Certificate store and subject name must be specified for secure listening.");}constexpr size_t maxCertStoreSize = 1 << 20;std::ifstream certStoreStream(m_options.certificateStore, std::ios::binary);certStoreStream.seekg(0, std::ios_base::end);const size_t certStoreSize = certStoreStream.tellg();if (!certStoreStream.good() || certStoreSize == 0 || certStoreSize > maxCertStoreSize) {throw std::logic_error("Error reading certificate store.");}certStoreStream.seekg(0, std::ios_base::beg);m_certificateStore.resize(certStoreSize);certStoreStream.read(reinterpret_cast<char*>(m_certificateStore.data()), certStoreSize);if (certStoreStream.fail()) {throw std::logic_error("Error reading certificate store.");}}
}

3. 創(chuàng)建XR實例(CreateInstance)

OpenXR里3個常用的擴展包:XR_MSFT_holographic_remoting
XR_MSFT_holographic_remoting_speech XR_MSFT_remoting_frame_mirroring

void CreateInstance() {CHECK(m_instance.Get() == XR_NULL_HANDLE);// Build out the extensions to enable. Some extensions are required and some are optional.const std::vector<const char*> enabledExtensions = SelectExtensions();//選擇所需擴展包// Create the instance with enabled extensions.XrInstanceCreateInfo createInfo{XR_TYPE_INSTANCE_CREATE_INFO};createInfo.enabledExtensionCount = (uint32_t)enabledExtensions.size();createInfo.enabledExtensionNames = enabledExtensions.data();createInfo.applicationInfo = {"SampleRemoteOpenXr", 1, "", 1, XR_CURRENT_API_VERSION};strcpy_s(createInfo.applicationInfo.applicationName, m_applicationName.c_str());CHECK_XRCMD(xrCreateInstance(&createInfo, m_instance.Put()));m_extensions.PopulateDispatchTable(m_instance.Get());
}

4. 交互動作初始化(CreateActions)

還沒進入實時通訊狀態(tài)前

void CreateActions() {CHECK(m_instance.Get() != XR_NULL_HANDLE);// Create an action set.{XrActionSetCreateInfo actionSetInfo{XR_TYPE_ACTION_SET_CREATE_INFO};strcpy_s(actionSetInfo.actionSetName, "place_hologram_action_set");strcpy_s(actionSetInfo.localizedActionSetName, "Placement");CHECK_XRCMD(xrCreateActionSet(m_instance.Get(), &actionSetInfo, m_actionSet.Put()));}// Create actions.{// Enable subaction path filtering for left or right hand.m_subactionPaths[LeftSide] = GetXrPath("/user/hand/left");m_subactionPaths[RightSide] = GetXrPath("/user/hand/right");// Create an input action to place a hologram.{XrActionCreateInfo actionInfo{XR_TYPE_ACTION_CREATE_INFO};actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;strcpy_s(actionInfo.actionName, "place_hologram");strcpy_s(actionInfo.localizedActionName, "Place Hologram");actionInfo.countSubactionPaths = (uint32_t)m_subactionPaths.size();actionInfo.subactionPaths = m_subactionPaths.data();CHECK_XRCMD(xrCreateAction(m_actionSet.Get(), &actionInfo, m_placeAction.Put()));}// Create an input action getting the left and right hand poses.{XrActionCreateInfo actionInfo{XR_TYPE_ACTION_CREATE_INFO};actionInfo.actionType = XR_ACTION_TYPE_POSE_INPUT;strcpy_s(actionInfo.actionName, "hand_pose");strcpy_s(actionInfo.localizedActionName, "Hand Pose");actionInfo.countSubactionPaths = (uint32_t)m_subactionPaths.size();actionInfo.subactionPaths = m_subactionPaths.data();CHECK_XRCMD(xrCreateAction(m_actionSet.Get(), &actionInfo, m_poseAction.Put()));}// Create an output action for vibrating the left and right controller.{XrActionCreateInfo actionInfo{XR_TYPE_ACTION_CREATE_INFO};actionInfo.actionType = XR_ACTION_TYPE_VIBRATION_OUTPUT;strcpy_s(actionInfo.actionName, "vibrate");strcpy_s(actionInfo.localizedActionName, "Vibrate");actionInfo.countSubactionPaths = (uint32_t)m_subactionPaths.size();actionInfo.subactionPaths = m_subactionPaths.data();CHECK_XRCMD(xrCreateAction(m_actionSet.Get(), &actionInfo, m_vibrateAction.Put()));}// Create an input action to exit the session.}// Set up suggested bindings for the simple_controller profile.{std::vector<XrActionSuggestedBinding> bindings;bindings.push_back({m_placeAction.Get(), GetXrPath("/user/hand/right/input/select/click")});bindings.push_back({m_placeAction.Get(), GetXrPath("/user/hand/left/input/select/click")});bindings.push_back({m_poseAction.Get(), GetXrPath("/user/hand/right/input/aim/pose")});bindings.push_back({m_poseAction.Get(), GetXrPath("/user/hand/left/input/aim/pose")});XrInteractionProfileSuggestedBinding suggestedBindings{XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING};suggestedBindings.interactionProfile = GetXrPath("/interaction_profiles/khr/simple_controller");suggestedBindings.suggestedBindings = bindings.data();suggestedBindings.countSuggestedBindings = (uint32_t)bindings.size();CHECK_XRCMD(xrSuggestInteractionProfileBindings(m_instance.Get(), &suggestedBindings));}
}

5. 驗證通訊是否正常(ProcessEvents)

監(jiān)視連接狀態(tài)
XR_TYPE_REMOTING_EVENT_DATA_CONNECTED_MSFT 已成功建立
XR_TYPE_REMOTING_EVENT_DATA_DISCONNECTED_MSFT 已建立的連接已關閉或無法建立連接
XR_TYPE_REMOTING_EVENT_DATA_LISTENING_MSFT 偵聽啟動

auto pollEvent = [&](XrEventDataBuffer& eventData) -> bool {eventData.type = XR_TYPE_EVENT_DATA_BUFFER;eventData.next = nullptr;return CHECK_XRCMD(xrPollEvent(m_instance.Get(), &eventData)) == XR_SUCCESS;
};
XrEventDataBuffer eventData{};
while (pollEvent(eventData)) {switch (eventData.type) {...	case XR_TYPE_REMOTING_EVENT_DATA_LISTENING_MSFT: {DEBUG_PRINT("Holographic Remoting: Listening on port %d",reinterpret_cast<const XrRemotingEventDataListeningMSFT*>(&eventData)->listeningPort);break;}case XR_TYPE_REMOTING_EVENT_DATA_CONNECTED_MSFT: {DEBUG_PRINT("Holographic Remoting: Connected.");break;}case XR_TYPE_REMOTING_EVENT_DATA_DISCONNECTED_MSFT: {DEBUG_PRINT("Holographic Remoting: Disconnected - Reason: %d",reinterpret_cast<const XrRemotingEventDataDisconnectedMSFT*>(&eventData)->disconnectReason);break;}
}

6. XR初始化(ProcessWindowEventsWin32)

連接XR設備 (ConnectOrListen)

a. 使用Hololens的話,端口是8265,remoteHostName 就是眼鏡中顯示的ip地址。如果固定使用一臺電腦的話,可以初始化地址。

XrRemotingConnectInfoMSFT connectInfo{static_cast<XrStructureType>(XR_TYPE_REMOTING_CONNECT_INFO_MSFT)};
connectInfo.remoteHostName = "192.168.x.x";
connectInfo.remotePort = 8265;
connectInfo.secureConnection = false;
xrRemotingConnectMSFT(m_instance.Get(), m_systemId, &connectInfo);

b. 可以通過調用 xrRemotingListenMSFT 方法來偵聽遠程應用上的傳入連接

XrRemotingListenInfoMSFT listenInfo{static_cast<XrStructureType>(XR_TYPE_REMOTING_LISTEN_INFO_MSFT)};
listenInfo.listenInterface = "0.0.0.0";
listenInfo.handshakeListenPort = 8265;
listenInfo.transportListenPort = 8266;
listenInfo.secureConnection = false;
xrRemotingListenMSFT(m_instance.Get(), m_systemId, &listenInfo);

注意:代碼b必須在a前面,b是用來接收信號的,如果沒有收到信號就連接并創(chuàng)建任務,則運行到b時,就會報錯說是接收不到信息。

The timeout is fixed to 10 seconds.
If a connection can be established within this time, the XrSession creation will succeed and the session state will transition to XR_SESSION_STATE_READY.
In case no connection can be established the session creation also succeeds but immediately transitions to XR_SESSION_STATE_LOSS_PENDING.

初始化配置 (InitializeSession)

包括 CreateSpaces(包括獲取用戶空間坐標,詳見(四))CreateSwapchains兩個重要函數

7. 與交互相關的函數初始化(PollActions)

在while函數中實時識別雙手,定位手的位置等

// 手握住
if (placeActionValue.isActive && placeActionValue.changedSinceLastSync && placeActionValue.currentState) {//如果握住if (side == 0)//side=0左手,=1右手DEBUG_PRINT("BeginAction[LeftSide]");elseDEBUG_PRINT("BeginAction[RightSide]");//添加一些自定義函數...
}
// 手松開了
else if (placeActionValue.isActive && placeActionValue.changedSinceLastSync && !placeActionValue.currentState) {if (side == 0)DEBUG_PRINT("EndAction[LeftSide]");elseDEBUG_PRINT("EndAction[RightSide]");//添加一些自定義函數...
}

8. 將本地內容傳輸到眼鏡中(RenderFrame)

利用XrRemotingFrameMirrorImageInfoMSFT鏡像本地信息。

XrFrameEndInfo frameEndInfo{XR_TYPE_FRAME_END_INFO};
...
XrRemotingFrameMirrorImageD3D11MSFT mirrorImageD3D11{static_cast<XrStructureType>(XR_TYPE_REMOTING_FRAME_MIRROR_IMAGE_D3D11_MSFT)};
mirrorImageD3D11.texture = m_window->GetNextSwapchainTexture();
XrRemotingFrameMirrorImageInfoMSFT mirrorImageEndInfo{static_cast<XrStructureType>(XR_TYPE_REMOTING_FRAME_MIRROR_IMAGE_INFO_MSFT)};
mirrorImageEndInfo.image = reinterpret_cast<const XrRemotingFrameMirrorImageBaseHeaderMSFT*>(&mirrorImageD3D11);
frameEndInfo.next = &mirrorImageEndInfo;
xrEndFrame(m_session.Get(), &frameEndInfo);
m_window->PresentSwapchain();

總結

以上是生活随笔為你收集整理的Hololens2-OpenXR开发(二)-实现通讯的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。