Merge pull request #605 from brainrom/picofix

Pico android flavor
This commit is contained in:
Bjorn 2023-01-30 19:37:42 -08:00 committed by GitHub
commit bd03180d44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 117 additions and 25 deletions

View File

@ -210,24 +210,17 @@ endif()
# OpenXR
if(LOVR_ENABLE_HEADSET AND LOVR_USE_OPENXR)
include_directories(deps/openxr/include)
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")
else()
if(LOVR_SYSTEM_OPENXR)
pkg_search_module(OPENXR openxr)
if(NOT OPENXR_FOUND)
message(FATAL_ERROR "OpenXR not found.")
endif()
include_directories(${OPENXR_INCLUDE_DIRS})
set(LOVR_OPENXR ${OPENXR_LIBRARIES})
else()
set(DYNAMIC_LOADER ON CACHE BOOL "")
add_subdirectory(deps/openxr openxr)
set(LOVR_OPENXR openxr_loader)
if(LOVR_SYSTEM_OPENXR AND NOT ANDROID)
pkg_search_module(OPENXR openxr)
if(NOT OPENXR_FOUND)
message(FATAL_ERROR "OpenXR not found.")
endif()
include_directories(${OPENXR_INCLUDE_DIRS})
set(LOVR_OPENXR ${OPENXR_LIBRARIES})
else()
set(DYNAMIC_LOADER ON CACHE BOOL "")
add_subdirectory(deps/openxr openxr)
set(LOVR_OPENXR openxr_loader)
endif()
endif()
@ -766,8 +759,21 @@ elseif(ANDROID)
endif()
if(LOVR_USE_OPENXR)
get_target_property(OPENXR_LIB ${LOVR_OPENXR} IMPORTED_LOCATION)
file(COPY ${OPENXR_LIB} DESTINATION raw/lib/${ANDROID_ABI})
add_custom_command(TARGET move_files POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
$<TARGET_SONAME_FILE:${LOVR_OPENXR}>
raw/lib/${ANDROID_ABI}/libopenxr_loader_generic.so
)
set (PICO_LOADER "${CMAKE_CURRENT_SOURCE_DIR}/deps/pico-openxr/libs/android.${ANDROID_ABI}/libopenxr_loader.so")
if (EXISTS ${PICO_LOADER})
configure_file(${PICO_LOADER} "raw/lib/${ANDROID_ABI}/libopenxr_loader_pico.so" COPYONLY)
endif()
set (OCULUS_LOADER "${CMAKE_CURRENT_SOURCE_DIR}/deps/oculus-openxr/Libs/Android/${ANDROID_ABI}/Release/libopenxr_loader.so")
if (EXISTS ${OCULUS_LOADER})
configure_file(${OCULUS_LOADER} "raw/lib/${ANDROID_ABI}/libopenxr_loader_oculus.so" COPYONLY)
endif()
configure_file("${ANDROID_NDK}/toolchains/llvm/prebuilt/${ANDROID_HOST_TAG}/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so" "raw/lib/${ANDROID_ABI}/libc++_shared.so" COPYONLY)
endif()
if(LOVR_USE_OCULUS_AUDIO)

View File

@ -3,10 +3,24 @@ package org.lovr.app;
import android.Manifest;
import android.app.NativeActivity;
import android.content.pm.PackageManager;
import android.util.Log;
import android.os.Build;
public class Activity extends NativeActivity {
static {
System.loadLibrary("openxr_loader");
if (Build.MANUFACTURER.contains("Oculus")) {
Log.d("LOVR", "Using Oculus OpenXR Loader");
System.loadLibrary("openxr_loader_oculus");
}
else if (Build.MANUFACTURER.contains("Pico"))
{
Log.d("LOVR", "Using Pico OpenXR Loader");
System.loadLibrary("openxr_loader_pico");
}
else {
Log.d("LOVR", "Using Generic OpenXR Loader");
System.loadLibrary("openxr_loader_generic");
}
System.loadLibrary("lovr");
}

View File

@ -1,9 +1,9 @@
<?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="0x00030001" android:required="true"/>
<uses-feature android:name="android.hardware.vr.headtracking" android:required="false"/>
<uses-feature android:name="oculus.software.handtracking" android:required="false"/>
<!-- Oculus -->
<uses-feature android:name="oculus.software.trackedkeyboard" android:required="false"/>
<uses-feature android:name="com.oculus.feature.RENDER_MODEL" android:required="false"/>
<uses-feature android:name="com.oculus.feature.PASSTHROUGH" android:required="false"/>
@ -14,16 +14,26 @@
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- Khronos/Generic -->
<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">
<meta-data android:name="pvr.app.type" android:value="vr"/> <!-- Pico -->
<meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only"/>
<meta-data android:name="com.oculus.supportedDevices" android:value="quest|quest2"/>
<meta-data android:name="com.oculus.handtracking.version" android:value="V2.0"/>
<activity android:name="Activity" android:launchMode="singleTask" android:screenOrientation="landscape" android:excludeFromRecents="true">
<activity android:name="Activity" android:launchMode="singleTask" android:screenOrientation="landscape" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" android:excludeFromRecents="true">
<meta-data android:name="android.app.lib_name" android:value="lovr"/>
<meta-data android:name="com.oculus.vr.focusaware" android:value="true"/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="com.oculus.intent.category.VR"/>
<category android:name="org.khronos.openxr.intent.category.IMMERSIVE_HMD" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

View File

@ -330,6 +330,10 @@ 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 },
#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 },
@ -337,7 +341,9 @@ static bool openxr_init(HeadsetConfig* config) {
{ "XR_FB_hand_tracking_aim", &state.features.handTrackingAim, true },
{ "XR_FB_hand_tracking_mesh", &state.features.handTrackingMesh, true },
{ "XR_FB_keyboard_tracking", &state.features.keyboardTracking, true },
#ifndef __ANDROID__
{ "XR_MND_headless", &state.features.headless, true },
#endif
{ "XR_EXTX_overlay", &state.features.overlay, config->overlay },
{ "XR_HTCX_vive_tracker_interaction", &state.features.viveTrackers, true }
};
@ -354,15 +360,27 @@ 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,
#ifdef __ANDROID__
.next = &infoAndroid,
#endif
.applicationInfo.engineName = "LÖVR",
.applicationInfo.engineVersion = (LOVR_VERSION_MAJOR << 24) + (LOVR_VERSION_MINOR << 16) + LOVR_VERSION_PATCH,
.applicationInfo.applicationName = "LÖVR",
.applicationInfo.applicationVersion = 0,
.applicationInfo.apiVersion = XR_CURRENT_API_VERSION,
.enabledExtensionCount = enabledExtensionCount,
.enabledExtensionNames = enabledExtensionNames
.enabledExtensionNames = enabledExtensionNames,
};
XR_INIT(xrCreateInstance(&info, &state.instance));
@ -547,6 +565,7 @@ static bool openxr_init(HeadsetConfig* config) {
PROFILE_WMR,
PROFILE_TRACKER,
PROFILE_GAZE,
PROFILE_PICO,
MAX_PROFILES
};
@ -558,7 +577,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 {
@ -757,6 +777,45 @@ 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" },
{ 0, NULL }
}
};
@ -769,6 +828,7 @@ static bool openxr_init(HeadsetConfig* config) {
bindings[PROFILE_GAZE][0].path = NULL;
}
int successProfiles = -1;
XrPath path;
XrActionSuggestedBinding suggestedBindings[64];
for (uint32_t i = 0, count = 0; i < MAX_PROFILES; i++, count = 0) {
@ -780,13 +840,15 @@ static bool openxr_init(HeadsetConfig* config) {
if (count > 0) {
XR_INIT(xrStringToPath(state.instance, interactionProfilePaths[i], &path));
XR_INIT(xrSuggestInteractionProfileBindings(state.instance, &(XrInteractionProfileSuggestedBinding) {
int res = (xrSuggestInteractionProfileBindings(state.instance, &(XrInteractionProfileSuggestedBinding) {
.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING,
.interactionProfile = path,
.countSuggestedBindings = count,
.suggestedBindings = suggestedBindings
}));
if (XR_SUCCEEDED(res)) successProfiles++;
}
XR_INIT(successProfiles);
}
}