如何在 Google VR 视图中导航? [英] How to navigate in Google VR view?

查看:17
本文介绍了如何在 Google VR 视图中导航?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 虚拟全景视图我知道在 VR 应用中有两种导航方式

I am writing an android app using VrPanoramaView I know there are two ways to navigate in VR apps

  • 使用纸板上的单个按钮作为点击
  • 将长时间看某物视为点击

如何使用其中一种实现导航,以便如果用户单击按钮 panoview 将跳到下一张图片?

How can i implement navigation using one of these so that if user clicks button panoview will skip to the next picture?

以下是示例 Vr PanoramaView 代码

Below is the sample Vr PanoramaView code

**
 * A basic PanoWidget Activity to load panorama images from disk. It will load a test image by
 * default. It can also load an arbitrary image from disk using:
 *   adb shell am start -a "android.intent.action.VIEW" 
 *     -n "com.google.vr.sdk.samples.simplepanowidget/.SimpleVrPanoramaActivity" 
 *     -d "/sdcard/FILENAME.JPG"
 *
 * To load stereo images, "--ei inputType 2" can be used to pass in an integer extra which will set
 * VrPanoramaView.Options.inputType.
 */
public class SimpleVrPanoramaActivity extends Activity {
  InputStream istr = null;

  private static final String TAG = SimpleVrPanoramaActivity.class.getSimpleName();
  /** Actual panorama widget. **/
  private VrPanoramaView panoWidgetView;
  /**
   * Arbitrary variable to track load status. In this example, this variable should only be accessed
   * on the UI thread. In a real app, this variable would be code that performs some UI actions when
   * the panorama is fully loaded.
   */
  public boolean loadImageSuccessful;
  /** Tracks the file to be loaded across the lifetime of this app. **/
  private Uri fileUri;
  /** Configuration information for the panorama. **/
  private Options panoOptions = new Options();
  private ImageLoaderTask backgroundImageLoaderTask;

  /**
   * Called when the app is launched via the app icon or an intent using the adb command above. This
   * initializes the app and loads the image to render.
   */
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_layout);

    // Make the source link clickable.
    TextView sourceText = (TextView) findViewById(R.id.source);
    sourceText.setText(Html.fromHtml(getString(R.string.source)));
    sourceText.setMovementMethod(LinkMovementMethod.getInstance());

    panoWidgetView = (VrPanoramaView) findViewById(R.id.pano_view);
    panoWidgetView.setEventListener(new ActivityEventListener());

    // Initial launch of the app or an Activity recreation due to rotation.
    handleIntent(getIntent());
  }

  /**
   * Called when the Activity is already running and it's given a new intent.
   */
  @Override
  protected void onNewIntent(Intent intent) {
    Log.i(TAG, this.hashCode() + ".onNewIntent()");
    // Save the intent. This allows the getIntent() call in onCreate() to use this new Intent during
    // future invocations.
    setIntent(intent);
    // Load the new image.
    handleIntent(intent);
  }

  /**
   * Load custom images based on the Intent or load the default image. See the Javadoc for this
   * class for information on generating a custom intent via adb.
   */
  private void handleIntent(Intent intent) {
    // Determine if the Intent contains a file to load.
    if (Intent.ACTION_VIEW.equals(intent.getAction())) {
      Log.i(TAG, "ACTION_VIEW Intent recieved");

      fileUri = intent.getData();
      if (fileUri == null) {
        Log.w(TAG, "No data uri specified. Use "-d /path/filename".");
      } else {
        Log.i(TAG, "Using file " + fileUri.toString());
      }

      panoOptions.inputType = intent.getIntExtra("inputType", Options.TYPE_MONO);
      Log.i(TAG, "Options.inputType = " + panoOptions.inputType);
    } else {
      Log.i(TAG, "Intent is not ACTION_VIEW. Using default pano image.");
      fileUri = null;
      panoOptions.inputType = Options.TYPE_MONO;
    }

    // Load the bitmap in a background thread to avoid blocking the UI thread. This operation can
    // take 100s of milliseconds.
    if (backgroundImageLoaderTask != null) {
      // Cancel any task from a previous intent sent to this activity.
      backgroundImageLoaderTask.cancel(true);
    }
    backgroundImageLoaderTask = new ImageLoaderTask();
    backgroundImageLoaderTask.execute(Pair.create(fileUri, panoOptions));
  }

  @Override
  protected void onPause() {
    panoWidgetView.pauseRendering();
    super.onPause();
  }

  @Override
  protected void onResume() {
    super.onResume();
    panoWidgetView.resumeRendering();
  }

  @Override
  protected void onDestroy() {
    // Destroy the widget and free memory.
    panoWidgetView.shutdown();

    // The background task has a 5 second timeout so it can potentially stay alive for 5 seconds
    // after the activity is destroyed unless it is explicitly cancelled.
    if (backgroundImageLoaderTask != null) {
      backgroundImageLoaderTask.cancel(true);
    }
    super.onDestroy();
  }

  /**
   * Helper class to manage threading.
   */
  class ImageLoaderTask extends AsyncTask<Pair<Uri, Options>, Void, Boolean> {

    /**
     * Reads the bitmap from disk in the background and waits until it's loaded by pano widget.
     */
    @Override
    protected Boolean doInBackground(Pair<Uri, Options>... fileInformation) {
      Options panoOptions = null;  // It's safe to use null VrPanoramaView.Options.
      InputStream istr = null;
      if (fileInformation == null || fileInformation.length < 1
          || fileInformation[0] == null || fileInformation[0].first == null) {
        AssetManager assetManager = getAssets();
        try {
          istr=new URL("https://s18.postimg.org/rnoymr5o9/andes.jpg").openStream();
          //istr = assetManager.open("andes.jpg");
          panoOptions = new Options();
          panoOptions.inputType = Options.TYPE_STEREO_OVER_UNDER;
        } catch (IOException e) {
          Log.e(TAG, "Could not decode default bitmap: " + e);
          return false;
        }
      } else {
        try {
          istr = new FileInputStream(new File(fileInformation[0].first.getPath()));
          panoOptions = fileInformation[0].second;
        } catch (IOException e) {
          Log.e(TAG, "Could not load file: " + e);
          return false;
        }
      }

      try {
        istr.close();
      } catch (IOException e) {
        Log.e(TAG, "Could not close input stream: " + e);
      }

      return true;
    }

    @Override
    protected void onPostExecute(Boolean aBoolean) {
      super.onPostExecute(aBoolean);

      panoWidgetView.loadImageFromBitmap(BitmapFactory.decodeStream(istr), panoOptions);

    }
  }

  /**
   * Listen to the important events from widget.
   */
  private class ActivityEventListener extends VrPanoramaEventListener {
    /**
     * Called by pano widget on the UI thread when it's done loading the image.
     */
    @Override
    public void onLoadSuccess() {
      loadImageSuccessful = true;
    }

    /**
     * Called by pano widget on the UI thread on any asynchronous error.
     */
    @Override
    public void onLoadError(String errorMessage) {
      loadImageSuccessful = false;
      Toast.makeText(
          SimpleVrPanoramaActivity.this, "Error loading pano: " + errorMessage, Toast.LENGTH_LONG)
          .show();
      Log.e(TAG, "Error loading pano: " + errorMessage);
    }
  }
}

推荐答案

  1. 您需要声明传感器

  1. You need to declare Sensors

private SensorManager mSensorManager;
private OrientationSensor mOrientationSensor;
mSensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);
mOrientationSensor = new OrientationSensor(this, mSensorManager, OrientationSensor.MODE_LOOK_THROUGH);

  • 让你的activity或fragment实现SensorEventListener

    创建向量以获取旋转值

     private float[] mHeadRotation = new float[2];
    

  • 在 onSensorChanged 中

  • In onSensorChanged

    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        mUiPanoWidgetView.getHeadRotation(mHeadRotation);
        updateReticule();
    }
    

  • 根据你在图片上的位置做你想做的事.示例:

  • Do what you want depending on where you are on picture. Example:

    private void updateReticule() {
        if(mHeadRotation[1] > -20 && mHeadRotation[1] < 20 && mHeadRotation[0] > -15 && mHeadRotation[0] < 15){
            showButton();
        } else {
            showReticule();
        }
    }
    

  • showButton() 可以在屏幕中央显示或隐藏一个箭头(ImageButton).然后在箭头上设置一个 OnClickListener.如果用户点击,则可以转到下一张图片.

  • showButton() can show or hide an arrow (ImageButton) in the center of the screen. Then you set an OnClickListener on the arrow. If users click, then you can go to next picture.

    希望对你有帮助:)

    这篇关于如何在 Google VR 视图中导航?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆