diff --git a/core/os/input.cpp b/core/os/input.cpp
index 6e1e618d9a8..a766ef87fc6 100644
--- a/core/os/input.cpp
+++ b/core/os/input.cpp
@@ -60,6 +60,7 @@ void Input::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_joy_name","device"),&Input::get_joy_name);
ObjectTypeDB::bind_method(_MD("get_joy_guid","device"),&Input::get_joy_guid);
ObjectTypeDB::bind_method(_MD("get_accelerometer"),&Input::get_accelerometer);
+ ObjectTypeDB::bind_method(_MD("get_magnetometer"),&Input::get_magnetometer);
//ObjectTypeDB::bind_method(_MD("get_mouse_pos"),&Input::get_mouse_pos); - this is not the function you want
ObjectTypeDB::bind_method(_MD("get_mouse_speed"),&Input::get_mouse_speed);
ObjectTypeDB::bind_method(_MD("get_mouse_button_mask"),&Input::get_mouse_button_mask);
diff --git a/core/os/input.h b/core/os/input.h
index 535776f39c0..46edb30aa15 100644
--- a/core/os/input.h
+++ b/core/os/input.h
@@ -75,6 +75,7 @@ public:
virtual void warp_mouse_pos(const Vector2& p_to)=0;
virtual Vector3 get_accelerometer()=0;
+ virtual Vector3 get_magnetometer()=0;
virtual void action_press(const StringName& p_action)=0;
virtual void action_release(const StringName& p_action)=0;
diff --git a/doc/base/classes.xml b/doc/base/classes.xml
index 561d62649d3..4893f0c4835 100644
--- a/doc/base/classes.xml
+++ b/doc/base/classes.xml
@@ -15387,6 +15387,13 @@ Example: (content-length:12), (Content-Type:application/json; charset=UTF-8)
If the device has an accelerometer, this will return the movement.
+
+
+
+
+ If the device has a magnetometer, this will return the magnetic field strength in micro-Tesla for all axes.
+
+
diff --git a/main/input_default.cpp b/main/input_default.cpp
index c8b8062eee2..5b4ae7f2cb4 100644
--- a/main/input_default.cpp
+++ b/main/input_default.cpp
@@ -200,6 +200,12 @@ Vector3 InputDefault::get_accelerometer() {
return accelerometer;
}
+Vector3 InputDefault::get_magnetometer() {
+
+ _THREAD_SAFE_METHOD_
+ return magnetometer;
+}
+
void InputDefault::parse_input_event(const InputEvent& p_event) {
_THREAD_SAFE_METHOD_
@@ -296,6 +302,14 @@ void InputDefault::set_accelerometer(const Vector3& p_accel) {
}
+void InputDefault::set_magnetometer(const Vector3& p_magnetometer) {
+
+ _THREAD_SAFE_METHOD_
+
+ magnetometer=p_magnetometer;
+
+}
+
void InputDefault::set_main_loop(MainLoop *p_main_loop) {
main_loop=p_main_loop;
diff --git a/main/input_default.h b/main/input_default.h
index 471ae9e692b..8f6a4304367 100644
--- a/main/input_default.h
+++ b/main/input_default.h
@@ -14,6 +14,7 @@ class InputDefault : public Input {
Map _joy_axis;
Map custom_action_press;
Vector3 accelerometer;
+ Vector3 magnetometer;
Vector2 mouse_pos;
MainLoop *main_loop;
@@ -132,6 +133,7 @@ public:
void parse_joystick_mapping(String p_mapping, bool p_update_existing);
virtual Vector3 get_accelerometer();
+ virtual Vector3 get_magnetometer();
virtual Point2 get_mouse_pos() const;
virtual Point2 get_mouse_speed() const;
@@ -142,6 +144,7 @@ public:
void parse_input_event(const InputEvent& p_event);
void set_accelerometer(const Vector3& p_accel);
+ void set_magnetometer(const Vector3& p_magnetometer);
void set_joy_axis(int p_device,int p_axis,float p_value);
void set_main_loop(MainLoop *main_loop);
diff --git a/platform/android/godot_android.cpp b/platform/android/godot_android.cpp
index f9feb3481f4..edb051575f5 100644
--- a/platform/android/godot_android.cpp
+++ b/platform/android/godot_android.cpp
@@ -313,6 +313,7 @@ struct engine {
ASensorManager* sensorManager;
const ASensor* accelerometerSensor;
+ const ASensor* magnetometerSensor;
ASensorEventQueue* sensorEventQueue;
bool display_active;
@@ -735,16 +736,29 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd) {
ASensorEventQueue_setEventRate(engine->sensorEventQueue,
engine->accelerometerSensor, (1000L/60)*1000);
+ }
+ // Also start monitoring the magnetometer.
+ if (engine->magnetometerSensor != NULL) {
+ ASensorEventQueue_enableSensor(engine->sensorEventQueue,
+ engine->magnetometerSensor);
+ // We'd like to get 60 events per second (in us).
+ ASensorEventQueue_setEventRate(engine->sensorEventQueue,
+ engine->magnetometerSensor, (1000L/60)*1000);
+
}
engine->animating = 1;
break;
case APP_CMD_LOST_FOCUS:
- // When our app loses focus, we stop monitoring the accelerometer.
+ // When our app loses focus, we stop monitoring the sensors.
// This is to avoid consuming battery while not being used.
if (engine->accelerometerSensor != NULL) {
ASensorEventQueue_disableSensor(engine->sensorEventQueue,
engine->accelerometerSensor);
}
+ if (engine->magnetometerSensor != NULL) {
+ ASensorEventQueue_disableSensor(engine->sensorEventQueue,
+ engine->magnetometerSensor);
+ }
// Also stop animating.
engine->animating = 0;
engine_draw_frame(engine);
@@ -768,10 +782,12 @@ void android_main(struct android_app* state) {
FileAccessAndroid::asset_manager=state->activity->assetManager;
- // Prepare to monitor accelerometer
+ // Prepare to monitor sensors
engine.sensorManager = ASensorManager_getInstance();
engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager,
- ASENSOR_TYPE_ACCELEROMETER);
+ ASENSOR_TYPE_ACCELEROMETER);
+ engine.magnetometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager,
+ ASENSOR_TYPE_MAGNETIC_FIELD);
engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager,
state->looper, LOOPER_ID_USER, NULL, NULL);
@@ -812,16 +828,21 @@ void android_main(struct android_app* state) {
// If a sensor has data, process it now.
// LOGI("events\n");
if (ident == LOOPER_ID_USER) {
- if (engine.accelerometerSensor != NULL) {
+ if (engine.accelerometerSensor != NULL || engine.magnetometerSensor != NULL) {
ASensorEvent event;
while (ASensorEventQueue_getEvents(engine.sensorEventQueue,
&event, 1) > 0) {
if (engine.os) {
+ if (event.acceleration != NULL) {
engine.os->process_accelerometer(Vector3(event.acceleration.x, event.acceleration.y,
event.acceleration.z));
-
+ }
+ if (event.magnetic != NULL) {
+ engine.os->process_magnetometer(Vector3(event.magnetic.x, event.magnetic.y,
+ event.magnetic.z));
+ }
}
}
diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java
index 1f208f8fb65..c4ba2da7517 100644
--- a/platform/android/java/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/src/org/godotengine/godot/Godot.java
@@ -206,6 +206,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
private SensorManager mSensorManager;
private Sensor mAccelerometer;
+ private Sensor mMagnetometer;
public FrameLayout layout;
public RelativeLayout adLayout;
@@ -374,6 +375,8 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
+ mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
+ mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_GAME);
result_callback = null;
@@ -588,6 +591,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
mView.onResume();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
+ mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_NORMAL);
GodotLib.focusin();
if(use_immersive && Build.VERSION.SDK_INT >= 19.0){ // check if the application runs on an android 4.4+
Window window = getWindow();
@@ -646,7 +650,14 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
float x = adjustedValues[0];
float y = adjustedValues[1];
float z = adjustedValues[2];
- GodotLib.accelerometer(x,y,z);
+
+ int typeOfSensor = event.sensor.getType();
+ if (typeOfSensor == event.sensor.TYPE_ACCELEROMETER) {
+ GodotLib.accelerometer(x,y,z);
+ }
+ if (typeOfSensor == event.sensor.TYPE_MAGNETIC_FIELD) {
+ GodotLib.magnetometer(x,y,z);
+ }
}
@Override public final void onAccuracyChanged(Sensor sensor, int accuracy) {
diff --git a/platform/android/java/src/org/godotengine/godot/GodotLib.java b/platform/android/java/src/org/godotengine/godot/GodotLib.java
index 7c5ac33c858..df181ae1bb5 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotLib.java
@@ -51,6 +51,7 @@ public class GodotLib {
public static native void step();
public static native void touch(int what,int pointer,int howmany, int[] arr);
public static native void accelerometer(float x, float y, float z);
+ public static native void magnetometer(float x, float y, float z);
public static native void key(int p_scancode, int p_unicode_char, boolean p_pressed);
public static native void joybutton(int p_device, int p_but, boolean p_pressed);
public static native void joyaxis(int p_device, int p_axis, float p_value);
diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp
index b5beb8fa2c0..1ea7cd7ebba 100644
--- a/platform/android/java_glue.cpp
+++ b/platform/android/java_glue.cpp
@@ -650,6 +650,7 @@ static bool resized_reload=false;
static bool quit_request=false;
static Size2 new_size;
static Vector3 accelerometer;
+static Vector3 magnetometer;
static HashMap jni_singletons;
static jobject godot_io;
@@ -1088,6 +1089,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv * env, jo
os_android->process_accelerometer(accelerometer);
+ os_android->process_magnetometer(magnetometer);
+
if (os_android->main_loop_iterate()==true) {
jclass cls = env->FindClass("org/godotengine/godot/Godot");
@@ -1488,6 +1491,14 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv
}
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_magnetometer(JNIEnv * env, jobject obj, jfloat x, jfloat y, jfloat z) {
+
+ input_mutex->lock();
+ magnetometer=Vector3(x,y,z);
+ input_mutex->unlock();
+
+}
+
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv * env, jobject obj){
if (!suspend_mutex)
diff --git a/platform/android/java_glue.h b/platform/android/java_glue.h
index 1d65d21251f..f7916efe2c5 100644
--- a/platform/android/java_glue.h
+++ b/platform/android/java_glue.h
@@ -49,6 +49,7 @@ extern "C" {
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(JNIEnv * env, jobject obj, jint p_device, jboolean p_connected, jstring p_name);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_audio(JNIEnv * env, jobject obj);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv * env, jobject obj, jfloat x, jfloat y, jfloat z);
+ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_magnetometer(JNIEnv * env, jobject obj, jfloat x, jfloat y, jfloat z);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv * env, jobject obj);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv * env, jobject obj);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_singleton(JNIEnv * env, jobject obj, jstring name,jobject p_object);
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 2ef28333bed..4e6dfb2db21 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -609,6 +609,11 @@ void OS_Android::process_accelerometer(const Vector3& p_accelerometer) {
input->set_accelerometer(p_accelerometer);
}
+void OS_Android::process_magnetometer(const Vector3& p_magnetometer) {
+
+ input->set_magnetometer(p_magnetometer);
+}
+
bool OS_Android::has_touchscreen_ui_hint() const {
return true;
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index ec1f4119b49..843b3c47886 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -239,6 +239,7 @@ public:
void process_accelerometer(const Vector3& p_accelerometer);
+ void process_magnetometer(const Vector3& p_magnetometer);
void process_touch(int p_what,int p_pointer, const Vector& p_points);
void process_joy_event(JoystickEvent p_event);
void process_event(InputEvent p_event);