Skip to content

Advanced Usage

Asha edited this page Sep 13, 2017 · 7 revisions

Cubemap(since 2.5.0)

@Override
protected MDVRLibrary createVRLibrary() {
    return MDVRLibrary.with(this)
            .displayMode(MDVRLibrary.DISPLAY_MODE_NORMAL)
            .interactiveMode(MDVRLibrary.INTERACTIVE_MODE_TOUCH)
            .projectionMode(MDVRLibrary.PROJECTION_MODE_CUBE) // needed
            .asCubemap(new MDVRLibrary.ICubemapProvider() {
                @Override
                public void onProvideCubemap(MD360CubemapTexture.Callback callback, int cubeFace) {
                    Log.d(TAG, "Load face: " + cubeFace);

                    switch(cubeFace) {
                        case MD360CubemapTexture.CUBE_FRONT:
                            nextUri = getDrawableUri(R.drawable.cube_front);
                            break;
                        case MD360CubemapTexture.CUBE_BACK:
                            nextUri = getDrawableUri(R.drawable.cube_back);
                            break;
                        case MD360CubemapTexture.CUBE_TOP:
                            nextUri = getDrawableUri(R.drawable.cube_top);
                            break;
                        case MD360CubemapTexture.CUBE_BOTTOM:
                            nextUri = getDrawableUri(R.drawable.cube_bottom);
                            break;
                        case MD360CubemapTexture.CUBE_LEFT:
                            nextUri = getDrawableUri(R.drawable.cube_left);
                            break;
                        case MD360CubemapTexture.CUBE_RIGHT:
                            nextUri = getDrawableUri(R.drawable.cube_right);
                            break;
                        default:
                                return;
                    }

                    loadImage(currentUri(), callback);
                }

                @Override
                public void onReady() {
                    // This can be used to hide a loading view and show the library view
                    Toast.makeText(CubemapPlayerActivity.this, "CubeMap Ready", Toast.LENGTH_SHORT).show();
                    cancelBusy();
                }
            })
            .pinchEnabled(true)
            .build(findViewById(R.id.gl_view));
}

Working with RecyclerView(since 2.5.0)

RecyclerViewActivity.java

Director Pitch/Yaw/Roll(since 2.4.0)

  • value setter
getVRLibrary().updateCamera().setEyeZ(18).setPitch(90)
  • value getter
getVRLibrary().getDirectorBrief()

// the brief is like this
public class MDDirectorBrief {
    private float pitch;
    private float yaw;
    private float roll;
}
  • value limit
getVRLibrary().setDirectorFilter(filter);

or

@Override
protected MDVRLibrary createVRLibrary() {
    return MDVRLibrary.with(this)
            ...
            .directorFilter(filter)
            .build(R.id.gl_view);
}

the sample impl of filter like this,

filter = new MDVRLibrary.DirectorFilterAdatper() {
    @Override
    public float onFilterPitch(float input) {
        // limit from -70 to 70
        if (input > 70){
            return 70;
        }

        if (input < -70){
            return -70;
        }

        return input;
    }

    @Override
    public float onFilterYaw(float input) {
        return super.onFilterYaw(input);
    }
};

MDView Usage(since 2.3.0)

findViewById(R.id.button_add_md_view).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        TextView textView = new TextView(activity);
        textView.setBackgroundColor(0x55FFCC11);
        textView.setText("Hello world.");

        MDViewBuilder builder = MDViewBuilder.create()
                .provider(textView, 400/*view width*/, 100/*view height*/)
                .size(4, 1)
                .position(MDPosition.newInstance().setZ(-12.0f))
                .title("md view")
                .tag("tag-md-text-view")
                ;

        MDAbsView mdView = new MDView(builder);
        plugins.add(mdView);
        getVRLibrary().addPlugin(mdView);
    }
});

findViewById(R.id.button_update_md_view).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        MDAbsView mdView = getVRLibrary().findViewByTag("tag-md-text-view");
        if (mdView != null){
            TextView textView = mdView.castAttachedView(TextView.class);
            textView.setText("Cheer up!");
            textView.setBackgroundColor(0x8800FF00);

            // You should call MDView#invalidate 
            // to notify the vrlib after android view changed.
            mdView.invalidate();
        }
    }
});

Enable Anti Distortion(since 2.0.0)

// init configuation
protected MDVRLibrary createVRLibrary() {
    return MDVRLibrary.with(this)
            ...
            .barrelDistortionConfig(new BarrelDistortionConfig().setDefaultEnabled(true).setScale(0.95f))
            .build(R.id.gl_view);
}
// setter
mVRLibrary.setAntiDistortionEnabled(true);

Eye Picker(since 2.0.0)

// setEyePickChangedListener dynamicly.
final TextView hotspotText = (TextView) findViewById(R.id.hotspot_text);
getVRLibrary().setEyePickChangedListener(new MDVRLibrary.IPickListener() {
    @Override
    public void onHotspotHit(IMDHotspot hotspot, long hitTimestamp) {
        String text = hotspot == null ? "nop" : String.format(Locale.CHINESE, "%s  %fs", hotspot.getTitle(), (System.currentTimeMillis() - hitTimestamp) / 1000.0f );
        hotspotText.setText(text);
    }
});
// disable the eye picker
getVRLibrary().eyePickEanbled(false);

Hotspot and widget(which has normal/focused/checked status) supported (since 2.0.0)

// add hotspot dynamicly.
private MDPosition[] positions = new MDPosition[]{
        MDPosition.newInstance().setZ(-8.0f).setYaw(-45.0f),
        MDPosition.newInstance().setZ(-18.0f).setYaw(15.0f).setAngleX(15),
};

findViewById(R.id.button_add_plugin).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        final int index = (int) (Math.random() * 100) % positions.length;
        MDPosition position = positions[index];
        MDHotspotBuilder builder = MDHotspotBuilder.create(new AndroidProvider(activity))
                .size(4f,4f)
                .provider(0, activity, android.R.drawable.star_off)
                .provider(1, activity, android.R.drawable.star_on)
                .provider(10, activity, android.R.drawable.checkbox_off_background)
                .provider(11, activity, android.R.drawable.checkbox_on_background)
                .listenClick(new MDVRLibrary.ITouchPickListener() {
                    @Override
                    public void onHotspotHit(IMDHotspot hitHotspot, MDRay ray) {
                        if (hitHotspot instanceof MDWidgetPlugin){
                            MDWidgetPlugin widgetPlugin = (MDWidgetPlugin) hitHotspot;
                            widgetPlugin.setChecked(!widgetPlugin.getChecked());
                        }
                    }
                })
                .title("star" + index)
                .position(position)
                .status(0,1)
                .checkedStatus(10,11);

        MDWidgetPlugin plugin = new MDWidgetPlugin(builder);

        plugins.add(plugin);
        getVRLibrary().addPlugin(plugin);
        Toast.makeText(MD360PlayerActivity.this, "add plugin position:" + position, Toast.LENGTH_SHORT).show();
    }
});

// android impl
private class AndroidProvider implements MDVRLibrary.IImageLoadProvider {

    Activity activity;

    public AndroidProvider(Activity activity) {
        this.activity = activity;
    }

    @Override
    public void onProvideBitmap(Uri uri, MD360BitmapTexture.Callback callback) {
        try {
            Bitmap bitmap = BitmapFactory.decodeStream(activity.getContentResolver().openInputStream(uri));
            callback.texture(bitmap);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }
}

Switch projection (since 1.5.0)

// projection mode in MDVRLibrary.java
public static final int PROJECTION_MODE_SPHERE = 201;
public static final int PROJECTION_MODE_DOME180 = 202;
public static final int PROJECTION_MODE_DOME230 = 203;
public static final int PROJECTION_MODE_DOME180_UPPER = 204;
public static final int PROJECTION_MODE_DOME230_UPPER = 205;
public static final int PROJECTION_MODE_STEREO_SPHERE = 206;
public static final int PROJECTION_MODE_PLANE_FIT = 207;
public static final int PROJECTION_MODE_PLANE_CROP = 208;
public static final int PROJECTION_MODE_PLANE_FULL = 209;

// You should call MDVRLibrary#onTextureResize(float width, float height)
// If you are using DOME projection and PLANE projection.

@Override
protected MDVRLibrary createVRLibrary() {
    return MDVRLibrary.with(this)
    		...
            .projectionMode(MDVRLibrary.PROJECTION_MODE_STEREO_SPHERE)
            ...
            .build(R.id.surface_view);
}

// switch in runtime
// MDVRLibrary#switchProjectionMode(Activity activity, int mode)

Motion configuration (since 1.3.0)

  • support sensor delay configuration in motion mode.
MDVRLibrary.with(this)
....
.motionDelay(SensorManager.SENSOR_DELAY_GAME)
...
.build(R.id.surface_view);
  • support sensorCallback
MDVRLibrary.with(this)
....
.sensorCallback(new SensorEventListener() {
    @Override
    public void onSensorChanged(SensorEvent event) {

    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }
})
....
.build(R.id.surface_view);

MD360Director Customize (since 1.2.0)

@Override
protected MDVRLibrary createVRLibrary() {
    return MDVRLibrary.with(this)
            ...
            .directorFactory(new DirectorFactory()) //替换默认MD360DirectorFactory
            ...
            .build(R.id.surface_view);
}

private static class DirectorFactory extends MD360DirectorFactory{
    @Override
    public MD360Director createDirector(int index) {
        switch (index){
            // setAngle: angle to rotate in degrees
            case 1:   return MD360Director.builder().setAngle(20).setEyeX(-2.0f).setLookX(-2.0f).build();
            default:  return MD360Director.builder().setAngle(20).build();
        }
    }
}

Click Listener

Builder#gesture

@Override
protected MDVRLibrary createVRLibrary() {
    return MDVRLibrary.with(this)
            .....
            .listenGesture(new MDVRLibrary.IGestureListener() {
                @Override
                public void onClick(MotionEvent e) {
                    //....
                }
            })
            .build(R.id.surface_view);
}

Enable the pinch

Builder#pinchEnabled

@Override
protected MDVRLibrary createVRLibrary() {
    return MDVRLibrary.with(this)
            .....
            .pinchEnabled(true) //disable by default
            .build(R.id.surface_view);
}

Feature not support callback

add ifNotSupport to builder, e.g. VideoPlayerActivity#createVRLibrary

@Override
protected MDVRLibrary createVRLibrary() {
    return MDVRLibrary.with(this)
            .....
            .ifNotSupport(new MDVRLibrary.INotSupportCallback() {
                @Override
                public void onNotSupport(int mode) {
                    String tip = mode == MDVRLibrary.INTERACTIVE_MODE_MOTION
                            ? "onNotSupport:MOTION" : "onNotSupport:" + String.valueOf(mode);
                    Toast.makeText(VideoPlayerActivity.this, tip, Toast.LENGTH_SHORT).show();
                }
            })
            .build(R.id.surface_view);
}