diff --git a/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderActivity.java b/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderActivity.java index 69450ce4..53bf3fa4 100644 --- a/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderActivity.java +++ b/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderActivity.java @@ -2,7 +2,12 @@ package graphics.pathfinder.pathfinderdemo; import android.Manifest; import android.annotation.SuppressLint; +import android.content.Context; import android.content.pm.PackageManager; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; @@ -14,6 +19,9 @@ import android.util.Log; import android.view.MotionEvent; import android.view.View; +import java.util.ArrayList; +import java.util.Arrays; + /** * An example full-screen activity that shows and hides the system UI (i.e. * status bar and navigation/system bar) with user interaction. @@ -154,6 +162,42 @@ public class PathfinderActivity extends AppCompatActivity { return true; } }); + + final SensorManager sensorManager = (SensorManager) + getSystemService(Context.SENSOR_SERVICE); + final Sensor rotationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR); + sensorManager.registerListener(new SensorEventListener() { + private boolean mInitialized; + private float mPitch; + private float mYaw; + + @Override + public void onSensorChanged(SensorEvent event) { + // https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles#Quaternion_to_Euler_Angles_Conversion + float[] q = event.values; + float pitch = (float)Math.asin(2.0 * (q[0] * q[2] - q[3] * q[1])); + float yaw = (float)Math.atan2(2.0 * (q[0] * q[3] + q[1] * q[2]), + 1.0 - 2.0 * (q[2] * q[2] + q[3] * q[3])); + + float deltaPitch = pitch - mPitch; + float deltaYaw = yaw - mYaw; + + mPitch = pitch; + mYaw = yaw; + + if (!mInitialized) { + mInitialized = true; + return; + } + + PathfinderDemoRenderer.pushLookEvent(-deltaPitch, deltaYaw); + } + + @Override + public void onAccuracyChanged(Sensor sensor, int accuracy) { + + } + }, rotationSensor, 5000); } @Override diff --git a/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoRenderer.java b/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoRenderer.java index 681de831..b2729045 100644 --- a/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoRenderer.java +++ b/demo/android/app/src/main/java/graphics/pathfinder/pathfinderdemo/PathfinderDemoRenderer.java @@ -14,6 +14,7 @@ public class PathfinderDemoRenderer extends Object implements GLSurfaceView.Rend public static native void pushMouseDownEvent(int x, int y); public static native void pushMouseDraggedEvent(int x, int y); + public static native void pushLookEvent(float pitch, float yaw); static { System.loadLibrary("pathfinder_android_demo"); diff --git a/demo/android/rust/src/lib.rs b/demo/android/rust/src/lib.rs index 266e87a7..f7262015 100644 --- a/demo/android/rust/src/lib.rs +++ b/demo/android/rust/src/lib.rs @@ -19,7 +19,6 @@ use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_gl::GLVersion; use pathfinder_gpu::resources::ResourceLoader; use std::cell::RefCell; -use std::ffi::CString; use std::io::Error as IOError; use std::mem; use std::os::raw::c_void; @@ -63,8 +62,8 @@ pub unsafe extern "system" fn #[no_mangle] pub unsafe extern "system" fn Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushMouseDownEvent( - env: JNIEnv, - class: JClass, + _: JNIEnv, + _: JClass, x: i32, y: i32) { EVENT_QUEUE.lock().unwrap().push(Event::MouseDown(Point2DI32::new(x, y))) @@ -73,13 +72,23 @@ pub unsafe extern "system" fn #[no_mangle] pub unsafe extern "system" fn Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushMouseDraggedEvent( - env: JNIEnv, - class: JClass, + _: JNIEnv, + _: JClass, x: i32, y: i32) { EVENT_QUEUE.lock().unwrap().push(Event::MouseDragged(Point2DI32::new(x, y))) } +#[no_mangle] +pub unsafe extern "system" fn + Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushLookEvent( + _: JNIEnv, + _: JClass, + pitch: f32, + yaw: f32) { + EVENT_QUEUE.lock().unwrap().push(Event::Look { pitch, yaw }) +} + struct WindowImpl; impl Window for WindowImpl { diff --git a/demo/common/src/lib.rs b/demo/common/src/lib.rs index b14b9d92..e28493d7 100644 --- a/demo/common/src/lib.rs +++ b/demo/common/src/lib.rs @@ -275,6 +275,12 @@ impl DemoApp where W: Window { *transform = transform.post_translate(position); } } + Event::Look { pitch, yaw } => { + if let Camera::ThreeD { ref mut transform, .. } = self.camera { + transform.pitch += pitch; + transform.yaw += yaw; + } + } Event::KeyDown(Keycode::Alphanumeric(b'w')) => { if let Camera::ThreeD { ref mut velocity, .. } = self.camera { let scale_factor = scale_factor_for_view_box(self.scene_view_box); diff --git a/demo/common/src/window.rs b/demo/common/src/window.rs index 1c98d5ea..8c8504c8 100644 --- a/demo/common/src/window.rs +++ b/demo/common/src/window.rs @@ -39,6 +39,7 @@ pub enum Event { MouseMoved(Point2DI32), MouseDragged(Point2DI32), Zoom(f32), + Look { pitch: f32, yaw: f32 }, User { message_type: u32, message_data: u32 }, }