Add more Daydream VR support
This commit is contained in:
parent
5db7edad0b
commit
49660a6b31
|
@ -22,6 +22,8 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
compile 'com.google.vr:sdk-base:1.160.0'
|
||||||
|
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
implementation 'com.android.support:appcompat-v7:27.1.1'
|
implementation 'com.android.support:appcompat-v7:27.1.1'
|
||||||
implementation 'com.android.support:support-v4:27.1.1'
|
implementation 'com.android.support:support-v4:27.1.1'
|
||||||
|
|
|
@ -11,17 +11,40 @@
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
<activity
|
<activity
|
||||||
android:name=".PathfinderActivity"
|
android:name=".PathfinderActivity"
|
||||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
android:configChanges="density|navigation|orientation|keyboardHidden|screenSize|uiMode"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/FullscreenTheme">
|
android:theme="@style/VrActivityTheme"
|
||||||
|
android:resizeableActivity="false">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
|
||||||
|
<!-- This marks the Activity as a Daydream Activity and allows it
|
||||||
|
to be launched from the Daydream Home. -->
|
||||||
|
<category android:name="com.google.intent.category.DAYDREAM" />
|
||||||
|
|
||||||
|
<!-- This marks the Activity as a Cardboard Activity and allows it
|
||||||
|
to be launched from the Cardboard app. -->
|
||||||
|
<category android:name="com.google.intent.category.CARDBOARD" />
|
||||||
|
|
||||||
|
<!-- This allows this Activity to be launched from the traditional
|
||||||
|
Android 2D launcher as well. Remove it if you do not want
|
||||||
|
this Activity to be launched directly from the 2D launcher. -->
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<service android:name=".PathfinderDemoVRListenerService"
|
||||||
|
android:label="@string/service_name"
|
||||||
|
android:permission="android.permission.BIND_VR_LISTENER_SERVICE">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.service.vr.VrListenerService" />
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
</application>
|
</application>
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
<uses-feature android:name="android.software.vr.mode" android:required="false"/>
|
||||||
|
<uses-feature android:name="android.hardware.vr.high_performance" android:required="false"/>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
|
@ -2,102 +2,42 @@ package graphics.pathfinder.pathfinderdemo;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.hardware.Sensor;
|
import android.hardware.Sensor;
|
||||||
import android.hardware.SensorEvent;
|
import android.hardware.SensorEvent;
|
||||||
import android.hardware.SensorEventListener;
|
import android.hardware.SensorEventListener;
|
||||||
import android.hardware.SensorManager;
|
import android.hardware.SensorManager;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.provider.Settings;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.RequiresApi;
|
||||||
import android.support.v4.app.ActivityCompat;
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v7.app.ActionBar;
|
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import com.google.vr.cardboard.AndroidNCompat;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An example full-screen activity that shows and hides the system UI (i.e.
|
* An example full-screen activity that shows and hides the system UI (i.e.
|
||||||
* status bar and navigation/system bar) with user interaction.
|
* status bar and navigation/system bar) with user interaction.
|
||||||
*/
|
*/
|
||||||
public class PathfinderActivity extends AppCompatActivity {
|
public class PathfinderActivity extends Activity {
|
||||||
private PathfinderDemoRenderer mRenderer;
|
private PathfinderDemoRenderer mRenderer;
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not the system UI should be auto-hidden after
|
|
||||||
* {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
|
|
||||||
*/
|
|
||||||
private static final boolean AUTO_HIDE = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after
|
|
||||||
* user interaction before hiding the system UI.
|
|
||||||
*/
|
|
||||||
private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some older devices needs a small delay between UI widget updates
|
* Some older devices needs a small delay between UI widget updates
|
||||||
* and a change of the status and navigation bar.
|
* and a change of the status and navigation bar.
|
||||||
*/
|
*/
|
||||||
private static final int UI_ANIMATION_DELAY = 300;
|
|
||||||
private final Handler mHideHandler = new Handler();
|
|
||||||
private PathfinderDemoSurfaceView mContentView;
|
private PathfinderDemoSurfaceView mContentView;
|
||||||
private final Runnable mHidePart2Runnable = new Runnable() {
|
|
||||||
@SuppressLint("InlinedApi")
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// Delayed removal of status and navigation bar
|
|
||||||
|
|
||||||
// Note that some of these constants are new as of API 16 (Jelly Bean)
|
ComponentName mVRListenerComponentName;
|
||||||
// and API 19 (KitKat). It is safe to use them, as they are inlined
|
|
||||||
// at compile-time and do nothing on earlier devices.
|
|
||||||
mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
|
|
||||||
| View.SYSTEM_UI_FLAG_FULLSCREEN
|
|
||||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
|
||||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
|
||||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
|
||||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private View mControlsView;
|
|
||||||
private final Runnable mShowPart2Runnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// Delayed display of UI elements
|
|
||||||
ActionBar actionBar = getSupportActionBar();
|
|
||||||
if (actionBar != null) {
|
|
||||||
actionBar.show();
|
|
||||||
}
|
|
||||||
mControlsView.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private boolean mVisible;
|
|
||||||
private final Runnable mHideRunnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
hide();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Touch listener to use for in-layout UI controls to delay hiding the
|
|
||||||
* system UI. This is to prevent the jarring behavior of controls going away
|
|
||||||
* while interacting with activity UI.
|
|
||||||
*/
|
|
||||||
private final View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
|
||||||
if (AUTO_HIDE) {
|
|
||||||
delayedHide(AUTO_HIDE_DELAY_MILLIS);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -122,13 +62,26 @@ public class PathfinderActivity extends AppCompatActivity {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
|
void setVRMode(boolean enabled) {
|
||||||
|
try {
|
||||||
|
setVrModeEnabled(false, mVRListenerComponentName);
|
||||||
|
} catch (PackageManager.NameNotFoundException exception) {
|
||||||
|
startActivity(new Intent(Settings.ACTION_VR_LISTENER_SETTINGS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
private void init() {
|
private void init() {
|
||||||
|
mVRListenerComponentName = new ComponentName("graphics.pathfinder.pathfinderdemo",
|
||||||
|
"graphics.pathfinder.pathfinderdemo.PathfinderDemoVRListenerService");
|
||||||
|
|
||||||
setContentView(R.layout.activity_pathfinder);
|
setContentView(R.layout.activity_pathfinder);
|
||||||
|
|
||||||
mVisible = true;
|
|
||||||
mControlsView = findViewById(R.id.fullscreen_content_controls);
|
|
||||||
mContentView = findViewById(R.id.fullscreen_content);
|
mContentView = findViewById(R.id.fullscreen_content);
|
||||||
|
mContentView.setStereoModeEnabled(false);
|
||||||
|
setVRMode(false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Set up the user interaction to manually show or hide the system UI.
|
// Set up the user interaction to manually show or hide the system UI.
|
||||||
|
@ -141,7 +94,7 @@ public class PathfinderActivity extends AppCompatActivity {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mContentView.setEGLContextClientVersion(3);
|
mContentView.setEGLContextClientVersion(3);
|
||||||
mRenderer = new PathfinderDemoRenderer(getAssets());
|
mRenderer = new PathfinderDemoRenderer(this);
|
||||||
mContentView.setRenderer(mRenderer);
|
mContentView.setRenderer(mRenderer);
|
||||||
|
|
||||||
mContentView.setOnTouchListener(new View.OnTouchListener() {
|
mContentView.setOnTouchListener(new View.OnTouchListener() {
|
||||||
|
@ -203,53 +156,5 @@ public class PathfinderActivity extends AppCompatActivity {
|
||||||
@Override
|
@Override
|
||||||
protected void onPostCreate(Bundle savedInstanceState) {
|
protected void onPostCreate(Bundle savedInstanceState) {
|
||||||
super.onPostCreate(savedInstanceState);
|
super.onPostCreate(savedInstanceState);
|
||||||
|
|
||||||
// Trigger the initial hide() shortly after the activity has been
|
|
||||||
// created, to briefly hint to the user that UI controls
|
|
||||||
// are available.
|
|
||||||
delayedHide(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void toggle() {
|
|
||||||
if (mVisible) {
|
|
||||||
hide();
|
|
||||||
} else {
|
|
||||||
show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void hide() {
|
|
||||||
// Hide UI first
|
|
||||||
ActionBar actionBar = getSupportActionBar();
|
|
||||||
if (actionBar != null) {
|
|
||||||
actionBar.hide();
|
|
||||||
}
|
|
||||||
mControlsView.setVisibility(View.GONE);
|
|
||||||
mVisible = false;
|
|
||||||
|
|
||||||
// Schedule a runnable to remove the status and navigation bar after a delay
|
|
||||||
mHideHandler.removeCallbacks(mShowPart2Runnable);
|
|
||||||
mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("InlinedApi")
|
|
||||||
private void show() {
|
|
||||||
// Show the system bar
|
|
||||||
mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
|
||||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
|
||||||
mVisible = true;
|
|
||||||
|
|
||||||
// Schedule a runnable to display UI elements after a delay
|
|
||||||
mHideHandler.removeCallbacks(mHidePart2Runnable);
|
|
||||||
mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Schedules a call to hide() in delay milliseconds, canceling any
|
|
||||||
* previously scheduled calls.
|
|
||||||
*/
|
|
||||||
private void delayedHide(int delayMillis) {
|
|
||||||
mHideHandler.removeCallbacks(mHideRunnable);
|
|
||||||
mHideHandler.postDelayed(mHideRunnable, delayMillis);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,58 +1,89 @@
|
||||||
package graphics.pathfinder.pathfinderdemo;
|
package graphics.pathfinder.pathfinderdemo;
|
||||||
|
|
||||||
import android.content.res.AssetManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.opengl.GLSurfaceView;
|
import android.os.Build;
|
||||||
|
import android.support.annotation.RequiresApi;
|
||||||
|
|
||||||
|
import com.google.vr.sdk.base.Eye;
|
||||||
|
import com.google.vr.sdk.base.GvrView;
|
||||||
|
import com.google.vr.sdk.base.HeadTransform;
|
||||||
|
import com.google.vr.sdk.base.Viewport;
|
||||||
import javax.microedition.khronos.egl.EGLConfig;
|
import javax.microedition.khronos.egl.EGLConfig;
|
||||||
import javax.microedition.khronos.opengles.GL10;
|
|
||||||
|
|
||||||
public class PathfinderDemoRenderer extends Object implements GLSurfaceView.Renderer {
|
public class PathfinderDemoRenderer extends Object implements GvrView.Renderer {
|
||||||
private AssetManager mAssetManager;
|
private PathfinderActivity mActivity;
|
||||||
private boolean mInitialized;
|
private boolean mInitialized;
|
||||||
|
private boolean mInVRMode;
|
||||||
|
|
||||||
private static native void init(PathfinderDemoResourceLoader resourceLoader,
|
private static native void init(PathfinderDemoResourceLoader resourceLoader,
|
||||||
int width,
|
int width,
|
||||||
int height);
|
int height);
|
||||||
|
|
||||||
private static native int prepareFrame();
|
private static native int prepareFrame();
|
||||||
|
|
||||||
private static native void drawScene(int sceneIndex);
|
private static native void drawScene(int sceneIndex);
|
||||||
|
|
||||||
private static native void finishDrawingFrame();
|
private static native void finishDrawingFrame();
|
||||||
|
|
||||||
public static native void pushWindowResizedEvent(int width, int height);
|
public static native void pushWindowResizedEvent(int width, int height);
|
||||||
|
|
||||||
public static native void pushMouseDownEvent(int x, int y);
|
public static native void pushMouseDownEvent(int x, int y);
|
||||||
|
|
||||||
public static native void pushMouseDraggedEvent(int x, int y);
|
public static native void pushMouseDraggedEvent(int x, int y);
|
||||||
|
|
||||||
public static native void pushLookEvent(float pitch, float yaw);
|
public static native void pushLookEvent(float pitch, float yaw);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
System.loadLibrary("pathfinder_android_demo");
|
System.loadLibrary("pathfinder_android_demo");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PathfinderDemoRenderer() {}
|
PathfinderDemoRenderer(PathfinderActivity activity) {
|
||||||
|
|
||||||
PathfinderDemoRenderer(AssetManager assetManager) {
|
|
||||||
super();
|
super();
|
||||||
mAssetManager = assetManager;
|
mActivity = activity;
|
||||||
mInitialized = false;
|
mInitialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
@Override
|
@Override
|
||||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
public void onDrawFrame(HeadTransform headTransform, Eye leftEye, Eye rightEye) {
|
||||||
|
boolean inVR = prepareFrame() > 1;
|
||||||
|
if (inVR != mInVRMode) {
|
||||||
|
mInVRMode = inVR;
|
||||||
|
try {
|
||||||
|
mActivity.setVrModeEnabled(mInVRMode, mActivity.mVRListenerComponentName);
|
||||||
|
} catch (PackageManager.NameNotFoundException exception) {
|
||||||
|
throw new RuntimeException(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int sceneIndex = 0; sceneIndex < (inVR ? 2 : 1); sceneIndex++)
|
||||||
|
drawScene(sceneIndex);
|
||||||
|
finishDrawingFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSurfaceChanged(GL10 gl, int width, int height) {
|
public void onFinishFrame(Viewport viewport) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSurfaceChanged(int width, int height) {
|
||||||
if (!mInitialized) {
|
if (!mInitialized) {
|
||||||
init(new PathfinderDemoResourceLoader(mAssetManager), width, height);
|
init(new PathfinderDemoResourceLoader(mActivity.getAssets()), width, height);
|
||||||
mInitialized = true;
|
mInitialized = true;
|
||||||
} else {
|
} else {
|
||||||
pushWindowResizedEvent(width, height);
|
pushWindowResizedEvent(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDrawFrame(GL10 gl) {
|
public void onSurfaceCreated(EGLConfig config) {
|
||||||
int sceneCount = prepareFrame();
|
|
||||||
for (int sceneIndex = 0; sceneIndex < sceneCount; sceneIndex++)
|
}
|
||||||
drawScene(sceneIndex);
|
|
||||||
finishDrawingFrame();
|
@Override
|
||||||
|
public void onRendererShutdown() {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,9 @@ import android.opengl.GLSurfaceView;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import com.google.vr.sdk.base.GvrView;
|
||||||
|
|
||||||
public class PathfinderDemoSurfaceView extends GLSurfaceView {
|
public class PathfinderDemoSurfaceView extends GvrView {
|
||||||
public PathfinderDemoSurfaceView(Context context) {
|
public PathfinderDemoSurfaceView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,4 +3,5 @@
|
||||||
|
|
||||||
<string name="dummy_button">Dummy Button</string>
|
<string name="dummy_button">Dummy Button</string>
|
||||||
<string name="dummy_content">DUMMY\nCONTENT</string>
|
<string name="dummy_content">DUMMY\nCONTENT</string>
|
||||||
|
<string name="service_name">PathfinderVRListenerService</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in New Issue