Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions core/config/project_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1570,6 +1570,11 @@ ProjectSettings::ProjectSettings() {

GLOBAL_DEF("collada/use_ambient", false);

// Input settings
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_long_press_as_right_click", false);
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_pan_and_scale_gestures", false);
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "input_devices/pointing/android/rotary_input_scroll_axis", PROPERTY_HINT_ENUM, "Horizontal,Vertical"), 1);

// These properties will not show up in the dialog. If you want to exclude whole groups, use add_hidden_prefix().
GLOBAL_DEF_INTERNAL("application/config/features", PackedStringArray());
GLOBAL_DEF_INTERNAL("internationalization/locale/translation_remaps", PackedStringArray());
Expand Down
33 changes: 33 additions & 0 deletions core/input/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,21 +513,49 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, const String &p_

Vector3 Input::get_gravity() const {
_THREAD_SAFE_METHOD_

#ifdef DEBUG_ENABLED
if (!gravity_enabled) {
WARN_PRINT_ONCE("`input_devices/sensors/enable_gravity` is not enabled in project settings.");
}
#endif

return gravity;
}

Vector3 Input::get_accelerometer() const {
_THREAD_SAFE_METHOD_

#ifdef DEBUG_ENABLED
if (!accelerometer_enabled) {
WARN_PRINT_ONCE("`input_devices/sensors/enable_accelerometer` is not enabled in project settings.");
}
#endif

return accelerometer;
}

Vector3 Input::get_magnetometer() const {
_THREAD_SAFE_METHOD_

#ifdef DEBUG_ENABLED
if (!magnetometer_enabled) {
WARN_PRINT_ONCE("`input_devices/sensors/enable_magnetometer` is not enabled in project settings.");
}
#endif

return magnetometer;
}

Vector3 Input::get_gyroscope() const {
_THREAD_SAFE_METHOD_

#ifdef DEBUG_ENABLED
if (!gyroscope_enabled) {
WARN_PRINT_ONCE("`input_devices/sensors/enable_gyroscope` is not enabled in project settings.");
}
#endif

return gyroscope;
}

Expand Down Expand Up @@ -1683,6 +1711,11 @@ Input::Input() {
// Always use standard behavior in the editor.
legacy_just_pressed_behavior = false;
}

accelerometer_enabled = GLOBAL_DEF_RST_BASIC("input_devices/sensors/enable_accelerometer", false);
gravity_enabled = GLOBAL_DEF_RST_BASIC("input_devices/sensors/enable_gravity", false);
gyroscope_enabled = GLOBAL_DEF_RST_BASIC("input_devices/sensors/enable_gyroscope", false);
magnetometer_enabled = GLOBAL_DEF_RST_BASIC("input_devices/sensors/enable_magnetometer", false);
}

Input::~Input() {
Expand Down
4 changes: 4 additions & 0 deletions core/input/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,13 @@ class Input : public Object {
RBSet<JoyButton> joy_buttons_pressed;
RBMap<JoyAxis, float> _joy_axis;
//RBMap<StringName,int> custom_action_press;
bool gravity_enabled = false;
Vector3 gravity;
bool accelerometer_enabled = false;
Vector3 accelerometer;
bool magnetometer_enabled = false;
Vector3 magnetometer;
bool gyroscope_enabled = false;
Vector3 gyroscope;
Vector2 mouse_pos;
int64_t mouse_window = 0;
Expand Down
12 changes: 12 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1422,6 +1422,18 @@
<member name="input_devices/pointing/emulate_touch_from_mouse" type="bool" setter="" getter="" default="false">
If [code]true[/code], sends touch input events when clicking or dragging the mouse.
</member>
<member name="input_devices/sensors/enable_accelerometer" type="bool" setter="" getter="" default="false">
If [code]true[/code], the accelerometer sensor is enabled and [method Input.get_accelerometer] returns valid data.
</member>
<member name="input_devices/sensors/enable_gravity" type="bool" setter="" getter="" default="false">
If [code]true[/code], the gravity sensor is enabled and [method Input.get_gravity] returns valid data.
</member>
<member name="input_devices/sensors/enable_gyroscope" type="bool" setter="" getter="" default="false">
If [code]true[/code], the gyroscope sensor is enabled and [method Input.get_gyroscope] returns valid data.
</member>
<member name="input_devices/sensors/enable_magnetometer" type="bool" setter="" getter="" default="false">
If [code]true[/code], the magnetometer sensor is enabled and [method Input.get_magnetometer] returns valid data.
</member>
<member name="internationalization/locale/fallback" type="String" setter="" getter="" default="&quot;en&quot;">
The locale to fall back to if a translation isn't available in a given language. If left empty, [code]en[/code] (English) will be used.
</member>
Expand Down
3 changes: 0 additions & 3 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2942,9 +2942,6 @@ Error Main::setup2(bool p_show_boot_logo) {
id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF_BASIC("input_devices/pointing/emulate_mouse_from_touch", true)));
}

GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_long_press_as_right_click", false);
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_pan_and_scale_gestures", false);
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "input_devices/pointing/android/rotary_input_scroll_axis", PROPERTY_HINT_ENUM, "Horizontal,Vertical"), 1);
OS::get_singleton()->benchmark_end_measure("Startup", "Setup Window and Boot");
}

Expand Down
149 changes: 59 additions & 90 deletions platform/android/java/lib/src/org/godotengine/godot/Godot.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ import android.content.res.Configuration
import android.content.res.Resources
import android.graphics.Color
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.os.*
import android.util.Log
Expand All @@ -53,6 +51,7 @@ import androidx.core.view.WindowInsetsAnimationCompat
import androidx.core.view.WindowInsetsCompat
import com.google.android.vending.expansion.downloader.*
import org.godotengine.godot.input.GodotEditText
import org.godotengine.godot.input.GodotInputHandler
import org.godotengine.godot.io.directory.DirectoryAccessHandler
import org.godotengine.godot.io.file.FileAccessHandler
import org.godotengine.godot.plugin.GodotPluginRegistry
Expand All @@ -73,6 +72,7 @@ import java.io.InputStream
import java.lang.Exception
import java.security.MessageDigest
import java.util.*
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference

/**
Expand All @@ -81,7 +81,7 @@ import java.util.concurrent.atomic.AtomicReference
* Can be hosted by [Activity], [Fragment] or [Service] android components, so long as its
* lifecycle methods are properly invoked.
*/
class Godot(private val context: Context) : SensorEventListener {
class Godot(private val context: Context) {

private companion object {
private val TAG = Godot::class.java.simpleName
Expand All @@ -99,15 +99,23 @@ class Godot(private val context: Context) : SensorEventListener {
private val pluginRegistry: GodotPluginRegistry by lazy {
GodotPluginRegistry.getPluginRegistry()
}

private val accelerometer_enabled = AtomicBoolean(false)
private val mAccelerometer: Sensor? by lazy {
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
}

private val gravity_enabled = AtomicBoolean(false)
private val mGravity: Sensor? by lazy {
mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY)
}

private val magnetometer_enabled = AtomicBoolean(false)
private val mMagnetometer: Sensor? by lazy {
mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)
}

private val gyroscope_enabled = AtomicBoolean(false)
private val mGyroscope: Sensor? by lazy {
mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
}
Expand All @@ -127,6 +135,7 @@ class Godot(private val context: Context) : SensorEventListener {
val fileAccessHandler = FileAccessHandler(context)
val netUtils = GodotNetUtils(context)
private val commandLineFileParser = CommandLineFileParser()
private val godotInputHandler = GodotInputHandler(context, this)

/**
* Task to run when the engine terminates.
Expand Down Expand Up @@ -154,6 +163,17 @@ class Godot(private val context: Context) : SensorEventListener {
private var renderViewInitialized = false
private var primaryHost: GodotHost? = null

/**
* Tracks whether we're in the RESUMED lifecycle state.
* See [onResume] and [onPause]
*/
private var resumed = false

/**
* Tracks whether [onGodotSetupCompleted] fired.
*/
private val godotMainLoopStarted = AtomicBoolean(false)

var io: GodotIO? = null

private var commandLine : MutableList<String> = ArrayList<String>()
Expand Down Expand Up @@ -416,10 +436,10 @@ class Godot(private val context: Context) : SensorEventListener {
if (!meetsVulkanRequirements(activity.packageManager)) {
throw IllegalStateException(activity.getString(R.string.error_missing_vulkan_requirements_message))
}
GodotVulkanRenderView(host, this)
GodotVulkanRenderView(host, this, godotInputHandler)
} else {
// Fallback to openGl
GodotGLRenderView(host, this, xrMode, useDebugOpengl)
GodotGLRenderView(host, this, godotInputHandler, xrMode, useDebugOpengl)
}

if (host == primaryHost) {
Expand Down Expand Up @@ -520,23 +540,13 @@ class Godot(private val context: Context) : SensorEventListener {

fun onResume(host: GodotHost) {
Log.v(TAG, "OnResume: $host")
resumed = true
if (host != primaryHost) {
return
}

renderView?.onActivityResumed()
if (mAccelerometer != null) {
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME)
}
if (mGravity != null) {
mSensorManager.registerListener(this, mGravity, SensorManager.SENSOR_DELAY_GAME)
}
if (mMagnetometer != null) {
mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_GAME)
}
if (mGyroscope != null) {
mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME)
}
registerSensorsIfNeeded()
if (useImmersive) {
val window = requireActivity().window
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
Expand All @@ -551,14 +561,34 @@ class Godot(private val context: Context) : SensorEventListener {
}
}

private fun registerSensorsIfNeeded() {
if (!resumed || !godotMainLoopStarted.get()) {
return
}

if (accelerometer_enabled.get() && mAccelerometer != null) {
mSensorManager.registerListener(godotInputHandler, mAccelerometer, SensorManager.SENSOR_DELAY_GAME)
}
if (gravity_enabled.get() && mGravity != null) {
mSensorManager.registerListener(godotInputHandler, mGravity, SensorManager.SENSOR_DELAY_GAME)
}
if (magnetometer_enabled.get() && mMagnetometer != null) {
mSensorManager.registerListener(godotInputHandler, mMagnetometer, SensorManager.SENSOR_DELAY_GAME)
}
if (gyroscope_enabled.get() && mGyroscope != null) {
mSensorManager.registerListener(godotInputHandler, mGyroscope, SensorManager.SENSOR_DELAY_GAME)
}
}

fun onPause(host: GodotHost) {
Log.v(TAG, "OnPause: $host")
resumed = false
if (host != primaryHost) {
return
}

renderView?.onActivityPaused()
mSensorManager.unregisterListener(this)
mSensorManager.unregisterListener(godotInputHandler)
for (plugin in pluginRegistry.allPlugins) {
plugin.onMainPause()
}
Expand Down Expand Up @@ -659,6 +689,16 @@ class Godot(private val context: Context) : SensorEventListener {
*/
private fun onGodotMainLoopStarted() {
Log.v(TAG, "OnGodotMainLoopStarted")
godotMainLoopStarted.set(true)

accelerometer_enabled.set(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/sensors/enable_accelerometer")))
gravity_enabled.set(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/sensors/enable_gravity")))
gyroscope_enabled.set(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/sensors/enable_gyroscope")))
magnetometer_enabled.set(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/sensors/enable_magnetometer")))

runOnUiThread {
registerSensorsIfNeeded()
}

for (plugin in pluginRegistry.allPlugins) {
plugin.onGodotMainLoopStarted()
Expand Down Expand Up @@ -858,77 +898,6 @@ class Godot(private val context: Context) : SensorEventListener {
}
}

private fun getRotatedValues(values: FloatArray?): FloatArray? {
if (values == null || values.size != 3) {
return null
}
val rotatedValues = FloatArray(3)
when (windowManager.defaultDisplay.rotation) {
Surface.ROTATION_0 -> {
rotatedValues[0] = values[0]
rotatedValues[1] = values[1]
rotatedValues[2] = values[2]
}
Surface.ROTATION_90 -> {
rotatedValues[0] = -values[1]
rotatedValues[1] = values[0]
rotatedValues[2] = values[2]
}
Surface.ROTATION_180 -> {
rotatedValues[0] = -values[0]
rotatedValues[1] = -values[1]
rotatedValues[2] = values[2]
}
Surface.ROTATION_270 -> {
rotatedValues[0] = values[1]
rotatedValues[1] = -values[0]
rotatedValues[2] = values[2]
}
}
return rotatedValues
}

override fun onSensorChanged(event: SensorEvent) {
if (renderView == null) {
return
}

val rotatedValues = getRotatedValues(event.values)

when (event.sensor.type) {
Sensor.TYPE_ACCELEROMETER -> {
rotatedValues?.let {
renderView?.queueOnRenderThread {
GodotLib.accelerometer(-it[0], -it[1], -it[2])
}
}
}
Sensor.TYPE_GRAVITY -> {
rotatedValues?.let {
renderView?.queueOnRenderThread {
GodotLib.gravity(-it[0], -it[1], -it[2])
}
}
}
Sensor.TYPE_MAGNETIC_FIELD -> {
rotatedValues?.let {
renderView?.queueOnRenderThread {
GodotLib.magnetometer(-it[0], -it[1], -it[2])
}
}
}
Sensor.TYPE_GYROSCOPE -> {
rotatedValues?.let {
renderView?.queueOnRenderThread {
GodotLib.gyroscope(it[0], it[1], it[2])
}
}
}
}
}

override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}

/**
* Used by the native code (java_godot_wrapper.h) to vibrate the device.
* @param durationMs
Expand Down Expand Up @@ -1063,7 +1032,7 @@ class Godot(private val context: Context) : SensorEventListener {

@Keep
private fun initInputDevices() {
renderView?.initInputDevices()
godotInputHandler.initInputDevices()
}

@Keep
Expand Down
Loading