Skip to content

Commit

Permalink
Merge pull request godotengine#18 from m4gr3d/godot4_vr_editor_standa…
Browse files Browse the repository at this point in the history
…lone

Configuring the VR Editor for standalone devices
  • Loading branch information
BastiaanOlij committed Jan 9, 2023
2 parents 301e002 + a2c64b3 commit a86198d
Show file tree
Hide file tree
Showing 10 changed files with 381 additions and 31 deletions.
12 changes: 6 additions & 6 deletions modules/openxr/action_map/openxr_action_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ void OpenXRActionMap::create_editor_action_sets() {

// Create our interaction profiles
Ref<OpenXRInteractionProfile> profile = OpenXRInteractionProfile::new_profile("/interaction_profiles/khr/simple_controller");
profile->add_new_binding(select, "/user/hand/left/input/trigger/click,/user/hand/right/input/trigger/click");
profile->add_new_binding(select, "/user/hand/left/input/select/click,/user/hand/right/input/select/click");
// simple controller doesn't support grip or has extra buttons so no alt_select support, shame...
profile->add_new_binding(tool_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
add_interaction_profile(profile);
Expand All @@ -506,15 +506,15 @@ void OpenXRActionMap::create_editor_action_sets() {

// Create our WMR controller profile
profile = OpenXRInteractionProfile::new_profile("/interaction_profiles/microsoft/motion_controller");
profile->add_new_binding(select, "/user/hand/left/input/trigger/click,/user/hand/right/input/trigger/click");
profile->add_new_binding(select, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value");
// no alt_select support, we don't have extra buttons, maybe abuse menu?
profile->add_new_binding(grab, "/user/hand/left/input/squeeze/click,/user/hand/right/input/squeeze/click"); // OpenXR will convert bool to float
profile->add_new_binding(tool_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
add_interaction_profile(profile);

// Create our Meta touch controller profile
profile = OpenXRInteractionProfile::new_profile("/interaction_profiles/oculus/touch_controller");
profile->add_new_binding(select, "/user/hand/left/input/trigger/click,/user/hand/right/input/trigger/click");
profile->add_new_binding(select, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value");
profile->add_new_binding(alt_select, "/user/hand/left/input/x/click,/user/hand/right/input/a/click");
profile->add_new_binding(grab, "/user/hand/left/input/squeeze/value,/user/hand/right/input/squeeze/value"); // should be converted to boolean
profile->add_new_binding(tool_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
Expand All @@ -530,15 +530,15 @@ void OpenXRActionMap::create_editor_action_sets() {

// Create our HP MR controller profile
profile = OpenXRInteractionProfile::new_profile("/interaction_profiles/hp/mixed_reality_controller");
profile->add_new_binding(select, "/user/hand/left/input/trigger/click,/user/hand/right/input/trigger/click");
profile->add_new_binding(select, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value");
profile->add_new_binding(alt_select, "/user/hand/left/input/x/click,/user/hand/right/input/a/click");
profile->add_new_binding(grab, "/user/hand/left/input/squeeze/click,/user/hand/right/input/squeeze/click"); // OpenXR will convert bool to float
profile->add_new_binding(grab, "/user/hand/left/input/squeeze/value,/user/hand/right/input/squeeze/value"); // OpenXR will convert bool to float
profile->add_new_binding(tool_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
add_interaction_profile(profile);

// Create our Samsung Odyssey controller profile,
profile = OpenXRInteractionProfile::new_profile("/interaction_profiles/samsung/odyssey_controller");
profile->add_new_binding(select, "/user/hand/left/input/trigger/click,/user/hand/right/input/trigger/click");
profile->add_new_binding(select, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value");
// no alt_select support, we don't have extra buttons, maybe abuse menu?
profile->add_new_binding(grab, "/user/hand/left/input/squeeze/click,/user/hand/right/input/squeeze/click");
profile->add_new_binding(tool_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
Expand Down
11 changes: 7 additions & 4 deletions platform/android/display_server_android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -662,16 +662,19 @@ void DisplayServerAndroid::cursor_set_custom_image(const Ref<Resource> &p_cursor

void DisplayServerAndroid::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
#if defined(VULKAN_ENABLED)
context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
if (rendering_driver == "vulkan") {
context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
}
#endif
}

DisplayServer::VSyncMode DisplayServerAndroid::window_get_vsync_mode(WindowID p_window) const {
#if defined(VULKAN_ENABLED)
return context_vulkan->get_vsync_mode(p_window);
#else
return DisplayServer::VSYNC_ENABLED;
if (rendering_driver == "vulkan") {
return context_vulkan->get_vsync_mode(p_window);
}
#endif
return DisplayServer::VSYNC_ENABLED;
}

void DisplayServerAndroid::reset_swap_buffers_flag() {
Expand Down
96 changes: 84 additions & 12 deletions platform/android/java/editor/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@ plugins {
id 'org.jetbrains.kotlin.android'
}

dependencies {
implementation libraries.kotlinStdLib
implementation libraries.androidxFragment
implementation project(":lib")

implementation "androidx.window:window:1.0.0"
}

ext {
// Build number added as a suffix to the version code, and incremented for each build/upload to
// the Google Play store.
Expand Down Expand Up @@ -76,26 +68,106 @@ android {
}
}

flavorDimensions "xrMode", "xrRuntime"
productFlavors {
pancake {
dimension "xrMode"
}
openxr {
dimension "xrMode"
ndk {
abiFilters "arm64-v8a"
}
applicationIdSuffix ".openxr"
versionNameSuffix "-openxr"
}

google {
dimension "xrRuntime"
}
meta {
dimension "xrRuntime"
applicationIdSuffix ".meta"
versionNameSuffix "-meta"
}
pico {
dimension "xrRuntime"
applicationIdSuffix ".pico"
versionNameSuffix "-pico"
}
}

packagingOptions {
// 'doNotStrip' is enabled for development within Android Studio
if (shouldNotStrip()) {
doNotStrip '**/*.so'
}
}

// Disable 'release' buildtype.
// The editor can't be used with target=release only, as debugging tools are then not
// included, and it would crash on errors instead of reporting them.
variantFilter { variant ->
// Disable 'release' buildtype.
// The editor can't be used with target=release only, as debugging tools are then not
// included, and it would crash on errors instead of reporting them.
if (variant.buildType.name == "release") {
setIgnore(true)
}

// Disable invalid flavors combinations
def names = variant.flavors*.name
if (names.contains("pancake")) {
if (names.contains("meta") || names.contains("pico")) {
setIgnore(true)
}
}
if (names.contains("openxr") && names.contains("google")) {
setIgnore(true)
}
}

applicationVariants.all { variant ->
variant.outputs.all { output ->
def suffix = variant.name == "dev" ? "_dev" : ""
def suffix = ""
switch (variant.name) {
case "openxrMetaDev":
suffix = "_openxr_meta_dev"
break
case "openxrMetaDebug":
suffix = "_openxr_meta"
break
case "openxrPicoDev":
suffix = "_openxr_pico_dev"
break
case "openxrPicoDebug":
suffix = "_openxr_pico"
break
case "pancakeGoogleDev":
suffix = "_dev"
break
case "pancakeGoogleDebug":
default:
suffix = ""
break
}
output.outputFileName = "android_editor${suffix}.apk"
}
}
}

configurations {
openxrMetaImplementation {}
openxrPicoImplementation {}
}

dependencies {
implementation libraries.kotlinStdLib
implementation libraries.androidxFragment
implementation project(":lib")

implementation "androidx.window:window:1.0.0"

// Meta OpenXR dependencies
openxrMetaImplementation "org.godotengine:godot-openxr-loaders-meta:1.0.0"

// Pico OpenXR dependencies
openxrPicoImplementation "org.godotengine:godot-openxr-loaders-pico:1.0.0"
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import android.os.Debug
import android.os.Environment
import android.util.Log
import android.widget.Toast
import androidx.annotation.CallSuper
import androidx.window.layout.WindowMetricsCalculator
import org.godotengine.godot.FullScreenGodotApp
import org.godotengine.godot.utils.PermissionsUtil
Expand All @@ -64,11 +65,11 @@ open class GodotEditor : FullScreenGodotApp() {

private const val COMMAND_LINE_PARAMS = "command_line_params"

private const val EDITOR_ARG = "--editor"
private const val EDITOR_ARG_SHORT = "-e"
const val EDITOR_ARG = "--editor"
const val EDITOR_ARG_SHORT = "-e"

private const val PROJECT_MANAGER_ARG = "--project-manager"
private const val PROJECT_MANAGER_ARG_SHORT = "-p"
const val PROJECT_MANAGER_ARG = "--project-manager"
const val PROJECT_MANAGER_ARG_SHORT = "-p"
}

private val commandLineParams = ArrayList<String>()
Expand All @@ -92,39 +93,61 @@ open class GodotEditor : FullScreenGodotApp() {
}
}

private fun updateCommandLineParams(args: Array<String>?) {
@CallSuper
protected open fun updateCommandLineParams(args: Array<String>?) {
// Update the list of command line params with the new args
commandLineParams.clear()
if (args != null && args.isNotEmpty()) {
commandLineParams.addAll(listOf(*args))
}
}

override fun getCommandLine() = commandLineParams
final override fun getCommandLine() = commandLineParams

override fun onNewGodotInstanceRequested(args: Array<String>) {
open fun selectGodotInstanceTargetClass(args: Array<String>): Class<*> {
// Parse the arguments to figure out which activity to start.
var targetClass: Class<*> = GodotGame::class.java

for (arg in args) {
if (EDITOR_ARG == arg || EDITOR_ARG_SHORT == arg) {
targetClass = GodotEditor::class.java
break
}

if (PROJECT_MANAGER_ARG == arg || PROJECT_MANAGER_ARG_SHORT == arg) {
targetClass = GodotProjectManager::class.java
break
}
}

return targetClass
}

open fun shouldLaunchGodotInstanceAdjacent(args: Array<String>): Boolean {
// Whether we should launch the new godot instance in an adjacent window
// https://developer.android.com/reference/android/content/Intent#FLAG_ACTIVITY_LAUNCH_ADJACENT
var launchAdjacent =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && (isInMultiWindowMode || isLargeScreen)

for (arg in args) {
if (EDITOR_ARG == arg || EDITOR_ARG_SHORT == arg) {
targetClass = GodotEditor::class.java
launchAdjacent = false
break
}

if (PROJECT_MANAGER_ARG == arg || PROJECT_MANAGER_ARG_SHORT == arg) {
targetClass = GodotProjectManager::class.java
launchAdjacent = false
break
}
}

return launchAdjacent
}

final override fun onNewGodotInstanceRequested(args: Array<String>) {
val launchAdjacent = shouldLaunchGodotInstanceAdjacent(args)
val targetClass = selectGodotInstanceTargetClass(args)

// Launch a new activity
val newInstance = Intent(this, targetClass)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
Expand Down
53 changes: 53 additions & 0 deletions platform/android/java/editor/src/openxr/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.godotengine.editor">

<application>

<activity android:name=".GodotXRProjectManager"
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
android:process=":GodotXRProjectManager"
android:launchMode="singleTask"
android:exported="true"
android:screenOrientation="userLandscape"
android:resizeableActivity="false"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">

<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.oculus.intent.category.VR" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name=".GodotXREditor"
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
android:process=":GodotXREditor"
android:launchMode="singleTask"
android:exported="false"
android:screenOrientation="userLandscape"
android:resizeableActivity="false"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
<intent-filter>
<category android:name="com.oculus.intent.category.VR" />
</intent-filter>
</activity>

<activity
android:name=".GodotXRGame"
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
android:process=":GodotXRGame"
android:launchMode="singleTask"
android:exported="false"
android:screenOrientation="userLandscape"
android:resizeableActivity="false"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
<intent-filter>
<category android:name="com.oculus.intent.category.VR" />
</intent-filter>
</activity>

</application>

</manifest>
Loading

0 comments on commit a86198d

Please sign in to comment.