12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999 |
- #include "openxr_api.h"
- #include "extensions/openxr_extension_wrapper_extension.h"
- #include "openxr_interface.h"
- #include "openxr_util.h"
- #include "core/config/engine.h"
- #include "core/config/project_settings.h"
- #include "core/os/memory.h"
- #include "core/version.h"
- #ifdef TOOLS_ENABLED
- #include "editor/editor_settings.h"
- #endif
- #include "openxr_platform_inc.h"
- #ifdef VULKAN_ENABLED
- #include "extensions/openxr_vulkan_extension.h"
- #endif
- #if defined(GLES3_ENABLED) && !defined(MACOS_ENABLED)
- #include "extensions/openxr_opengl_extension.h"
- #endif
- #include "extensions/openxr_composition_layer_depth_extension.h"
- #include "extensions/openxr_fb_display_refresh_rate_extension.h"
- #include "extensions/openxr_fb_foveation_extension.h"
- #include "extensions/openxr_fb_passthrough_extension_wrapper.h"
- #include "extensions/openxr_fb_update_swapchain_extension.h"
- #ifdef ANDROID_ENABLED
- #define OPENXR_LOADER_NAME "libopenxr_loader.so"
- #endif
- OpenXRAPI *OpenXRAPI::singleton = nullptr;
- Vector<OpenXRExtensionWrapper *> OpenXRAPI::registered_extension_wrappers;
- bool OpenXRAPI::openxr_is_enabled(bool p_check_run_in_editor) {
-
- if (Engine::get_singleton()->is_editor_hint() && p_check_run_in_editor) {
-
- return false;
- } else {
- if (XRServer::get_xr_mode() == XRServer::XRMODE_DEFAULT) {
- return GLOBAL_GET("xr/openxr/enabled");
- } else {
- return XRServer::get_xr_mode() == XRServer::XRMODE_ON;
- }
- }
- }
- String OpenXRAPI::get_default_action_map_resource_name() {
- String name = GLOBAL_GET("xr/openxr/default_action_map");
- return name;
- }
- String OpenXRAPI::get_error_string(XrResult result) {
- if (XR_SUCCEEDED(result)) {
- return String("Succeeded");
- }
- if (instance == XR_NULL_HANDLE) {
- Array args;
- args.push_back(Variant(result));
- return String("Error code {0}").format(args);
- }
- char resultString[XR_MAX_RESULT_STRING_SIZE];
- xrResultToString(instance, result, resultString);
- return String(resultString);
- }
- String OpenXRAPI::get_swapchain_format_name(int64_t p_swapchain_format) const {
-
- if (graphics_extension) {
- return graphics_extension->get_swapchain_format_name(p_swapchain_format);
- }
- return String("Swapchain format ") + String::num_int64(int64_t(p_swapchain_format));
- }
- bool OpenXRAPI::load_layer_properties() {
-
- if (layer_properties != nullptr) {
-
- return true;
- }
-
- XrResult result = xrEnumerateApiLayerProperties(0, &num_layer_properties, nullptr);
- ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate number of api layer properties");
- layer_properties = (XrApiLayerProperties *)memalloc(sizeof(XrApiLayerProperties) * num_layer_properties);
- ERR_FAIL_NULL_V(layer_properties, false);
- for (uint32_t i = 0; i < num_layer_properties; i++) {
- layer_properties[i].type = XR_TYPE_API_LAYER_PROPERTIES;
- layer_properties[i].next = nullptr;
- }
- result = xrEnumerateApiLayerProperties(num_layer_properties, &num_layer_properties, layer_properties);
- ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate api layer properties");
- for (uint32_t i = 0; i < num_layer_properties; i++) {
- print_verbose(String("OpenXR: Found OpenXR layer ") + layer_properties[i].layerName);
- }
- return true;
- }
- bool OpenXRAPI::load_supported_extensions() {
-
- if (supported_extensions != nullptr) {
-
- return true;
- }
-
- XrResult result = xrEnumerateInstanceExtensionProperties(nullptr, 0, &num_supported_extensions, nullptr);
- ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate number of extension properties");
- supported_extensions = (XrExtensionProperties *)memalloc(sizeof(XrExtensionProperties) * num_supported_extensions);
- ERR_FAIL_NULL_V(supported_extensions, false);
-
- for (uint32_t i = 0; i < num_supported_extensions; i++) {
- supported_extensions[i].type = XR_TYPE_EXTENSION_PROPERTIES;
- supported_extensions[i].next = nullptr;
- }
- result = xrEnumerateInstanceExtensionProperties(nullptr, num_supported_extensions, &num_supported_extensions, supported_extensions);
- ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate extension properties");
- for (uint32_t i = 0; i < num_supported_extensions; i++) {
- print_verbose(String("OpenXR: Found OpenXR extension ") + supported_extensions[i].extensionName);
- }
- return true;
- }
- bool OpenXRAPI::is_extension_supported(const String &p_extension) const {
- for (uint32_t i = 0; i < num_supported_extensions; i++) {
- if (supported_extensions[i].extensionName == p_extension) {
- return true;
- }
- }
- return false;
- }
- bool OpenXRAPI::is_extension_enabled(const String &p_extension) const {
- CharString extension = p_extension.ascii();
- for (int i = 0; i < enabled_extensions.size(); i++) {
- if (strcmp(enabled_extensions[i].ptr(), extension.ptr()) == 0) {
- return true;
- }
- }
- return false;
- }
- bool OpenXRAPI::is_top_level_path_supported(const String &p_toplevel_path) {
- String required_extension = OpenXRInteractionProfileMetadata::get_singleton()->get_top_level_extension(p_toplevel_path);
-
- ERR_FAIL_COND_V_MSG(required_extension == XR_PATH_UNSUPPORTED_NAME, false, "OpenXR: Unsupported toplevel path " + p_toplevel_path);
- if (required_extension == "") {
-
- return true;
- }
- if (!is_extension_enabled(required_extension)) {
-
- print_verbose("OpenXR: Top level path " + p_toplevel_path + " requires extension " + required_extension);
- return false;
- }
- return true;
- }
- bool OpenXRAPI::is_interaction_profile_supported(const String &p_ip_path) {
- String required_extension = OpenXRInteractionProfileMetadata::get_singleton()->get_interaction_profile_extension(p_ip_path);
-
- ERR_FAIL_COND_V_MSG(required_extension == XR_PATH_UNSUPPORTED_NAME, false, "OpenXR: Unsupported interaction profile " + p_ip_path);
- if (required_extension == "") {
-
- return true;
- }
- if (!is_extension_enabled(required_extension)) {
-
- print_verbose("OpenXR: Interaction profile " + p_ip_path + " requires extension " + required_extension);
- return false;
- }
- return true;
- }
- bool OpenXRAPI::interaction_profile_supports_io_path(const String &p_ip_path, const String &p_io_path) {
- if (!is_interaction_profile_supported(p_ip_path)) {
- return false;
- }
- const OpenXRInteractionProfileMetadata::IOPath *io_path = OpenXRInteractionProfileMetadata::get_singleton()->get_io_path(p_ip_path, p_io_path);
-
- ERR_FAIL_NULL_V_MSG(io_path, false, "OpenXR: Unsupported io path " + String(p_ip_path) + String(p_io_path));
- if (io_path->openxr_extension_name == "") {
-
- return true;
- }
- if (!is_extension_enabled(io_path->openxr_extension_name)) {
-
- print_verbose("OpenXR: IO path " + String(p_ip_path) + String(p_io_path) + " requires extension " + io_path->openxr_extension_name);
- return false;
- }
- return true;
- }
- void OpenXRAPI::copy_string_to_char_buffer(const String p_string, char *p_buffer, int p_buffer_len) {
- CharString char_string = p_string.utf8();
- int len = char_string.length();
- if (len < p_buffer_len - 1) {
-
- memcpy(p_buffer, char_string.get_data(), len);
- p_buffer[len] = '\0';
- } else {
- memcpy(p_buffer, char_string.get_data(), p_buffer_len - 1);
- p_buffer[p_buffer_len - 1] = '\0';
- }
- }
- bool OpenXRAPI::create_instance() {
-
-
- HashMap<String, bool *> requested_extensions;
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- const HashMap<String, bool *> &wrapper_request_extensions = wrapper->get_requested_extensions();
- for (const KeyValue<String, bool *> &requested_extension : wrapper_request_extensions) {
- requested_extensions[requested_extension.key] = requested_extension.value;
- }
- }
-
- enabled_extensions.clear();
- for (KeyValue<String, bool *> &requested_extension : requested_extensions) {
- if (!is_extension_supported(requested_extension.key)) {
- if (requested_extension.value == nullptr) {
-
- ERR_FAIL_V_MSG(false, String("OpenXR: OpenXR Runtime does not support ") + requested_extension.key + String(" extension!"));
- } else {
-
- *requested_extension.value = false;
- }
- } else if (requested_extension.value != nullptr) {
-
- *requested_extension.value = true;
-
- enabled_extensions.push_back(requested_extension.key.ascii());
- } else {
-
- enabled_extensions.push_back(requested_extension.key.ascii());
- }
- }
- Vector<const char *> extension_ptrs;
- for (int i = 0; i < enabled_extensions.size(); i++) {
- print_verbose(String("OpenXR: Enabling extension ") + String(enabled_extensions[i]));
- extension_ptrs.push_back(enabled_extensions[i].get_data());
- }
-
- String project_name = GLOBAL_GET("application/config/name");
-
- XrApplicationInfo application_info{
- "",
- 1,
- "Godot Game Engine",
- VERSION_MAJOR * 10000 + VERSION_MINOR * 100 + VERSION_PATCH,
- XR_CURRENT_API_VERSION
- };
- void *next_pointer = nullptr;
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- void *np = wrapper->set_instance_create_info_and_get_next_pointer(next_pointer);
- if (np != nullptr) {
- next_pointer = np;
- }
- }
- XrInstanceCreateInfo instance_create_info = {
- XR_TYPE_INSTANCE_CREATE_INFO,
- next_pointer,
- 0,
- application_info,
- 0,
- nullptr,
- uint32_t(extension_ptrs.size()),
- extension_ptrs.ptr()
- };
- copy_string_to_char_buffer(project_name, instance_create_info.applicationInfo.applicationName, XR_MAX_APPLICATION_NAME_SIZE);
- XrResult result = xrCreateInstance(&instance_create_info, &instance);
- ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "Failed to create XR instance.");
-
- XrInstanceProperties instanceProps = {
- XR_TYPE_INSTANCE_PROPERTIES,
- nullptr,
- 0,
- ""
- };
- OPENXR_API_INIT_XR_FUNC_V(xrGetInstanceProperties);
- result = xrGetInstanceProperties(instance, &instanceProps);
- if (XR_FAILED(result)) {
-
- print_line("OpenXR: Failed to get XR instance properties [", get_error_string(result), "]");
- runtime_name = "";
- runtime_version = "";
- } else {
- runtime_name = instanceProps.runtimeName;
- runtime_version = OpenXRUtil::make_xr_version_string(instanceProps.runtimeVersion);
- print_line("OpenXR: Running on OpenXR runtime: ", runtime_name, " ", runtime_version);
- }
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_instance_created(instance);
- }
- return true;
- }
- bool OpenXRAPI::get_system_info() {
-
-
- XrSystemGetInfo system_get_info = {
- XR_TYPE_SYSTEM_GET_INFO,
- nullptr,
- form_factor
- };
- XrResult result = xrGetSystem(instance, &system_get_info, &system_id);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to get system for our form factor [", get_error_string(result), "]");
- return false;
- }
-
- void *next_pointer = nullptr;
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- void *np = wrapper->set_system_properties_and_get_next_pointer(next_pointer);
- if (np != nullptr) {
- next_pointer = np;
- }
- }
- XrSystemProperties system_properties = {
- XR_TYPE_SYSTEM_PROPERTIES,
- next_pointer,
- 0,
- 0,
- "",
- {
- 0,
- 0,
- 0,
- },
- {
- false,
- false
- }
- };
- result = xrGetSystemProperties(instance, system_id, &system_properties);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to get System properties [", get_error_string(result), "]");
- return false;
- }
-
- system_name = String(system_properties.systemName);
- vendor_id = system_properties.vendorId;
- graphics_properties = system_properties.graphicsProperties;
- tracking_properties = system_properties.trackingProperties;
- return true;
- }
- bool OpenXRAPI::load_supported_view_configuration_types() {
-
- ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
- if (supported_view_configuration_types != nullptr) {
-
- memfree(supported_view_configuration_types);
- supported_view_configuration_types = nullptr;
- }
- XrResult result = xrEnumerateViewConfigurations(instance, system_id, 0, &num_view_configuration_types, nullptr);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to get view configuration count [", get_error_string(result), "]");
- return false;
- }
- supported_view_configuration_types = (XrViewConfigurationType *)memalloc(sizeof(XrViewConfigurationType) * num_view_configuration_types);
- ERR_FAIL_NULL_V(supported_view_configuration_types, false);
- result = xrEnumerateViewConfigurations(instance, system_id, num_view_configuration_types, &num_view_configuration_types, supported_view_configuration_types);
- ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerateview configurations");
- ERR_FAIL_COND_V_MSG(num_view_configuration_types == 0, false, "OpenXR: Failed to enumerateview configurations");
- for (uint32_t i = 0; i < num_view_configuration_types; i++) {
- print_verbose(String("OpenXR: Found supported view configuration ") + OpenXRUtil::get_view_configuration_name(supported_view_configuration_types[i]));
- }
-
- if (!is_view_configuration_supported(view_configuration)) {
- print_verbose(String("OpenXR: ") + OpenXRUtil::get_view_configuration_name(view_configuration) + String(" isn't supported, defaulting to ") + OpenXRUtil::get_view_configuration_name(supported_view_configuration_types[0]));
- view_configuration = supported_view_configuration_types[0];
- }
- return true;
- }
- bool OpenXRAPI::load_supported_environmental_blend_modes() {
-
- ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
- if (supported_environment_blend_modes != nullptr) {
-
- memfree(supported_environment_blend_modes);
- supported_environment_blend_modes = nullptr;
- num_supported_environment_blend_modes = 0;
- }
- XrResult result = xrEnumerateEnvironmentBlendModes(instance, system_id, view_configuration, 0, &num_supported_environment_blend_modes, nullptr);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to get supported environmental blend mode count [", get_error_string(result), "]");
- return false;
- }
- supported_environment_blend_modes = (XrEnvironmentBlendMode *)memalloc(sizeof(XrEnvironmentBlendMode) * num_supported_environment_blend_modes);
- ERR_FAIL_NULL_V(supported_environment_blend_modes, false);
- result = xrEnumerateEnvironmentBlendModes(instance, system_id, view_configuration, num_supported_environment_blend_modes, &num_supported_environment_blend_modes, supported_environment_blend_modes);
- ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate environmental blend modes");
- ERR_FAIL_COND_V_MSG(num_supported_environment_blend_modes == 0, false, "OpenXR: Failed to enumerate environmental blend modes");
- for (uint32_t i = 0; i < num_supported_environment_blend_modes; i++) {
- print_verbose(String("OpenXR: Found environmental blend mode ") + OpenXRUtil::get_environment_blend_mode_name(supported_environment_blend_modes[i]));
- }
-
- if (!is_environment_blend_mode_supported(environment_blend_mode)) {
- print_verbose(String("OpenXR: ") + OpenXRUtil::get_environment_blend_mode_name(environment_blend_mode) + String(" isn't supported, defaulting to ") + OpenXRUtil::get_environment_blend_mode_name(supported_environment_blend_modes[0]));
- environment_blend_mode = supported_environment_blend_modes[0];
- }
- return true;
- }
- bool OpenXRAPI::is_view_configuration_supported(XrViewConfigurationType p_configuration_type) const {
- ERR_FAIL_NULL_V(supported_view_configuration_types, false);
- for (uint32_t i = 0; i < num_view_configuration_types; i++) {
- if (supported_view_configuration_types[i] == p_configuration_type) {
- return true;
- }
- }
- return false;
- }
- bool OpenXRAPI::load_supported_view_configuration_views(XrViewConfigurationType p_configuration_type) {
-
-
- if (!is_view_configuration_supported(p_configuration_type)) {
- print_line("OpenXR: View configuration ", OpenXRUtil::get_view_configuration_name(view_configuration), " is not supported.");
- return false;
- }
- if (view_configuration_views != nullptr) {
-
- memfree(view_configuration_views);
- view_configuration_views = nullptr;
- }
- XrResult result = xrEnumerateViewConfigurationViews(instance, system_id, p_configuration_type, 0, &view_count, nullptr);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to get view configuration count [", get_error_string(result), "]");
- return false;
- }
- view_configuration_views = (XrViewConfigurationView *)memalloc(sizeof(XrViewConfigurationView) * view_count);
- ERR_FAIL_NULL_V(view_configuration_views, false);
- for (uint32_t i = 0; i < view_count; i++) {
- view_configuration_views[i].type = XR_TYPE_VIEW_CONFIGURATION_VIEW;
- view_configuration_views[i].next = nullptr;
- }
- result = xrEnumerateViewConfigurationViews(instance, system_id, p_configuration_type, view_count, &view_count, view_configuration_views);
- ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate view configurations");
- for (uint32_t i = 0; i < view_count; i++) {
- print_verbose("OpenXR: Found supported view configuration view");
- print_verbose(String(" - width: ") + itos(view_configuration_views[i].maxImageRectWidth));
- print_verbose(String(" - height: ") + itos(view_configuration_views[i].maxImageRectHeight));
- print_verbose(String(" - sample count: ") + itos(view_configuration_views[i].maxSwapchainSampleCount));
- print_verbose(String(" - recommended render width: ") + itos(view_configuration_views[i].recommendedImageRectWidth));
- print_verbose(String(" - recommended render height: ") + itos(view_configuration_views[i].recommendedImageRectHeight));
- print_verbose(String(" - recommended render sample count: ") + itos(view_configuration_views[i].recommendedSwapchainSampleCount));
- }
- return true;
- }
- void OpenXRAPI::destroy_instance() {
- if (view_configuration_views != nullptr) {
- memfree(view_configuration_views);
- view_configuration_views = nullptr;
- }
- if (supported_view_configuration_types != nullptr) {
- memfree(supported_view_configuration_types);
- supported_view_configuration_types = nullptr;
- }
- if (supported_environment_blend_modes != nullptr) {
- memfree(supported_environment_blend_modes);
- supported_environment_blend_modes = nullptr;
- num_supported_environment_blend_modes = 0;
- }
- if (instance != XR_NULL_HANDLE) {
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_instance_destroyed();
- }
- xrDestroyInstance(instance);
- instance = XR_NULL_HANDLE;
- }
- enabled_extensions.clear();
- if (graphics_extension != nullptr) {
- unregister_extension_wrapper(graphics_extension);
- memdelete(graphics_extension);
- graphics_extension = nullptr;
- }
- }
- bool OpenXRAPI::create_session() {
- ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
- ERR_FAIL_COND_V(session != XR_NULL_HANDLE, false);
- void *next_pointer = nullptr;
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- void *np = wrapper->set_session_create_and_get_next_pointer(next_pointer);
- if (np != nullptr) {
- next_pointer = np;
- }
- }
- XrSessionCreateInfo session_create_info = {
- XR_TYPE_SESSION_CREATE_INFO,
- next_pointer,
- 0,
- system_id
- };
- XrResult result = xrCreateSession(instance, &session_create_info, &session);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to create session [", get_error_string(result), "]");
- return false;
- }
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_session_created(session);
- }
- return true;
- }
- bool OpenXRAPI::load_supported_reference_spaces() {
-
- ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
- if (supported_reference_spaces != nullptr) {
-
- memfree(supported_reference_spaces);
- supported_reference_spaces = nullptr;
- }
- XrResult result = xrEnumerateReferenceSpaces(session, 0, &num_reference_spaces, nullptr);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to get reference space count [", get_error_string(result), "]");
- return false;
- }
- supported_reference_spaces = (XrReferenceSpaceType *)memalloc(sizeof(XrReferenceSpaceType) * num_reference_spaces);
- ERR_FAIL_NULL_V(supported_reference_spaces, false);
- result = xrEnumerateReferenceSpaces(session, num_reference_spaces, &num_reference_spaces, supported_reference_spaces);
- ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate reference spaces");
- ERR_FAIL_COND_V_MSG(num_reference_spaces == 0, false, "OpenXR: Failed to enumerate reference spaces");
- for (uint32_t i = 0; i < num_reference_spaces; i++) {
- print_verbose(String("OpenXR: Found supported reference space ") + OpenXRUtil::get_reference_space_name(supported_reference_spaces[i]));
- }
-
- if (!is_reference_space_supported(reference_space)) {
- print_verbose(String("OpenXR: ") + OpenXRUtil::get_reference_space_name(reference_space) + String(" isn't supported, defaulting to ") + OpenXRUtil::get_reference_space_name(supported_reference_spaces[0]));
- reference_space = supported_reference_spaces[0];
- }
- return true;
- }
- bool OpenXRAPI::is_reference_space_supported(XrReferenceSpaceType p_reference_space) {
- ERR_FAIL_NULL_V(supported_reference_spaces, false);
- for (uint32_t i = 0; i < num_reference_spaces; i++) {
- if (supported_reference_spaces[i] == p_reference_space) {
- return true;
- }
- }
- return false;
- }
- bool OpenXRAPI::setup_spaces() {
- XrResult result;
- XrPosef identityPose = {
- { 0.0, 0.0, 0.0, 1.0 },
- { 0.0, 0.0, 0.0 }
- };
- ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
-
- {
- if (!is_reference_space_supported(reference_space)) {
- print_line("OpenXR: reference space ", OpenXRUtil::get_reference_space_name(reference_space), " is not supported.");
- return false;
- }
- XrReferenceSpaceCreateInfo play_space_create_info = {
- XR_TYPE_REFERENCE_SPACE_CREATE_INFO,
- nullptr,
- reference_space,
- identityPose
- };
- result = xrCreateReferenceSpace(session, &play_space_create_info, &play_space);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to create play space [", get_error_string(result), "]");
- return false;
- }
- }
-
- {
- if (!is_reference_space_supported(XR_REFERENCE_SPACE_TYPE_VIEW)) {
- print_line("OpenXR: reference space XR_REFERENCE_SPACE_TYPE_VIEW is not supported.");
- return false;
- }
- XrReferenceSpaceCreateInfo view_space_create_info = {
- XR_TYPE_REFERENCE_SPACE_CREATE_INFO,
- nullptr,
- XR_REFERENCE_SPACE_TYPE_VIEW,
- identityPose
- };
- result = xrCreateReferenceSpace(session, &view_space_create_info, &view_space);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to create view space [", get_error_string(result), "]");
- return false;
- }
- }
- return true;
- }
- bool OpenXRAPI::load_supported_swapchain_formats() {
- ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
- if (supported_swapchain_formats != nullptr) {
-
- memfree(supported_swapchain_formats);
- supported_swapchain_formats = nullptr;
- }
- XrResult result = xrEnumerateSwapchainFormats(session, 0, &num_swapchain_formats, nullptr);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to get swapchain format count [", get_error_string(result), "]");
- return false;
- }
- supported_swapchain_formats = (int64_t *)memalloc(sizeof(int64_t) * num_swapchain_formats);
- ERR_FAIL_NULL_V(supported_swapchain_formats, false);
- result = xrEnumerateSwapchainFormats(session, num_swapchain_formats, &num_swapchain_formats, supported_swapchain_formats);
- ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "OpenXR: Failed to enumerate swapchain formats");
- for (uint32_t i = 0; i < num_swapchain_formats; i++) {
- print_verbose(String("OpenXR: Found supported swapchain format ") + get_swapchain_format_name(supported_swapchain_formats[i]));
- }
- return true;
- }
- bool OpenXRAPI::is_swapchain_format_supported(int64_t p_swapchain_format) {
- ERR_FAIL_NULL_V(supported_swapchain_formats, false);
- for (uint32_t i = 0; i < num_swapchain_formats; i++) {
- if (supported_swapchain_formats[i] == p_swapchain_format) {
- return true;
- }
- }
- return false;
- }
- bool OpenXRAPI::create_swapchains() {
- ERR_FAIL_NULL_V(graphics_extension, false);
- ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
-
- Size2 recommended_size = get_recommended_target_size();
- uint32_t sample_count = 1;
-
- {
-
- Vector<int64_t> usable_swapchain_formats;
- int64_t swapchain_format_to_use = 0;
- graphics_extension->get_usable_swapchain_formats(usable_swapchain_formats);
-
- for (int i = 0; i < usable_swapchain_formats.size() && swapchain_format_to_use == 0; i++) {
- if (is_swapchain_format_supported(usable_swapchain_formats[i])) {
- swapchain_format_to_use = usable_swapchain_formats[i];
- }
- }
- if (swapchain_format_to_use == 0) {
- swapchain_format_to_use = usable_swapchain_formats[0];
- print_line("Couldn't find usable color swap chain format, using", get_swapchain_format_name(swapchain_format_to_use), "instead.");
- } else {
- print_verbose(String("Using color swap chain format:") + get_swapchain_format_name(swapchain_format_to_use));
- }
- if (!create_swapchain(XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT | XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT, swapchain_format_to_use, recommended_size.width, recommended_size.height, sample_count, view_count, swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain, &swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain_graphics_data)) {
- return false;
- }
- }
- views = (XrView *)memalloc(sizeof(XrView) * view_count);
- ERR_FAIL_NULL_V_MSG(views, false, "OpenXR Couldn't allocate memory for views");
- projection_views = (XrCompositionLayerProjectionView *)memalloc(sizeof(XrCompositionLayerProjectionView) * view_count);
- ERR_FAIL_NULL_V_MSG(projection_views, false, "OpenXR Couldn't allocate memory for projection views");
-
-
-
-
- if (submit_depth_buffer && OpenXRCompositionLayerDepthExtension::get_singleton()->is_available()) {
-
- Vector<int64_t> usable_swapchain_formats;
- int64_t swapchain_format_to_use = 0;
- graphics_extension->get_usable_depth_formats(usable_swapchain_formats);
-
- for (int i = 0; i < usable_swapchain_formats.size() && swapchain_format_to_use == 0; i++) {
- if (is_swapchain_format_supported(usable_swapchain_formats[i])) {
- swapchain_format_to_use = usable_swapchain_formats[i];
- }
- }
- if (swapchain_format_to_use == 0) {
- print_line("Couldn't find usable depth swap chain format, depth buffer will not be submitted.");
- } else {
- print_verbose(String("Using depth swap chain format:") + get_swapchain_format_name(swapchain_format_to_use));
-
- if (!create_swapchain(XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, swapchain_format_to_use, recommended_size.width, recommended_size.height, sample_count, view_count, swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain, &swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain_graphics_data)) {
- return false;
- }
- depth_views = (XrCompositionLayerDepthInfoKHR *)memalloc(sizeof(XrCompositionLayerDepthInfoKHR) * view_count);
- ERR_FAIL_NULL_V_MSG(depth_views, false, "OpenXR Couldn't allocate memory for depth views");
- }
- }
-
-
- {
-
- }
- for (uint32_t i = 0; i < view_count; i++) {
- views[i].type = XR_TYPE_VIEW;
- views[i].next = nullptr;
- projection_views[i].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
- projection_views[i].next = nullptr;
- projection_views[i].subImage.swapchain = swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain;
- projection_views[i].subImage.imageArrayIndex = i;
- projection_views[i].subImage.imageRect.offset.x = 0;
- projection_views[i].subImage.imageRect.offset.y = 0;
- projection_views[i].subImage.imageRect.extent.width = recommended_size.width;
- projection_views[i].subImage.imageRect.extent.height = recommended_size.height;
- if (submit_depth_buffer && OpenXRCompositionLayerDepthExtension::get_singleton()->is_available() && depth_views) {
- projection_views[i].next = &depth_views[i];
- depth_views[i].type = XR_TYPE_COMPOSITION_LAYER_DEPTH_INFO_KHR;
- depth_views[i].next = nullptr;
- depth_views[i].subImage.swapchain = swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain;
- depth_views[i].subImage.imageArrayIndex = i;
- depth_views[i].subImage.imageRect.offset.x = 0;
- depth_views[i].subImage.imageRect.offset.y = 0;
- depth_views[i].subImage.imageRect.extent.width = recommended_size.width;
- depth_views[i].subImage.imageRect.extent.height = recommended_size.height;
- depth_views[i].minDepth = 0.0;
- depth_views[i].maxDepth = 1.0;
- depth_views[i].nearZ = 0.01;
- depth_views[i].farZ = 100.0;
- }
- };
- return true;
- };
- void OpenXRAPI::destroy_session() {
- if (running && session != XR_NULL_HANDLE) {
- xrEndSession(session);
- }
- if (graphics_extension) {
- graphics_extension->cleanup_swapchain_graphics_data(&swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain_graphics_data);
- }
- if (views != nullptr) {
- memfree(views);
- views = nullptr;
- }
- if (projection_views != nullptr) {
- memfree(projection_views);
- projection_views = nullptr;
- }
- if (depth_views != nullptr) {
- memfree(depth_views);
- depth_views = nullptr;
- }
- for (int i = 0; i < OPENXR_SWAPCHAIN_MAX; i++) {
- if (swapchains[i].swapchain != XR_NULL_HANDLE) {
- xrDestroySwapchain(swapchains[i].swapchain);
- swapchains[i].swapchain = XR_NULL_HANDLE;
- }
- }
- if (supported_swapchain_formats != nullptr) {
- memfree(supported_swapchain_formats);
- supported_swapchain_formats = nullptr;
- }
-
- if (play_space != XR_NULL_HANDLE) {
- xrDestroySpace(play_space);
- play_space = XR_NULL_HANDLE;
- }
- if (view_space != XR_NULL_HANDLE) {
- xrDestroySpace(view_space);
- view_space = XR_NULL_HANDLE;
- }
- if (supported_reference_spaces != nullptr) {
-
- memfree(supported_reference_spaces);
- supported_reference_spaces = nullptr;
- }
- if (session != XR_NULL_HANDLE) {
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_session_destroyed();
- }
- xrDestroySession(session);
- session = XR_NULL_HANDLE;
- }
- }
- bool OpenXRAPI::create_swapchain(XrSwapchainUsageFlags p_usage_flags, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, XrSwapchain &r_swapchain, void **r_swapchain_graphics_data) {
- ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
- ERR_FAIL_NULL_V(graphics_extension, false);
- XrResult result;
- void *next_pointer = nullptr;
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- void *np = wrapper->set_swapchain_create_info_and_get_next_pointer(next_pointer);
- if (np != nullptr) {
- next_pointer = np;
- }
- }
- XrSwapchainCreateInfo swapchain_create_info = {
- XR_TYPE_SWAPCHAIN_CREATE_INFO,
- next_pointer,
- 0,
- p_usage_flags,
- p_swapchain_format,
- p_sample_count,
- p_width,
- p_height,
- 1,
- p_array_size,
- 1
- };
- XrSwapchain new_swapchain;
- result = xrCreateSwapchain(session, &swapchain_create_info, &new_swapchain);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to get swapchain [", get_error_string(result), "]");
- return false;
- }
- if (!graphics_extension->get_swapchain_image_data(new_swapchain, p_swapchain_format, p_width, p_height, p_sample_count, p_array_size, r_swapchain_graphics_data)) {
- xrDestroySwapchain(new_swapchain);
- return false;
- }
- r_swapchain = new_swapchain;
- return true;
- }
- bool OpenXRAPI::on_state_idle() {
- print_verbose("On state idle");
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_state_idle();
- }
- return true;
- }
- bool OpenXRAPI::on_state_ready() {
- print_verbose("On state ready");
-
- XrSessionBeginInfo session_begin_info = {
- XR_TYPE_SESSION_BEGIN_INFO,
- nullptr,
- view_configuration
- };
- XrResult result = xrBeginSession(session, &session_begin_info);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to begin session [", get_error_string(result), "]");
- return false;
- }
-
-
-
-
-
-
- if (!create_swapchains()) {
- return false;
- }
-
- running = true;
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_state_ready();
- }
- if (xr_interface) {
- xr_interface->on_state_ready();
- }
-
- return true;
- }
- bool OpenXRAPI::on_state_synchronized() {
- print_verbose("On state synchronized");
-
- List<RID> trackers;
- tracker_owner.get_owned_list(&trackers);
- for (int i = 0; i < trackers.size(); i++) {
- tracker_check_profile(trackers[i]);
- }
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_state_synchronized();
- }
- return true;
- }
- bool OpenXRAPI::on_state_visible() {
- print_verbose("On state visible");
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_state_visible();
- }
- if (xr_interface) {
- xr_interface->on_state_visible();
- }
- return true;
- }
- bool OpenXRAPI::on_state_focused() {
- print_verbose("On state focused");
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_state_focused();
- }
- if (xr_interface) {
- xr_interface->on_state_focused();
- }
- return true;
- }
- bool OpenXRAPI::on_state_stopping() {
- print_verbose("On state stopping");
- if (xr_interface) {
- xr_interface->on_state_stopping();
- }
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_state_stopping();
- }
- if (running) {
- XrResult result = xrEndSession(session);
- if (XR_FAILED(result)) {
-
- print_line("OpenXR: Failed to end session [", get_error_string(result), "]");
- }
- running = false;
- }
-
- return true;
- }
- bool OpenXRAPI::on_state_loss_pending() {
- print_verbose("On state loss pending");
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_state_loss_pending();
- }
-
- return true;
- }
- bool OpenXRAPI::on_state_exiting() {
- print_verbose("On state existing");
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_state_exiting();
- }
-
- return true;
- }
- void OpenXRAPI::set_form_factor(XrFormFactor p_form_factor) {
- ERR_FAIL_COND(is_initialized());
- form_factor = p_form_factor;
- }
- void OpenXRAPI::set_view_configuration(XrViewConfigurationType p_view_configuration) {
- ERR_FAIL_COND(is_initialized());
- view_configuration = p_view_configuration;
- }
- void OpenXRAPI::set_reference_space(XrReferenceSpaceType p_reference_space) {
- ERR_FAIL_COND(is_initialized());
- reference_space = p_reference_space;
- }
- void OpenXRAPI::set_submit_depth_buffer(bool p_submit_depth_buffer) {
- ERR_FAIL_COND(is_initialized());
- submit_depth_buffer = p_submit_depth_buffer;
- }
- bool OpenXRAPI::is_initialized() {
- return (instance != XR_NULL_HANDLE);
- }
- bool OpenXRAPI::is_running() {
- if (instance == XR_NULL_HANDLE) {
- return false;
- }
- if (session == XR_NULL_HANDLE) {
- return false;
- }
- return running;
- }
- bool OpenXRAPI::openxr_loader_init() {
- #ifdef ANDROID_ENABLED
- ERR_FAIL_COND_V_MSG(openxr_loader_library_handle != nullptr, false, "OpenXR Loader library is already loaded.");
- {
- Error error_code = OS::get_singleton()->open_dynamic_library(OPENXR_LOADER_NAME, openxr_loader_library_handle);
- ERR_FAIL_COND_V_MSG(error_code != OK, false, "OpenXR loader not found.");
- }
- {
- Error error_code = OS::get_singleton()->get_dynamic_library_symbol_handle(openxr_loader_library_handle, "xrGetInstanceProcAddr", (void *&)xrGetInstanceProcAddr);
- ERR_FAIL_COND_V_MSG(error_code != OK, false, "Symbol xrGetInstanceProcAddr not found in OpenXR Loader library.");
- }
- #endif
-
- OPENXR_API_INIT_XR_FUNC_V(xrCreateInstance);
- OPENXR_API_INIT_XR_FUNC_V(xrEnumerateApiLayerProperties);
- OPENXR_API_INIT_XR_FUNC_V(xrEnumerateInstanceExtensionProperties);
- return true;
- }
- bool OpenXRAPI::resolve_instance_openxr_symbols() {
- ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
- OPENXR_API_INIT_XR_FUNC_V(xrAcquireSwapchainImage);
- OPENXR_API_INIT_XR_FUNC_V(xrApplyHapticFeedback);
- OPENXR_API_INIT_XR_FUNC_V(xrAttachSessionActionSets);
- OPENXR_API_INIT_XR_FUNC_V(xrBeginFrame);
- OPENXR_API_INIT_XR_FUNC_V(xrBeginSession);
- OPENXR_API_INIT_XR_FUNC_V(xrCreateAction);
- OPENXR_API_INIT_XR_FUNC_V(xrCreateActionSet);
- OPENXR_API_INIT_XR_FUNC_V(xrCreateActionSpace);
- OPENXR_API_INIT_XR_FUNC_V(xrCreateReferenceSpace);
- OPENXR_API_INIT_XR_FUNC_V(xrCreateSession);
- OPENXR_API_INIT_XR_FUNC_V(xrCreateSwapchain);
- OPENXR_API_INIT_XR_FUNC_V(xrDestroyAction);
- OPENXR_API_INIT_XR_FUNC_V(xrDestroyActionSet);
- OPENXR_API_INIT_XR_FUNC_V(xrDestroyInstance);
- OPENXR_API_INIT_XR_FUNC_V(xrDestroySession);
- OPENXR_API_INIT_XR_FUNC_V(xrDestroySpace);
- OPENXR_API_INIT_XR_FUNC_V(xrDestroySwapchain);
- OPENXR_API_INIT_XR_FUNC_V(xrEndFrame);
- OPENXR_API_INIT_XR_FUNC_V(xrEndSession);
- OPENXR_API_INIT_XR_FUNC_V(xrEnumerateEnvironmentBlendModes);
- OPENXR_API_INIT_XR_FUNC_V(xrEnumerateReferenceSpaces);
- OPENXR_API_INIT_XR_FUNC_V(xrEnumerateSwapchainFormats);
- OPENXR_API_INIT_XR_FUNC_V(xrEnumerateViewConfigurations);
- OPENXR_API_INIT_XR_FUNC_V(xrEnumerateViewConfigurationViews);
- OPENXR_API_INIT_XR_FUNC_V(xrGetActionStateBoolean);
- OPENXR_API_INIT_XR_FUNC_V(xrGetActionStateFloat);
- OPENXR_API_INIT_XR_FUNC_V(xrGetActionStateVector2f);
- OPENXR_API_INIT_XR_FUNC_V(xrGetCurrentInteractionProfile);
- OPENXR_API_INIT_XR_FUNC_V(xrGetSystem);
- OPENXR_API_INIT_XR_FUNC_V(xrGetSystemProperties);
- OPENXR_API_INIT_XR_FUNC_V(xrLocateViews);
- OPENXR_API_INIT_XR_FUNC_V(xrLocateSpace);
- OPENXR_API_INIT_XR_FUNC_V(xrPathToString);
- OPENXR_API_INIT_XR_FUNC_V(xrPollEvent);
- OPENXR_API_INIT_XR_FUNC_V(xrReleaseSwapchainImage);
- OPENXR_API_INIT_XR_FUNC_V(xrResultToString);
- OPENXR_API_INIT_XR_FUNC_V(xrStringToPath);
- OPENXR_API_INIT_XR_FUNC_V(xrSuggestInteractionProfileBindings);
- OPENXR_API_INIT_XR_FUNC_V(xrSyncActions);
- OPENXR_API_INIT_XR_FUNC_V(xrWaitFrame);
- OPENXR_API_INIT_XR_FUNC_V(xrWaitSwapchainImage);
- return true;
- }
- XrResult OpenXRAPI::try_get_instance_proc_addr(const char *p_name, PFN_xrVoidFunction *p_addr) {
- return xrGetInstanceProcAddr(instance, p_name, p_addr);
- }
- XrResult OpenXRAPI::get_instance_proc_addr(const char *p_name, PFN_xrVoidFunction *p_addr) {
- XrResult result = try_get_instance_proc_addr(p_name, p_addr);
- if (result != XR_SUCCESS) {
- String error_message = String("Symbol ") + p_name + " not found in OpenXR instance.";
- ERR_FAIL_V_MSG(result, error_message.utf8().get_data());
- }
- return result;
- }
- bool OpenXRAPI::initialize(const String &p_rendering_driver) {
- ERR_FAIL_COND_V_MSG(instance != XR_NULL_HANDLE, false, "OpenXR instance was already created");
- if (!openxr_loader_init()) {
- return false;
- }
- if (p_rendering_driver == "vulkan") {
- #ifdef VULKAN_ENABLED
- graphics_extension = memnew(OpenXRVulkanExtension);
- register_extension_wrapper(graphics_extension);
- #else
-
- ERR_FAIL_V(false);
- #endif
- } else if (p_rendering_driver == "opengl3") {
- #if defined(GLES3_ENABLED) && !defined(MACOS_ENABLED)
- graphics_extension = memnew(OpenXROpenGLExtension);
- register_extension_wrapper(graphics_extension);
- #else
-
- ERR_FAIL_V(false);
- #endif
- } else {
- ERR_FAIL_V_MSG(false, "OpenXR: Unsupported rendering device.");
- }
-
- register_extension_wrapper(memnew(OpenXRFBUpdateSwapchainExtension(p_rendering_driver)));
- register_extension_wrapper(memnew(OpenXRFBFoveationExtension(p_rendering_driver)));
-
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_before_instance_created();
- }
- if (!load_layer_properties()) {
- destroy_instance();
- return false;
- }
- if (!load_supported_extensions()) {
- destroy_instance();
- return false;
- }
- if (!create_instance()) {
- destroy_instance();
- return false;
- }
- if (!resolve_instance_openxr_symbols()) {
- destroy_instance();
- return false;
- }
- if (!get_system_info()) {
- destroy_instance();
- return false;
- }
- if (!load_supported_view_configuration_types()) {
- destroy_instance();
- return false;
- }
- if (!load_supported_view_configuration_views(view_configuration)) {
- destroy_instance();
- return false;
- }
- if (!load_supported_environmental_blend_modes()) {
- destroy_instance();
- return false;
- }
- return true;
- }
- bool OpenXRAPI::initialize_session() {
- if (!create_session()) {
- destroy_session();
- return false;
- }
- if (!load_supported_reference_spaces()) {
- destroy_session();
- return false;
- }
- if (!setup_spaces()) {
- destroy_session();
- return false;
- }
- if (!load_supported_swapchain_formats()) {
- destroy_session();
- return false;
- }
- return true;
- }
- void OpenXRAPI::finish() {
- destroy_session();
- destroy_instance();
- }
- void OpenXRAPI::set_xr_interface(OpenXRInterface *p_xr_interface) {
- xr_interface = p_xr_interface;
- }
- void OpenXRAPI::register_extension_wrapper(OpenXRExtensionWrapper *p_extension_wrapper) {
- registered_extension_wrappers.push_back(p_extension_wrapper);
- }
- void OpenXRAPI::unregister_extension_wrapper(OpenXRExtensionWrapper *p_extension_wrapper) {
- registered_extension_wrappers.erase(p_extension_wrapper);
- }
- void OpenXRAPI::register_extension_metadata() {
- for (OpenXRExtensionWrapper *extension_wrapper : registered_extension_wrappers) {
- extension_wrapper->on_register_metadata();
- }
- }
- void OpenXRAPI::cleanup_extension_wrappers() {
- for (OpenXRExtensionWrapper *extension_wrapper : registered_extension_wrappers) {
-
- OpenXRExtensionWrapperExtension *gdextension_extension_wrapper = dynamic_cast<OpenXRExtensionWrapperExtension *>(extension_wrapper);
- if (gdextension_extension_wrapper) {
- memdelete(gdextension_extension_wrapper);
- } else {
- memdelete(extension_wrapper);
- }
- }
- registered_extension_wrappers.clear();
- }
- Size2 OpenXRAPI::get_recommended_target_size() {
- ERR_FAIL_NULL_V(view_configuration_views, Size2());
- Size2 target_size;
- target_size.width = view_configuration_views[0].recommendedImageRectWidth * render_target_size_multiplier;
- target_size.height = view_configuration_views[0].recommendedImageRectHeight * render_target_size_multiplier;
- return target_size;
- }
- XRPose::TrackingConfidence OpenXRAPI::get_head_center(Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity) {
- XrResult result;
- if (!running) {
- return XRPose::XR_TRACKING_CONFIDENCE_NONE;
- }
-
- if (frame_state.predictedDisplayTime == 0) {
- return XRPose::XR_TRACKING_CONFIDENCE_NONE;
- }
-
- XrTime display_time = get_next_frame_time();
- XrSpaceVelocity velocity = {
- XR_TYPE_SPACE_VELOCITY,
- nullptr,
- 0,
- { 0.0, 0.0, 0.0 },
- { 0.0, 0.0, 0.0 }
- };
- XrSpaceLocation location = {
- XR_TYPE_SPACE_LOCATION,
- &velocity,
- 0,
- {
- { 0.0, 0.0, 0.0, 0.0 },
- { 0.0, 0.0, 0.0 }
- }
- };
- result = xrLocateSpace(view_space, play_space, display_time, &location);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to locate view space in play space [", get_error_string(result), "]");
- return XRPose::XR_TRACKING_CONFIDENCE_NONE;
- }
- XRPose::TrackingConfidence confidence = transform_from_location(location, r_transform);
- parse_velocities(velocity, r_linear_velocity, r_angular_velocity);
- if (head_pose_confidence != confidence) {
-
- head_pose_confidence = confidence;
- if (head_pose_confidence == XRPose::XR_TRACKING_CONFIDENCE_NONE) {
- print_line("OpenXR head space location not valid (check tracking?)");
- } else if (head_pose_confidence == XRPose::XR_TRACKING_CONFIDENCE_LOW) {
- print_verbose("OpenVR Head pose now tracking with low confidence");
- } else {
- print_verbose("OpenVR Head pose now tracking with high confidence");
- }
- }
- return confidence;
- }
- bool OpenXRAPI::get_view_transform(uint32_t p_view, Transform3D &r_transform) {
- if (!running) {
- return false;
- }
-
- if (frame_state.predictedDisplayTime == 0) {
- return false;
- }
-
- if (views == nullptr || !view_pose_valid) {
- return false;
- }
-
- r_transform = transform_from_pose(views[p_view].pose);
- return true;
- }
- bool OpenXRAPI::get_view_projection(uint32_t p_view, double p_z_near, double p_z_far, Projection &p_camera_matrix) {
- ERR_FAIL_NULL_V(graphics_extension, false);
- if (!running) {
- return false;
- }
-
- if (frame_state.predictedDisplayTime == 0) {
- return false;
- }
-
- if (views == nullptr || !view_pose_valid) {
- return false;
- }
-
- if (depth_views != nullptr) {
- for (uint32_t i = 0; i < view_count; i++) {
- depth_views[i].nearZ = p_z_near;
- depth_views[i].farZ = p_z_far;
- }
- }
-
- return graphics_extension->create_projection_fov(views[p_view].fov, p_z_near, p_z_far, p_camera_matrix);
- }
- bool OpenXRAPI::poll_events() {
- ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
- XrEventDataBuffer runtimeEvent;
- runtimeEvent.type = XR_TYPE_EVENT_DATA_BUFFER;
- runtimeEvent.next = nullptr;
-
- XrResult pollResult = xrPollEvent(instance, &runtimeEvent);
- while (pollResult == XR_SUCCESS) {
- bool handled = false;
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- handled |= wrapper->on_event_polled(runtimeEvent);
- }
- switch (runtimeEvent.type) {
- case XR_TYPE_EVENT_DATA_EVENTS_LOST: {
- XrEventDataEventsLost *event = (XrEventDataEventsLost *)&runtimeEvent;
-
- WARN_PRINT("OpenXR EVENT: " + itos(event->lostEventCount) + " event data lost!");
- } break;
- case XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR: {
-
-
-
-
- print_verbose("OpenXR EVENT: STUB: visibility mask changed");
- } break;
- case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING: {
- XrEventDataInstanceLossPending *event = (XrEventDataInstanceLossPending *)&runtimeEvent;
-
-
- print_verbose(String("OpenXR EVENT: instance loss pending at ") + itos(event->lossTime));
- return false;
- } break;
- case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: {
- XrEventDataSessionStateChanged *event = (XrEventDataSessionStateChanged *)&runtimeEvent;
- session_state = event->state;
- if (session_state >= XR_SESSION_STATE_MAX_ENUM) {
- print_verbose(String("OpenXR EVENT: session state changed to UNKNOWN - ") + itos(session_state));
- } else {
- print_verbose(String("OpenXR EVENT: session state changed to ") + OpenXRUtil::get_session_state_name(session_state));
- switch (session_state) {
- case XR_SESSION_STATE_IDLE:
- on_state_idle();
- break;
- case XR_SESSION_STATE_READY:
- on_state_ready();
- break;
- case XR_SESSION_STATE_SYNCHRONIZED:
- on_state_synchronized();
- break;
- case XR_SESSION_STATE_VISIBLE:
- on_state_visible();
- break;
- case XR_SESSION_STATE_FOCUSED:
- on_state_focused();
- break;
- case XR_SESSION_STATE_STOPPING:
- on_state_stopping();
- break;
- case XR_SESSION_STATE_LOSS_PENDING:
- on_state_loss_pending();
- break;
- case XR_SESSION_STATE_EXITING:
- on_state_exiting();
- break;
- default:
- break;
- }
- }
- } break;
- case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING: {
- XrEventDataReferenceSpaceChangePending *event = (XrEventDataReferenceSpaceChangePending *)&runtimeEvent;
- print_verbose(String("OpenXR EVENT: reference space type ") + OpenXRUtil::get_reference_space_name(event->referenceSpaceType) + " change pending!");
- if (event->poseValid && xr_interface) {
- xr_interface->on_pose_recentered();
- }
- } break;
- case XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED: {
- print_verbose("OpenXR EVENT: interaction profile changed!");
- XrEventDataInteractionProfileChanged *event = (XrEventDataInteractionProfileChanged *)&runtimeEvent;
- List<RID> trackers;
- tracker_owner.get_owned_list(&trackers);
- for (int i = 0; i < trackers.size(); i++) {
- tracker_check_profile(trackers[i], event->session);
- }
- } break;
- default:
- if (!handled) {
- print_verbose(String("OpenXR Unhandled event type ") + OpenXRUtil::get_structure_type_name(runtimeEvent.type));
- }
- break;
- }
- runtimeEvent.type = XR_TYPE_EVENT_DATA_BUFFER;
- pollResult = xrPollEvent(instance, &runtimeEvent);
- }
- if (pollResult == XR_EVENT_UNAVAILABLE) {
-
- return true;
- } else {
- ERR_FAIL_V_MSG(false, "OpenXR: Failed to poll events!");
- }
- }
- bool OpenXRAPI::process() {
- ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
- if (!poll_events()) {
- return false;
- }
- if (!running) {
- return false;
- }
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_process();
- }
- return true;
- }
- bool OpenXRAPI::acquire_image(OpenXRSwapChainInfo &p_swapchain) {
- ERR_FAIL_COND_V(p_swapchain.image_acquired, true);
- XrResult result;
- if (!p_swapchain.skip_acquire_swapchain) {
- XrSwapchainImageAcquireInfo swapchain_image_acquire_info = {
- XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO,
- nullptr
- };
- result = xrAcquireSwapchainImage(p_swapchain.swapchain, &swapchain_image_acquire_info, &p_swapchain.image_index);
- if (!XR_UNQUALIFIED_SUCCESS(result)) {
-
- frame_state.shouldRender = false;
- if (XR_FAILED(result)) {
-
- print_line("OpenXR: failed to acquire swapchain image [", get_error_string(result), "]");
- return false;
- } else {
-
- return false;
- }
- }
- }
- XrSwapchainImageWaitInfo swapchain_image_wait_info = {
- XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO,
- nullptr,
- 17000000
- };
- result = xrWaitSwapchainImage(p_swapchain.swapchain, &swapchain_image_wait_info);
- if (!XR_UNQUALIFIED_SUCCESS(result)) {
-
- frame_state.shouldRender = false;
- if (XR_FAILED(result)) {
-
- print_line("OpenXR: failed to wait for swapchain image [", get_error_string(result), "]");
- return false;
- } else {
-
- p_swapchain.skip_acquire_swapchain = true;
- return false;
- }
- } else {
- p_swapchain.skip_acquire_swapchain = false;
- }
- return true;
- }
- bool OpenXRAPI::release_image(OpenXRSwapChainInfo &p_swapchain) {
- XrSwapchainImageReleaseInfo swapchain_image_release_info = {
- XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO,
- nullptr
- };
- XrResult result = xrReleaseSwapchainImage(p_swapchain.swapchain, &swapchain_image_release_info);
- if (XR_FAILED(result)) {
- print_line("OpenXR: failed to release swapchain image! [", get_error_string(result), "]");
- return false;
- }
- return true;
- }
- void OpenXRAPI::pre_render() {
- ERR_FAIL_COND(instance == XR_NULL_HANDLE);
- if (!running) {
- return;
- }
-
-
-
-
- XrFrameWaitInfo frame_wait_info = { XR_TYPE_FRAME_WAIT_INFO, nullptr };
- frame_state.predictedDisplayTime = 0;
- frame_state.predictedDisplayPeriod = 0;
- frame_state.shouldRender = false;
- XrResult result = xrWaitFrame(session, &frame_wait_info, &frame_state);
- if (XR_FAILED(result)) {
- print_line("OpenXR: xrWaitFrame() was not successful [", get_error_string(result), "]");
-
- frame_state.predictedDisplayTime = 0;
- frame_state.predictedDisplayPeriod = 0;
- frame_state.shouldRender = false;
- return;
- }
- if (frame_state.predictedDisplayPeriod > 500000000) {
-
- print_verbose(String("OpenXR resetting invalid display period ") + rtos(frame_state.predictedDisplayPeriod));
- frame_state.predictedDisplayPeriod = 0;
- }
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_pre_render();
- }
-
-
-
-
-
-
-
-
- XrViewLocateInfo view_locate_info = {
- XR_TYPE_VIEW_LOCATE_INFO,
- nullptr,
- view_configuration,
- frame_state.predictedDisplayTime,
- play_space
- };
- XrViewState view_state = {
- XR_TYPE_VIEW_STATE,
- nullptr,
- 0
- };
- uint32_t view_count_output;
- result = xrLocateViews(session, &view_locate_info, &view_state, view_count, &view_count_output, views);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Couldn't locate views [", get_error_string(result), "]");
- return;
- }
- bool pose_valid = true;
- for (uint64_t i = 0; i < view_count_output; i++) {
- if ((view_state.viewStateFlags & XR_VIEW_STATE_ORIENTATION_VALID_BIT) == 0 ||
- (view_state.viewStateFlags & XR_VIEW_STATE_POSITION_VALID_BIT) == 0) {
- pose_valid = false;
- }
- }
- if (view_pose_valid != pose_valid) {
- view_pose_valid = pose_valid;
- if (!view_pose_valid) {
- print_verbose("OpenXR View pose became invalid");
- } else {
- print_verbose("OpenXR View pose became valid");
- }
- }
-
- XrFrameBeginInfo frame_begin_info = {
- XR_TYPE_FRAME_BEGIN_INFO,
- nullptr
- };
- result = xrBeginFrame(session, &frame_begin_info);
- if (XR_FAILED(result)) {
- print_line("OpenXR: failed to being frame [", get_error_string(result), "]");
- return;
- }
- }
- bool OpenXRAPI::pre_draw_viewport(RID p_render_target) {
- if (!can_render()) {
- return false;
- }
-
-
- for (int i = 0; i < OPENXR_SWAPCHAIN_MAX; i++) {
- if (!swapchains[i].image_acquired && swapchains[i].swapchain != XR_NULL_HANDLE) {
- if (!acquire_image(swapchains[i])) {
- return false;
- }
- swapchains[i].image_acquired = true;
- }
- }
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_pre_draw_viewport(p_render_target);
- }
- return true;
- }
- XrSwapchain OpenXRAPI::get_color_swapchain() {
- return swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain;
- }
- RID OpenXRAPI::get_color_texture() {
- if (swapchains[OPENXR_SWAPCHAIN_COLOR].image_acquired) {
- return graphics_extension->get_texture(swapchains[OPENXR_SWAPCHAIN_COLOR].swapchain_graphics_data, swapchains[OPENXR_SWAPCHAIN_COLOR].image_index);
- } else {
- return RID();
- }
- }
- RID OpenXRAPI::get_depth_texture() {
-
- if (submit_depth_buffer && swapchains[OPENXR_SWAPCHAIN_DEPTH].image_acquired) {
- return graphics_extension->get_texture(swapchains[OPENXR_SWAPCHAIN_DEPTH].swapchain_graphics_data, swapchains[OPENXR_SWAPCHAIN_DEPTH].image_index);
- } else {
- return RID();
- }
- }
- void OpenXRAPI::post_draw_viewport(RID p_render_target) {
- if (!can_render()) {
- return;
- }
- for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
- wrapper->on_post_draw_viewport(p_render_target);
- }
- };
- void OpenXRAPI::end_frame() {
- XrResult result;
- ERR_FAIL_COND(instance == XR_NULL_HANDLE);
- if (!running) {
- return;
- }
- if (frame_state.shouldRender && view_pose_valid && !swapchains[OPENXR_SWAPCHAIN_COLOR].image_acquired) {
- print_line("OpenXR: No viewport was marked with use_xr, there is no rendered output!");
- }
-
-
-
-
- if (!frame_state.shouldRender || !view_pose_valid || !swapchains[OPENXR_SWAPCHAIN_COLOR].image_acquired) {
-
- XrFrameEndInfo frame_end_info = {
- XR_TYPE_FRAME_END_INFO,
- nullptr,
- frame_state.predictedDisplayTime,
- environment_blend_mode,
- 0,
- nullptr
- };
- result = xrEndFrame(session, &frame_end_info);
- if (XR_FAILED(result)) {
- print_line("OpenXR: failed to end frame! [", get_error_string(result), "]");
- return;
- }
-
- return;
- }
-
- for (int i = 0; i < OPENXR_SWAPCHAIN_MAX; i++) {
- if (swapchains[i].image_acquired) {
- swapchains[i].image_acquired = false;
- release_image(swapchains[i]);
- }
- }
- for (uint32_t eye = 0; eye < view_count; eye++) {
- projection_views[eye].fov = views[eye].fov;
- projection_views[eye].pose = views[eye].pose;
- }
- Vector<const XrCompositionLayerBaseHeader *> layers_list;
-
- for (OpenXRCompositionLayerProvider *provider : composition_layer_providers) {
- XrCompositionLayerBaseHeader *layer = provider->get_composition_layer();
- if (layer) {
- layers_list.push_back(layer);
- }
- }
- XrCompositionLayerFlags layer_flags = XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT;
- if (layers_list.size() > 0 || environment_blend_mode != XR_ENVIRONMENT_BLEND_MODE_OPAQUE) {
- layer_flags |= XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
- }
- XrCompositionLayerProjection projection_layer = {
- XR_TYPE_COMPOSITION_LAYER_PROJECTION,
- nullptr,
- layer_flags,
- play_space,
- view_count,
- projection_views,
- };
- layers_list.push_back((const XrCompositionLayerBaseHeader *)&projection_layer);
- XrFrameEndInfo frame_end_info = {
- XR_TYPE_FRAME_END_INFO,
- nullptr,
- frame_state.predictedDisplayTime,
- environment_blend_mode,
- static_cast<uint32_t>(layers_list.size()),
- layers_list.ptr()
- };
- result = xrEndFrame(session, &frame_end_info);
- if (XR_FAILED(result)) {
- print_line("OpenXR: failed to end frame! [", get_error_string(result), "]");
- return;
- }
- }
- float OpenXRAPI::get_display_refresh_rate() const {
- OpenXRDisplayRefreshRateExtension *drrext = OpenXRDisplayRefreshRateExtension::get_singleton();
- if (drrext) {
- return drrext->get_refresh_rate();
- }
- return 0.0;
- }
- void OpenXRAPI::set_display_refresh_rate(float p_refresh_rate) {
- OpenXRDisplayRefreshRateExtension *drrext = OpenXRDisplayRefreshRateExtension::get_singleton();
- if (drrext != nullptr) {
- drrext->set_refresh_rate(p_refresh_rate);
- }
- }
- Array OpenXRAPI::get_available_display_refresh_rates() const {
- OpenXRDisplayRefreshRateExtension *drrext = OpenXRDisplayRefreshRateExtension::get_singleton();
- if (drrext != nullptr) {
- return drrext->get_available_refresh_rates();
- }
- return Array();
- }
- double OpenXRAPI::get_render_target_size_multiplier() const {
- return render_target_size_multiplier;
- }
- void OpenXRAPI::set_render_target_size_multiplier(double multiplier) {
- render_target_size_multiplier = multiplier;
- }
- bool OpenXRAPI::is_foveation_supported() const {
- OpenXRFBFoveationExtension *fov_ext = OpenXRFBFoveationExtension::get_singleton();
- return fov_ext != nullptr && fov_ext->is_enabled();
- }
- int OpenXRAPI::get_foveation_level() const {
- OpenXRFBFoveationExtension *fov_ext = OpenXRFBFoveationExtension::get_singleton();
- if (fov_ext != nullptr && fov_ext->is_enabled()) {
- switch (fov_ext->get_foveation_level()) {
- case XR_FOVEATION_LEVEL_NONE_FB:
- return 0;
- case XR_FOVEATION_LEVEL_LOW_FB:
- return 1;
- case XR_FOVEATION_LEVEL_MEDIUM_FB:
- return 2;
- case XR_FOVEATION_LEVEL_HIGH_FB:
- return 3;
- default:
- return 0;
- }
- }
- return 0;
- }
- void OpenXRAPI::set_foveation_level(int p_foveation_level) {
- ERR_FAIL_UNSIGNED_INDEX(p_foveation_level, 4);
- OpenXRFBFoveationExtension *fov_ext = OpenXRFBFoveationExtension::get_singleton();
- if (fov_ext != nullptr && fov_ext->is_enabled()) {
- XrFoveationLevelFB levels[] = { XR_FOVEATION_LEVEL_NONE_FB, XR_FOVEATION_LEVEL_LOW_FB, XR_FOVEATION_LEVEL_MEDIUM_FB, XR_FOVEATION_LEVEL_HIGH_FB };
- fov_ext->set_foveation_level(levels[p_foveation_level]);
- }
- }
- bool OpenXRAPI::get_foveation_dynamic() const {
- OpenXRFBFoveationExtension *fov_ext = OpenXRFBFoveationExtension::get_singleton();
- if (fov_ext != nullptr && fov_ext->is_enabled()) {
- return fov_ext->get_foveation_dynamic() == XR_FOVEATION_DYNAMIC_LEVEL_ENABLED_FB;
- }
- return false;
- }
- void OpenXRAPI::set_foveation_dynamic(bool p_foveation_dynamic) {
- OpenXRFBFoveationExtension *fov_ext = OpenXRFBFoveationExtension::get_singleton();
- if (fov_ext != nullptr && fov_ext->is_enabled()) {
- fov_ext->set_foveation_dynamic(p_foveation_dynamic ? XR_FOVEATION_DYNAMIC_LEVEL_ENABLED_FB : XR_FOVEATION_DYNAMIC_DISABLED_FB);
- }
- }
- OpenXRAPI::OpenXRAPI() {
-
- singleton = this;
- if (Engine::get_singleton()->is_editor_hint()) {
-
- } else {
-
- int form_factor_setting = GLOBAL_GET("xr/openxr/form_factor");
- switch (form_factor_setting) {
- case 0: {
- form_factor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
- } break;
- case 1: {
- form_factor = XR_FORM_FACTOR_HANDHELD_DISPLAY;
- } break;
- default:
- break;
- }
- int view_configuration_setting = GLOBAL_GET("xr/openxr/view_configuration");
- switch (view_configuration_setting) {
- case 0: {
- view_configuration = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO;
- } break;
- case 1: {
- view_configuration = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
- } break;
-
- default:
- break;
- }
- int reference_space_setting = GLOBAL_GET("xr/openxr/reference_space");
- switch (reference_space_setting) {
- case 0: {
- reference_space = XR_REFERENCE_SPACE_TYPE_LOCAL;
- } break;
- case 1: {
- reference_space = XR_REFERENCE_SPACE_TYPE_STAGE;
- } break;
- default:
- break;
- }
- int environment_blend_mode_setting = GLOBAL_GET("xr/openxr/environment_blend_mode");
- switch (environment_blend_mode_setting) {
- case 0: {
- environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
- } break;
- case 1: {
- environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_ADDITIVE;
- } break;
- case 2: {
- environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND;
- } break;
- default:
- break;
- }
- submit_depth_buffer = GLOBAL_GET("xr/openxr/submit_depth_buffer");
- }
-
- frame_state.predictedDisplayTime = 0;
- frame_state.predictedDisplayPeriod = 0;
- }
- OpenXRAPI::~OpenXRAPI() {
-
- for (OpenXRCompositionLayerProvider *provider : composition_layer_providers) {
- memdelete(provider);
- }
- composition_layer_providers.clear();
- if (supported_extensions != nullptr) {
- memfree(supported_extensions);
- supported_extensions = nullptr;
- }
- if (layer_properties != nullptr) {
- memfree(layer_properties);
- layer_properties = nullptr;
- }
- #ifdef ANDROID_ENABLED
- if (openxr_loader_library_handle) {
- OS::get_singleton()->close_dynamic_library(openxr_loader_library_handle);
- openxr_loader_library_handle = nullptr;
- }
- #endif
- singleton = nullptr;
- }
- Transform3D OpenXRAPI::transform_from_pose(const XrPosef &p_pose) {
- Quaternion q(p_pose.orientation.x, p_pose.orientation.y, p_pose.orientation.z, p_pose.orientation.w);
- Basis basis(q);
- Vector3 origin(p_pose.position.x, p_pose.position.y, p_pose.position.z);
- return Transform3D(basis, origin);
- }
- template <typename T>
- XRPose::TrackingConfidence _transform_from_location(const T &p_location, Transform3D &r_transform) {
- Basis basis;
- Vector3 origin;
- XRPose::TrackingConfidence confidence = XRPose::XR_TRACKING_CONFIDENCE_NONE;
- const XrPosef &pose = p_location.pose;
-
- if (p_location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT) {
- Quaternion q(pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w);
- r_transform.basis = Basis(q);
- if (p_location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_TRACKED_BIT) {
-
- confidence = XRPose::XR_TRACKING_CONFIDENCE_HIGH;
- } else {
-
- confidence = XRPose::XR_TRACKING_CONFIDENCE_LOW;
- }
- } else {
- r_transform.basis = Basis();
- }
-
- if (p_location.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) {
- r_transform.origin = Vector3(pose.position.x, pose.position.y, pose.position.z);
- if (!(p_location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_TRACKED_BIT)) {
-
- confidence = XRPose::XR_TRACKING_CONFIDENCE_LOW;
- } else if (confidence == XRPose::XR_TRACKING_CONFIDENCE_NONE) {
-
- confidence = XRPose::XR_TRACKING_CONFIDENCE_HIGH;
- }
- } else {
-
- r_transform.origin = Vector3();
- }
- return confidence;
- }
- XRPose::TrackingConfidence OpenXRAPI::transform_from_location(const XrSpaceLocation &p_location, Transform3D &r_transform) {
- return _transform_from_location(p_location, r_transform);
- }
- XRPose::TrackingConfidence OpenXRAPI::transform_from_location(const XrHandJointLocationEXT &p_location, Transform3D &r_transform) {
- return _transform_from_location(p_location, r_transform);
- }
- void OpenXRAPI::parse_velocities(const XrSpaceVelocity &p_velocity, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity) {
- if (p_velocity.velocityFlags & XR_SPACE_VELOCITY_LINEAR_VALID_BIT) {
- XrVector3f linear_velocity = p_velocity.linearVelocity;
- r_linear_velocity = Vector3(linear_velocity.x, linear_velocity.y, linear_velocity.z);
- } else {
- r_linear_velocity = Vector3();
- }
- if (p_velocity.velocityFlags & XR_SPACE_VELOCITY_ANGULAR_VALID_BIT) {
- XrVector3f angular_velocity = p_velocity.angularVelocity;
- r_angular_velocity = Vector3(angular_velocity.x, angular_velocity.y, angular_velocity.z);
- } else {
- r_angular_velocity = Vector3();
- }
- }
- bool OpenXRAPI::xr_result(XrResult result, const char *format, Array args) const {
- if (XR_SUCCEEDED(result))
- return true;
- char resultString[XR_MAX_RESULT_STRING_SIZE];
- xrResultToString(instance, result, resultString);
- print_error(String("OpenXR ") + String(format).format(args) + String(" [") + String(resultString) + String("]"));
- return false;
- }
- RID OpenXRAPI::get_tracker_rid(XrPath p_path) {
- List<RID> current;
- tracker_owner.get_owned_list(¤t);
- for (int i = 0; i < current.size(); i++) {
- Tracker *tracker = tracker_owner.get_or_null(current[i]);
- if (tracker && tracker->toplevel_path == p_path) {
- return current[i];
- }
- }
- return RID();
- }
- RID OpenXRAPI::tracker_create(const String p_name) {
- ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, RID());
- Tracker new_tracker;
- new_tracker.name = p_name;
- new_tracker.toplevel_path = XR_NULL_PATH;
- new_tracker.active_profile_rid = RID();
- XrResult result = xrStringToPath(instance, p_name.utf8().get_data(), &new_tracker.toplevel_path);
- if (XR_FAILED(result)) {
- print_line("OpenXR: failed to get path for ", p_name, "! [", get_error_string(result), "]");
- return RID();
- }
- return tracker_owner.make_rid(new_tracker);
- }
- String OpenXRAPI::tracker_get_name(RID p_tracker) {
- if (p_tracker.is_null()) {
- return String("None");
- }
- Tracker *tracker = tracker_owner.get_or_null(p_tracker);
- ERR_FAIL_NULL_V(tracker, String());
- return tracker->name;
- }
- void OpenXRAPI::tracker_check_profile(RID p_tracker, XrSession p_session) {
- if (p_session == XR_NULL_HANDLE) {
- p_session = session;
- }
- Tracker *tracker = tracker_owner.get_or_null(p_tracker);
- ERR_FAIL_NULL(tracker);
- if (tracker->toplevel_path == XR_NULL_PATH) {
-
- return;
- }
- XrInteractionProfileState profile_state = {
- XR_TYPE_INTERACTION_PROFILE_STATE,
- nullptr,
- XR_NULL_PATH
- };
- XrResult result = xrGetCurrentInteractionProfile(p_session, tracker->toplevel_path, &profile_state);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to get interaction profile for", itos(tracker->toplevel_path), "[", get_error_string(result), "]");
- return;
- }
- XrPath new_profile = profile_state.interactionProfile;
- XrPath was_profile = get_interaction_profile_path(tracker->active_profile_rid);
- if (was_profile != new_profile) {
- tracker->active_profile_rid = get_interaction_profile_rid(new_profile);
- if (xr_interface) {
- xr_interface->tracker_profile_changed(p_tracker, tracker->active_profile_rid);
- }
- }
- }
- void OpenXRAPI::tracker_free(RID p_tracker) {
- Tracker *tracker = tracker_owner.get_or_null(p_tracker);
- ERR_FAIL_NULL(tracker);
-
- tracker_owner.free(p_tracker);
- }
- RID OpenXRAPI::action_set_create(const String p_name, const String p_localized_name, const int p_priority) {
- ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, RID());
- ActionSet action_set;
- action_set.name = p_name;
- action_set.is_attached = false;
-
- XrActionSetCreateInfo action_set_info = {
- XR_TYPE_ACTION_SET_CREATE_INFO,
- nullptr,
- "",
- "",
- uint32_t(p_priority)
- };
- copy_string_to_char_buffer(p_name, action_set_info.actionSetName, XR_MAX_ACTION_SET_NAME_SIZE);
- copy_string_to_char_buffer(p_localized_name, action_set_info.localizedActionSetName, XR_MAX_LOCALIZED_ACTION_SET_NAME_SIZE);
- XrResult result = xrCreateActionSet(instance, &action_set_info, &action_set.handle);
- if (XR_FAILED(result)) {
- print_line("OpenXR: failed to create action set ", p_name, "! [", get_error_string(result), "]");
- return RID();
- }
- return action_set_owner.make_rid(action_set);
- }
- String OpenXRAPI::action_set_get_name(RID p_action_set) {
- if (p_action_set.is_null()) {
- return String("None");
- }
- ActionSet *action_set = action_set_owner.get_or_null(p_action_set);
- ERR_FAIL_NULL_V(action_set, String());
- return action_set->name;
- }
- bool OpenXRAPI::attach_action_sets(const Vector<RID> &p_action_sets) {
- ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
- Vector<XrActionSet> action_handles;
- action_handles.resize(p_action_sets.size());
- for (int i = 0; i < p_action_sets.size(); i++) {
- ActionSet *action_set = action_set_owner.get_or_null(p_action_sets[i]);
- ERR_FAIL_NULL_V(action_set, false);
- if (action_set->is_attached) {
- return false;
- }
- action_handles.set(i, action_set->handle);
- }
-
-
- XrSessionActionSetsAttachInfo attach_info = {
- XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO,
- nullptr,
- (uint32_t)p_action_sets.size(),
- action_handles.ptr()
- };
- XrResult result = xrAttachSessionActionSets(session, &attach_info);
- if (XR_FAILED(result)) {
- print_line("OpenXR: failed to attach action sets! [", get_error_string(result), "]");
- return false;
- }
- for (int i = 0; i < p_action_sets.size(); i++) {
- ActionSet *action_set = action_set_owner.get_or_null(p_action_sets[i]);
- ERR_FAIL_NULL_V(action_set, false);
- action_set->is_attached = true;
- }
-
- return true;
- }
- void OpenXRAPI::action_set_free(RID p_action_set) {
- ActionSet *action_set = action_set_owner.get_or_null(p_action_set);
- ERR_FAIL_NULL(action_set);
- if (action_set->handle != XR_NULL_HANDLE) {
- xrDestroyActionSet(action_set->handle);
- }
- action_set_owner.free(p_action_set);
- }
- RID OpenXRAPI::get_action_rid(XrAction p_action) {
- List<RID> current;
- action_owner.get_owned_list(¤t);
- for (int i = 0; i < current.size(); i++) {
- Action *action = action_owner.get_or_null(current[i]);
- if (action && action->handle == p_action) {
- return current[i];
- }
- }
- return RID();
- }
- RID OpenXRAPI::action_create(RID p_action_set, const String p_name, const String p_localized_name, OpenXRAction::ActionType p_action_type, const Vector<RID> &p_trackers) {
- ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, RID());
- Action action;
- action.name = p_name;
- ActionSet *action_set = action_set_owner.get_or_null(p_action_set);
- ERR_FAIL_NULL_V(action_set, RID());
- ERR_FAIL_COND_V(action_set->handle == XR_NULL_HANDLE, RID());
- action.action_set_rid = p_action_set;
- switch (p_action_type) {
- case OpenXRAction::OPENXR_ACTION_BOOL:
- action.action_type = XR_ACTION_TYPE_BOOLEAN_INPUT;
- break;
- case OpenXRAction::OPENXR_ACTION_FLOAT:
- action.action_type = XR_ACTION_TYPE_FLOAT_INPUT;
- break;
- case OpenXRAction::OPENXR_ACTION_VECTOR2:
- action.action_type = XR_ACTION_TYPE_VECTOR2F_INPUT;
- break;
- case OpenXRAction::OPENXR_ACTION_POSE:
- action.action_type = XR_ACTION_TYPE_POSE_INPUT;
- break;
- case OpenXRAction::OPENXR_ACTION_HAPTIC:
- action.action_type = XR_ACTION_TYPE_VIBRATION_OUTPUT;
- break;
- default:
- ERR_FAIL_V(RID());
- break;
- }
- Vector<XrPath> toplevel_paths;
- for (int i = 0; i < p_trackers.size(); i++) {
- Tracker *tracker = tracker_owner.get_or_null(p_trackers[i]);
- if (tracker != nullptr && tracker->toplevel_path != XR_NULL_PATH) {
- ActionTracker action_tracker = {
- p_trackers[i],
- XR_NULL_HANDLE,
- false
- };
- action.trackers.push_back(action_tracker);
- toplevel_paths.push_back(tracker->toplevel_path);
- }
- }
- XrActionCreateInfo action_info = {
- XR_TYPE_ACTION_CREATE_INFO,
- nullptr,
- "",
- action.action_type,
- uint32_t(toplevel_paths.size()),
- toplevel_paths.ptr(),
- ""
- };
- copy_string_to_char_buffer(p_name, action_info.actionName, XR_MAX_ACTION_NAME_SIZE);
- copy_string_to_char_buffer(p_localized_name, action_info.localizedActionName, XR_MAX_LOCALIZED_ACTION_NAME_SIZE);
- XrResult result = xrCreateAction(action_set->handle, &action_info, &action.handle);
- if (XR_FAILED(result)) {
- print_line("OpenXR: failed to create action ", p_name, "! [", get_error_string(result), "]");
- return RID();
- }
- return action_owner.make_rid(action);
- }
- String OpenXRAPI::action_get_name(RID p_action) {
- if (p_action.is_null()) {
- return String("None");
- }
- Action *action = action_owner.get_or_null(p_action);
- ERR_FAIL_NULL_V(action, String());
- return action->name;
- }
- void OpenXRAPI::action_free(RID p_action) {
- Action *action = action_owner.get_or_null(p_action);
- ERR_FAIL_NULL(action);
- if (action->handle != XR_NULL_HANDLE) {
- xrDestroyAction(action->handle);
- }
- action_owner.free(p_action);
- }
- RID OpenXRAPI::get_interaction_profile_rid(XrPath p_path) {
- List<RID> current;
- interaction_profile_owner.get_owned_list(¤t);
- for (int i = 0; i < current.size(); i++) {
- InteractionProfile *ip = interaction_profile_owner.get_or_null(current[i]);
- if (ip && ip->path == p_path) {
- return current[i];
- }
- }
- return RID();
- }
- XrPath OpenXRAPI::get_interaction_profile_path(RID p_interaction_profile) {
- if (p_interaction_profile.is_null()) {
- return XR_NULL_PATH;
- }
- InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile);
- ERR_FAIL_NULL_V(ip, XR_NULL_PATH);
- return ip->path;
- }
- RID OpenXRAPI::interaction_profile_create(const String p_name) {
- if (!is_interaction_profile_supported(p_name)) {
-
- return RID();
- }
- InteractionProfile new_interaction_profile;
- XrResult result = xrStringToPath(instance, p_name.utf8().get_data(), &new_interaction_profile.path);
- if (XR_FAILED(result)) {
- print_line("OpenXR: failed to get path for ", p_name, "! [", get_error_string(result), "]");
- return RID();
- }
- RID existing_ip = get_interaction_profile_rid(new_interaction_profile.path);
- if (existing_ip.is_valid()) {
- return existing_ip;
- }
- new_interaction_profile.name = p_name;
- return interaction_profile_owner.make_rid(new_interaction_profile);
- }
- String OpenXRAPI::interaction_profile_get_name(RID p_interaction_profile) {
- if (p_interaction_profile.is_null()) {
- return String("None");
- }
- InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile);
- ERR_FAIL_NULL_V(ip, String());
- return ip->name;
- }
- void OpenXRAPI::interaction_profile_clear_bindings(RID p_interaction_profile) {
- InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile);
- ERR_FAIL_NULL(ip);
- ip->bindings.clear();
- }
- bool OpenXRAPI::interaction_profile_add_binding(RID p_interaction_profile, RID p_action, const String p_path) {
- InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile);
- ERR_FAIL_NULL_V(ip, false);
- if (!interaction_profile_supports_io_path(ip->name, p_path)) {
- return false;
- }
- XrActionSuggestedBinding binding;
- Action *action = action_owner.get_or_null(p_action);
- ERR_FAIL_COND_V(action == nullptr || action->handle == XR_NULL_HANDLE, false);
- binding.action = action->handle;
- XrResult result = xrStringToPath(instance, p_path.utf8().get_data(), &binding.binding);
- if (XR_FAILED(result)) {
- print_line("OpenXR: failed to get path for ", p_path, "! [", get_error_string(result), "]");
- return false;
- }
- ip->bindings.push_back(binding);
- return true;
- }
- bool OpenXRAPI::interaction_profile_suggest_bindings(RID p_interaction_profile) {
- ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
- InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile);
- ERR_FAIL_NULL_V(ip, false);
- const XrInteractionProfileSuggestedBinding suggested_bindings = {
- XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING,
- nullptr,
- ip->path,
- uint32_t(ip->bindings.size()),
- ip->bindings.ptr()
- };
- XrResult result = xrSuggestInteractionProfileBindings(instance, &suggested_bindings);
- if (result == XR_ERROR_PATH_UNSUPPORTED) {
-
- print_verbose("OpenXR Interaction profile " + ip->name + " is not supported on this runtime");
- } else if (XR_FAILED(result)) {
- print_line("OpenXR: failed to suggest bindings for ", ip->name, "! [", get_error_string(result), "]");
-
- }
-
- return true;
- }
- void OpenXRAPI::interaction_profile_free(RID p_interaction_profile) {
- InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile);
- ERR_FAIL_NULL(ip);
- ip->bindings.clear();
- interaction_profile_owner.free(p_interaction_profile);
- }
- bool OpenXRAPI::sync_action_sets(const Vector<RID> p_active_sets) {
- ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
- if (!running) {
- return false;
- }
- Vector<XrActiveActionSet> active_sets;
- for (int i = 0; i < p_active_sets.size(); i++) {
- ActionSet *action_set = action_set_owner.get_or_null(p_active_sets[i]);
- if (action_set && action_set->handle != XR_NULL_HANDLE) {
- XrActiveActionSet aset;
- aset.actionSet = action_set->handle;
- aset.subactionPath = XR_NULL_PATH;
- active_sets.push_back(aset);
- }
- }
- ERR_FAIL_COND_V(active_sets.size() == 0, false);
- XrActionsSyncInfo sync_info = {
- XR_TYPE_ACTIONS_SYNC_INFO,
- nullptr,
- uint32_t(active_sets.size()),
- active_sets.ptr()
- };
- XrResult result = xrSyncActions(session, &sync_info);
- if (XR_FAILED(result)) {
- print_line("OpenXR: failed to sync active action sets! [", get_error_string(result), "]");
- return false;
- }
- return true;
- }
- bool OpenXRAPI::get_action_bool(RID p_action, RID p_tracker) {
- ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
- Action *action = action_owner.get_or_null(p_action);
- ERR_FAIL_NULL_V(action, false);
- Tracker *tracker = tracker_owner.get_or_null(p_tracker);
- ERR_FAIL_NULL_V(tracker, false);
- if (!running) {
- return false;
- }
- ERR_FAIL_COND_V(action->action_type != XR_ACTION_TYPE_BOOLEAN_INPUT, false);
- XrActionStateGetInfo get_info = {
- XR_TYPE_ACTION_STATE_GET_INFO,
- nullptr,
- action->handle,
- tracker->toplevel_path
- };
- XrActionStateBoolean result_state;
- result_state.type = XR_TYPE_ACTION_STATE_BOOLEAN,
- result_state.next = nullptr;
- XrResult result = xrGetActionStateBoolean(session, &get_info, &result_state);
- if (XR_FAILED(result)) {
- print_line("OpenXR: couldn't get action boolean! [", get_error_string(result), "]");
- return false;
- }
- return result_state.isActive && result_state.currentState;
- }
- float OpenXRAPI::get_action_float(RID p_action, RID p_tracker) {
- ERR_FAIL_COND_V(session == XR_NULL_HANDLE, 0.0);
- Action *action = action_owner.get_or_null(p_action);
- ERR_FAIL_NULL_V(action, 0.0);
- Tracker *tracker = tracker_owner.get_or_null(p_tracker);
- ERR_FAIL_NULL_V(tracker, 0.0);
- if (!running) {
- return 0.0;
- }
- ERR_FAIL_COND_V(action->action_type != XR_ACTION_TYPE_FLOAT_INPUT, 0.0);
- XrActionStateGetInfo get_info = {
- XR_TYPE_ACTION_STATE_GET_INFO,
- nullptr,
- action->handle,
- tracker->toplevel_path
- };
- XrActionStateFloat result_state;
- result_state.type = XR_TYPE_ACTION_STATE_FLOAT,
- result_state.next = nullptr;
- XrResult result = xrGetActionStateFloat(session, &get_info, &result_state);
- if (XR_FAILED(result)) {
- print_line("OpenXR: couldn't get action float! [", get_error_string(result), "]");
- return 0.0;
- }
- return result_state.isActive ? result_state.currentState : 0.0;
- }
- Vector2 OpenXRAPI::get_action_vector2(RID p_action, RID p_tracker) {
- ERR_FAIL_COND_V(session == XR_NULL_HANDLE, Vector2());
- Action *action = action_owner.get_or_null(p_action);
- ERR_FAIL_NULL_V(action, Vector2());
- Tracker *tracker = tracker_owner.get_or_null(p_tracker);
- ERR_FAIL_NULL_V(tracker, Vector2());
- if (!running) {
- return Vector2();
- }
- ERR_FAIL_COND_V(action->action_type != XR_ACTION_TYPE_VECTOR2F_INPUT, Vector2());
- XrActionStateGetInfo get_info = {
- XR_TYPE_ACTION_STATE_GET_INFO,
- nullptr,
- action->handle,
- tracker->toplevel_path
- };
- XrActionStateVector2f result_state;
- result_state.type = XR_TYPE_ACTION_STATE_VECTOR2F,
- result_state.next = nullptr;
- XrResult result = xrGetActionStateVector2f(session, &get_info, &result_state);
- if (XR_FAILED(result)) {
- print_line("OpenXR: couldn't get action vector2! [", get_error_string(result), "]");
- return Vector2();
- }
- return result_state.isActive ? Vector2(result_state.currentState.x, result_state.currentState.y) : Vector2();
- }
- XRPose::TrackingConfidence OpenXRAPI::get_action_pose(RID p_action, RID p_tracker, Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity) {
- ERR_FAIL_COND_V(session == XR_NULL_HANDLE, XRPose::XR_TRACKING_CONFIDENCE_NONE);
- Action *action = action_owner.get_or_null(p_action);
- ERR_FAIL_NULL_V(action, XRPose::XR_TRACKING_CONFIDENCE_NONE);
- Tracker *tracker = tracker_owner.get_or_null(p_tracker);
- ERR_FAIL_NULL_V(tracker, XRPose::XR_TRACKING_CONFIDENCE_NONE);
- if (!running) {
- return XRPose::XR_TRACKING_CONFIDENCE_NONE;
- }
- ERR_FAIL_COND_V(action->action_type != XR_ACTION_TYPE_POSE_INPUT, XRPose::XR_TRACKING_CONFIDENCE_NONE);
-
- uint64_t index = 0xFFFFFFFF;
- uint64_t size = uint64_t(action->trackers.size());
- for (uint64_t i = 0; i < size && index == 0xFFFFFFFF; i++) {
- if (action->trackers[i].tracker_rid == p_tracker) {
- index = i;
- }
- }
- if (index == 0xFFFFFFFF) {
-
- return XRPose::XR_TRACKING_CONFIDENCE_NONE;
- }
- XrTime display_time = get_next_frame_time();
- if (display_time == 0) {
- return XRPose::XR_TRACKING_CONFIDENCE_NONE;
- }
- if (action->trackers[index].space == XR_NULL_HANDLE) {
-
- XrActionSpaceCreateInfo action_space_info = {
- XR_TYPE_ACTION_SPACE_CREATE_INFO,
- nullptr,
- action->handle,
- tracker->toplevel_path,
- {
- { 0.0, 0.0, 0.0, 1.0 },
- { 0.0, 0.0, 0.0 }
- }
- };
- XrSpace space;
- XrResult result = xrCreateActionSpace(session, &action_space_info, &space);
- if (XR_FAILED(result)) {
- print_line("OpenXR: couldn't create action space! [", get_error_string(result), "]");
- return XRPose::XR_TRACKING_CONFIDENCE_NONE;
- }
- action->trackers.ptrw()[index].space = space;
- }
- XrSpaceVelocity velocity = {
- XR_TYPE_SPACE_VELOCITY,
- nullptr,
- 0,
- { 0.0, 0.0, 0.0 },
- { 0.0, 0.0, 0.0 }
- };
- XrSpaceLocation location = {
- XR_TYPE_SPACE_LOCATION,
- &velocity,
- 0,
- {
- { 0.0, 0.0, 0.0, 0.0 },
- { 0.0, 0.0, 0.0 }
- }
- };
- XrResult result = xrLocateSpace(action->trackers[index].space, play_space, display_time, &location);
- if (XR_FAILED(result)) {
- print_line("OpenXR: failed to locate space! [", get_error_string(result), "]");
- return XRPose::XR_TRACKING_CONFIDENCE_NONE;
- }
- XRPose::TrackingConfidence confidence = transform_from_location(location, r_transform);
- parse_velocities(velocity, r_linear_velocity, r_angular_velocity);
- return confidence;
- }
- bool OpenXRAPI::trigger_haptic_pulse(RID p_action, RID p_tracker, float p_frequency, float p_amplitude, XrDuration p_duration_ns) {
- ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
- Action *action = action_owner.get_or_null(p_action);
- ERR_FAIL_NULL_V(action, false);
- Tracker *tracker = tracker_owner.get_or_null(p_tracker);
- ERR_FAIL_NULL_V(tracker, false);
- if (!running) {
- return false;
- }
- ERR_FAIL_COND_V(action->action_type != XR_ACTION_TYPE_VIBRATION_OUTPUT, false);
- XrHapticActionInfo action_info = {
- XR_TYPE_HAPTIC_ACTION_INFO,
- nullptr,
- action->handle,
- tracker->toplevel_path
- };
- XrHapticVibration vibration = {
- XR_TYPE_HAPTIC_VIBRATION,
- nullptr,
- p_duration_ns,
- p_frequency,
- p_amplitude,
- };
- XrResult result = xrApplyHapticFeedback(session, &action_info, (const XrHapticBaseHeader *)&vibration);
- if (XR_FAILED(result)) {
- print_line("OpenXR: failed to apply haptic feedback! [", get_error_string(result), "]");
- return false;
- }
- return true;
- }
- void OpenXRAPI::register_composition_layer_provider(OpenXRCompositionLayerProvider *provider) {
- composition_layer_providers.append(provider);
- }
- void OpenXRAPI::unregister_composition_layer_provider(OpenXRCompositionLayerProvider *provider) {
- composition_layer_providers.erase(provider);
- }
- const XrEnvironmentBlendMode *OpenXRAPI::get_supported_environment_blend_modes(uint32_t &count) {
- count = num_supported_environment_blend_modes;
- return supported_environment_blend_modes;
- }
- bool OpenXRAPI::is_environment_blend_mode_supported(XrEnvironmentBlendMode p_blend_mode) const {
- ERR_FAIL_NULL_V(supported_environment_blend_modes, false);
- for (uint32_t i = 0; i < num_supported_environment_blend_modes; i++) {
- if (supported_environment_blend_modes[i] == p_blend_mode) {
- return true;
- }
- }
- return false;
- }
- bool OpenXRAPI::set_environment_blend_mode(XrEnvironmentBlendMode p_blend_mode) {
-
-
- if (!is_initialized() || is_environment_blend_mode_supported(p_blend_mode)) {
- environment_blend_mode = p_blend_mode;
- return true;
- }
- return false;
- }
|