package com.asha.vrlib.strategy.projection; import android.app.Activity; import android.graphics.RectF; import com.asha.vrlib.MD360Director; import com.asha.vrlib.MD360DirectorFactory; import com.asha.vrlib.MDVRLibrary; import com.asha.vrlib.common.MDDirection; import com.asha.vrlib.common.MDGLHandler; import com.asha.vrlib.model.MDDirectorBrief; import com.asha.vrlib.model.MDMainPluginBuilder; import com.asha.vrlib.model.MDPosition; import com.asha.vrlib.objects.MDAbsObject3D; import com.asha.vrlib.plugins.MDAbsPlugin; import com.asha.vrlib.plugins.MDPluginAdapter; import com.asha.vrlib.strategy.ModeManager; import java.util.LinkedList; import java.util.List; import static com.asha.vrlib.common.VRUtil.checkGLThread; /** * Created by hzqiujiadi on 16/6/25. * hzqiujiadi ashqalcn@gmail.com */ public class ProjectionModeManager extends ModeManager<AbsProjectionStrategy> implements IProjectionMode { public static int[] sModes = {MDVRLibrary.PROJECTION_MODE_SPHERE, MDVRLibrary.PROJECTION_MODE_DOME180, MDVRLibrary.PROJECTION_MODE_DOME230}; public static class Params{ public RectF textureSize; public MD360DirectorFactory directorFactory; public MDMainPluginBuilder mainPluginBuilder; public IMDProjectionFactory projectionFactory; } private RectF mTextureSize; private MD360DirectorFactory mCustomDirectorFactory; private MDAbsPlugin mMainPlugin; private MDMainPluginBuilder mMainPluginBuilder; private IMDProjectionFactory mProjectionFactory; private final List<MD360Director> mDirectors; private final MDDirectorBrief mDirectorBrief; private final MDAbsPlugin mDirectorUpdatePlugin; public ProjectionModeManager(int mode, MDGLHandler handler, Params projectionManagerParams) { super(mode, handler); this.mDirectors = new LinkedList<>(); this.mTextureSize = projectionManagerParams.textureSize; this.mCustomDirectorFactory = projectionManagerParams.directorFactory; this.mProjectionFactory = projectionManagerParams.projectionFactory; this.mMainPluginBuilder = projectionManagerParams.mainPluginBuilder; this.mMainPluginBuilder.setProjectionModeManager(this); this.mDirectorBrief = new MDDirectorBrief(); this.mDirectorUpdatePlugin = new MDPluginAdapter(){ @Override public void beforeRenderer(int totalWidth, int totalHeight) { if (mDirectors.size() > 0){ mDirectorBrief.make(mDirectors.get(0).getViewQuaternion()); } } }; } public MDAbsPlugin getMainPlugin() { if (mMainPlugin == null){ mMainPlugin = getStrategy().buildMainPlugin(mMainPluginBuilder); } return mMainPlugin; } @Override public void switchMode(Activity activity, int mode) { super.switchMode(activity, mode); } @Override public void on(Activity activity) { super.on(activity); // destroy prev main plugin if( mMainPlugin != null){ getGLHandler().post(new PluginDestroyTask(mMainPlugin)); mMainPlugin = null; } mDirectors.clear(); MD360DirectorFactory factory = getStrategy().hijackDirectorFactory(); factory = factory == null ? mCustomDirectorFactory : factory; for (int i = 0; i < MDVRLibrary.sMultiScreenSize; i++){ mDirectors.add(factory.createDirector(i)); } } @Override protected AbsProjectionStrategy createStrategy(int mode) { if (mProjectionFactory != null){ AbsProjectionStrategy strategy = mProjectionFactory.createStrategy(mode); if (strategy != null) return strategy; } switch (mode){ case MDVRLibrary.PROJECTION_MODE_DOME180: return new DomeProjection(this.mTextureSize,180f,false); case MDVRLibrary.PROJECTION_MODE_DOME230: return new DomeProjection(this.mTextureSize,230f,false); case MDVRLibrary.PROJECTION_MODE_DOME180_UPPER: return new DomeProjection(this.mTextureSize,180f,true); case MDVRLibrary.PROJECTION_MODE_DOME230_UPPER: return new DomeProjection(this.mTextureSize,230f,true); case MDVRLibrary.PROJECTION_MODE_STEREO_SPHERE_HORIZONTAL: return new StereoSphereProjection(MDDirection.HORIZONTAL); case MDVRLibrary.PROJECTION_MODE_STEREO_SPHERE: case MDVRLibrary.PROJECTION_MODE_STEREO_SPHERE_VERTICAL: return new StereoSphereProjection(MDDirection.VERTICAL); case MDVRLibrary.PROJECTION_MODE_PLANE_FIT: case MDVRLibrary.PROJECTION_MODE_PLANE_CROP: case MDVRLibrary.PROJECTION_MODE_PLANE_FULL: return PlaneProjection.create(mode,this.mTextureSize); case MDVRLibrary.PROJECTION_MODE_MULTI_FISH_EYE_HORIZONTAL: return new MultiFishEyeProjection(1f, MDDirection.HORIZONTAL); case MDVRLibrary.PROJECTION_MODE_MULTI_FISH_EYE_VERTICAL: return new MultiFishEyeProjection(1f, MDDirection.VERTICAL); case MDVRLibrary.PROJECTION_MODE_SPHERE: default: return new SphereProjection(); } } @Override protected int[] getModes() { return sModes; } @Override public MDPosition getModelPosition() { return getStrategy().getModelPosition(); } @Override public MDAbsObject3D getObject3D() { return getStrategy().getObject3D(); } public List<MD360Director> getDirectors() { return mDirectors; } public MDDirectorBrief getDirectorBrief() { return mDirectorBrief; } public MDAbsPlugin getDirectorUpdatePlugin() { return mDirectorUpdatePlugin; } private static class PluginDestroyTask implements Runnable { private MDAbsPlugin plugin; public PluginDestroyTask(MDAbsPlugin plugin) { this.plugin = plugin; } @Override public void run() { checkGLThread("must call in gl thread"); plugin.destroyInGL(); plugin = null; } } }