Pico is back!

Tested on Pico Neo 3 with PUI v4.9.3
Also included generic (Monado-Android) Android flavor.
This commit is contained in:
Ilya Chelyadin 2022-11-22 20:22:27 +03:00
parent dbdd22ae95
commit 3f20364c3f
5 changed files with 128 additions and 5 deletions

View File

@ -59,6 +59,7 @@ if(EMSCRIPTEN)
set(LOVR_USE_WEBGPU ON)
set(LOVR_USE_VULKAN OFF)
elseif(ANDROID)
set(ANDROID_FLAVOR "oculus" CACHE STRING "Which Android flavor to build (oculus, pico or generis)")
find_package(Java REQUIRED)
set(LOVR_USE_DESKTOP OFF)
if(LOVR_BUILD_EXE)
@ -201,8 +202,18 @@ if(LOVR_ENABLE_HEADSET AND LOVR_USE_OPENXR)
if(ANDROID)
add_library(openxr_loader SHARED IMPORTED)
set(LOVR_OPENXR openxr_loader)
set(LOVR_OPENXR_OCULUS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/deps/oculus-openxr" CACHE STRING "The path to the Oculus OpenXR loader")
set_target_properties(openxr_loader PROPERTIES IMPORTED_LOCATION "${LOVR_OPENXR_OCULUS_PATH}/Libs/Android/${ANDROID_ABI}/Release/libopenxr_loader.so")
if(ANDROID_FLAVOR STREQUAL "oculus")
set(LOVR_OPENXR_OCULUS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/deps/oculus-openxr" CACHE STRING "The path to the Oculus OpenXR loader")
set_target_properties(openxr_loader PROPERTIES IMPORTED_LOCATION "${LOVR_OPENXR_OCULUS_PATH}/Libs/Android/${ANDROID_ABI}/Release/libopenxr_loader.so")
elseif(ANDROID_FLAVOR STREQUAL "pico")
set(LOVR_OPENXR_PICO_PATH "${CMAKE_CURRENT_SOURCE_DIR}/deps/pico-openxr" CACHE STRING "The path to the Pico OpenXR loader")
set_target_properties(openxr_loader PROPERTIES IMPORTED_LOCATION "${LOVR_OPENXR_PICO_PATH}/Libs/Android/${ANDROID_ABI}/libopenxr_loader.so")
elseif(ANDROID_FLAVOR STREQUAL "generic")
set(LOVR_OPENXR_GENERIC_PATH "${CMAKE_CURRENT_SOURCE_DIR}/deps/generic-openxr" CACHE STRING "The path to the Generic OpenXR loader")
set_target_properties(openxr_loader PROPERTIES IMPORTED_LOCATION "${LOVR_OPENXR_GENERIC_PATH}/Libs/Android/${ANDROID_ABI}/libopenxr_loader.so")
else()
message(FATAL_ERROR "Unsupported Android flavor (expected: oculus, pico or generis)")
endif()
else()
if(LOVR_SYSTEM_OPENXR)
pkg_search_module(OPENXR openxr)
@ -727,7 +738,7 @@ elseif(ANDROID)
if(LOVR_BUILD_EXE)
set(ANDROID_JAR "${ANDROID_SDK}/platforms/${ANDROID_PLATFORM}/android.jar")
set(ANDROID_TOOLS "${ANDROID_SDK}/build-tools/${ANDROID_BUILD_TOOLS_VERSION}")
set(ANDROID_MANIFEST "${CMAKE_CURRENT_SOURCE_DIR}/etc/AndroidManifest.xml" CACHE STRING "The AndroidManifest.xml file to use")
set(ANDROID_MANIFEST "${CMAKE_CURRENT_SOURCE_DIR}/etc/AndroidManifest_${ANDROID_FLAVOR}.xml" CACHE STRING "The AndroidManifest.xml file to use")
# If assets are included in the apk then add '-A assets' to aapt, otherwise don't add any flags
if(ANDROID_ASSETS)

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.lovr.app" android:installLocation="auto" android:versionCode="1">
<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="26"/>
<uses-feature
android:glEsVersion="0x00030002"
android:required="true" />
<uses-feature
android:name="android.hardware.vr.headtracking"
android:required="false"
android:version="1" />
<uses-permission android:name="org.khronos.openxr.permission.OPENXR" />
<uses-permission android:name="org.khronos.openxr.permission.OPENXR_SYSTEM" />
<queries>
<provider android:name="org.khronos.openxr.runtime_broker" android:authorities="org.khronos.openxr.runtime_broker;org.khronos.openxr.system_runtime_broker" />
</queries>
<application android:allowBackup="false" android:label="LÖVR" android:extractNativeLibs="false" android:debuggable="true">
<activity
android:name="Activity"
android:configChanges="screenSize|screenLayout|orientation|keyboardHidden|keyboard|navigation|uiMode|density"
android:excludeFromRecents="false"
android:launchMode="singleTask"
android:resizeableActivity="false"
android:screenOrientation="landscape"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
<meta-data android:name="android.app.lib_name" android:value="lovr" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="org.khronos.openxr.intent.category.IMMERSIVE_HMD" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.lovr.app">
<uses-sdk android:minSdkVersion="27" android:targetSdkVersion="27"/>
<uses-feature android:name="android.hardware.vr.headtracking" android:required="true"/>
<uses-feature android:glEsVersion="0x00030002" android:required="true"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<application android:allowBackup="false" android:label="LÖVR">
<meta-data android:name="pvr.app.type" android:value="vr"/>
<activity android:name="Activity" android:launchMode="singleTask" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
<meta-data android:name="android.app.lib_name" android:value="lovr"/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -329,6 +329,11 @@ static bool openxr_init(HeadsetConfig* config) {
#ifdef LOVR_VK
{ "XR_KHR_vulkan_enable2", NULL, true },
#endif
#ifdef __ANDROID__
{ "XR_KHR_android_create_instance", NULL, true },
{ "XR_PICO_android_controller_function_ext_enable", NULL, true},
#endif
{ "XR_KHR_composition_layer_depth", &state.features.depth, config->submitDepth },
{ "XR_EXT_eye_gaze_interaction", &state.features.gaze, true },
{ "XR_EXT_hand_tracking", &state.features.handTracking, true },
@ -352,6 +357,15 @@ static bool openxr_init(HeadsetConfig* config) {
free(extensionProperties);
#ifdef __ANDROID__
XrInstanceCreateInfoAndroidKHR infoAndroid = {
.type = XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR,
.applicationVM = os_get_java_vm(),
.applicationActivity = os_get_jni_context(),
.next = NULL
};
#endif
XrInstanceCreateInfo info = {
.type = XR_TYPE_INSTANCE_CREATE_INFO,
.applicationInfo.engineName = "LÖVR",
@ -360,7 +374,10 @@ static bool openxr_init(HeadsetConfig* config) {
.applicationInfo.applicationVersion = 0,
.applicationInfo.apiVersion = XR_CURRENT_API_VERSION,
.enabledExtensionCount = enabledExtensionCount,
.enabledExtensionNames = enabledExtensionNames
.enabledExtensionNames = enabledExtensionNames,
#ifdef __ANDROID__
.next = &infoAndroid
#endif
};
XR_INIT(xrCreateInstance(&info, &state.instance));
@ -545,6 +562,7 @@ static bool openxr_init(HeadsetConfig* config) {
PROFILE_WMR,
PROFILE_TRACKER,
PROFILE_GAZE,
PROFILE_PICO,
MAX_PROFILES
};
@ -556,7 +574,8 @@ static bool openxr_init(HeadsetConfig* config) {
[PROFILE_INDEX] = "/interaction_profiles/valve/index_controller",
[PROFILE_WMR] = "/interaction_profiles/microsoft/motion_controller",
[PROFILE_TRACKER] = "/interaction_profiles/htc/vive_tracker_htcx",
[PROFILE_GAZE] = "/interaction_profiles/ext/eye_gaze_interaction"
[PROFILE_GAZE] = "/interaction_profiles/ext/eye_gaze_interaction",
[PROFILE_PICO] = "/interaction_profiles/pico/neo3_controller",
};
typedef struct {
@ -755,6 +774,44 @@ static bool openxr_init(HeadsetConfig* config) {
[PROFILE_GAZE] = (Binding[]) {
{ ACTION_GAZE_POSE, "/user/eyes_ext/input/gaze_ext/pose" },
{ 0, NULL }
},
[PROFILE_PICO] = (Binding[]) {
{ ACTION_HAND_POSE, "/user/hand/left/input/grip/pose" },
{ ACTION_HAND_POSE, "/user/hand/right/input/grip/pose" },
{ ACTION_POINTER_POSE, "/user/hand/left/input/aim/pose" },
{ ACTION_POINTER_POSE, "/user/hand/right/input/aim/pose" },
{ ACTION_TRIGGER_DOWN, "/user/hand/left/input/trigger/value" },
{ ACTION_TRIGGER_DOWN, "/user/hand/right/input/trigger/value" },
{ ACTION_TRIGGER_TOUCH, "/user/hand/left/input/trigger/touch" },
{ ACTION_TRIGGER_TOUCH, "/user/hand/right/input/trigger/touch" },
{ ACTION_TRIGGER_AXIS, "/user/hand/left/input/trigger/value" },
{ ACTION_TRIGGER_AXIS, "/user/hand/right/input/trigger/value" },
{ ACTION_THUMBSTICK_DOWN, "/user/hand/left/input/thumbstick/click" },
{ ACTION_THUMBSTICK_DOWN, "/user/hand/right/input/thumbstick/click" },
{ ACTION_THUMBSTICK_TOUCH, "/user/hand/left/input/thumbstick/touch" },
{ ACTION_THUMBSTICK_TOUCH, "/user/hand/right/input/thumbstick/touch" },
{ ACTION_THUMBSTICK_X, "/user/hand/left/input/thumbstick/x" },
{ ACTION_THUMBSTICK_X, "/user/hand/right/input/thumbstick/x" },
{ ACTION_THUMBSTICK_Y, "/user/hand/left/input/thumbstick/y" },
{ ACTION_THUMBSTICK_Y, "/user/hand/right/input/thumbstick/y" },
//{ ACTION_MENU_DOWN, "/user/hand/left/input/menu/click" }, //Imposter
{ ACTION_MENU_DOWN, "/user/hand/right/input/system/click" },
{ ACTION_GRIP_DOWN, "/user/hand/left/input/squeeze/click" },
{ ACTION_GRIP_DOWN, "/user/hand/right/input/squeeze/click" },
{ ACTION_GRIP_AXIS, "/user/hand/left/input/squeeze/value" },
{ ACTION_GRIP_AXIS, "/user/hand/right/input/squeeze/value" },
{ ACTION_A_DOWN, "/user/hand/right/input/a/click" },
{ ACTION_A_TOUCH, "/user/hand/right/input/a/touch" },
{ ACTION_B_DOWN, "/user/hand/right/input/b/click" },
{ ACTION_B_TOUCH, "/user/hand/right/input/b/touch" },
{ ACTION_X_DOWN, "/user/hand/left/input/x/click" },
{ ACTION_X_TOUCH, "/user/hand/left/input/x/touch" },
{ ACTION_Y_DOWN, "/user/hand/left/input/y/click" },
{ ACTION_Y_TOUCH, "/user/hand/left/input/y/touch" },
{ ACTION_THUMBREST_TOUCH, "/user/hand/left/input/thumbrest/touch" },
{ ACTION_THUMBREST_TOUCH, "/user/hand/right/input/thumbrest/touch" },
{ ACTION_VIBRATE, "/user/hand/left/output/haptic" },
{ ACTION_VIBRATE, "/user/hand/right/output/haptic" },
}
};