package com.asha.vrlib.strategy.projection; import android.app.Activity; import android.graphics.RectF; import android.opengl.Matrix; import com.asha.vrlib.MD360Director; import com.asha.vrlib.MD360DirectorFactory; import com.asha.vrlib.MDVRLibrary; import com.asha.vrlib.model.MDMainPluginBuilder; import com.asha.vrlib.model.MDPosition; import com.asha.vrlib.objects.MDAbsObject3D; import com.asha.vrlib.objects.MDObject3DHelper; import com.asha.vrlib.objects.MDPlane; import com.asha.vrlib.plugins.MDAbsPlugin; import com.asha.vrlib.plugins.MDPanoramaPlugin; /** * Created by hzqiujiadi on 16/6/26. * hzqiujiadi ashqalcn@gmail.com */ public class PlaneProjection extends AbsProjectionStrategy { private MDPlane object3D; private PlaneScaleCalculator planeScaleCalculator; private static final MDPosition position = MDPosition.newInstance().setZ(-2f); private PlaneProjection(PlaneScaleCalculator calculator) { planeScaleCalculator = calculator; } @Override public void turnOnInGL(Activity activity) { object3D = new MDPlane(planeScaleCalculator); MDObject3DHelper.loadObj(activity, object3D); } @Override public void turnOffInGL(Activity activity) { } @Override public boolean isSupport(Activity activity) { return true; } @Override public MDAbsObject3D getObject3D() { return object3D; } @Override public MDPosition getModelPosition() { return position; } @Override public MDAbsPlugin buildMainPlugin(MDMainPluginBuilder builder) { return new MDPanoramaPlugin(builder); } @Override protected MD360DirectorFactory hijackDirectorFactory() { return new OrthogonalDirectorFactory(); } public static PlaneProjection create(int scaleType, RectF textureSize){ return new PlaneProjection(new PlaneScaleCalculator(scaleType,textureSize)); } public static class PlaneScaleCalculator{ private static final float sBaseValue = 1.0f; private RectF mTextureSize; private float mViewportRatio; private int mScaleType; private float mViewportWidth = sBaseValue; private float mViewportHeight = sBaseValue; private float mTextureWidth = sBaseValue; private float mTextureHeight = sBaseValue; public PlaneScaleCalculator(int scaleType, RectF textureSize) { this.mScaleType = scaleType; this.mTextureSize = textureSize; } public float getTextureRatio(){ return mTextureSize.width() / mTextureSize.height(); } public void setViewportRatio(float viewportRatio){ this.mViewportRatio = viewportRatio; } public void calculate(){ float viewportRatio = mViewportRatio; float textureRatio = getTextureRatio(); switch (this.mScaleType){ case MDVRLibrary.PROJECTION_MODE_PLANE_FULL: // fullscreen mViewportWidth = mViewportHeight = mTextureWidth = mTextureHeight = sBaseValue; break; case MDVRLibrary.PROJECTION_MODE_PLANE_CROP: if (textureRatio > viewportRatio){ /** * crop width of texture * * texture * ---------------------- * | | | | * | | viewport | | * | | | | * ---------------------- * */ mViewportWidth = sBaseValue * viewportRatio; mViewportHeight = sBaseValue; mTextureWidth = sBaseValue * textureRatio; mTextureHeight = sBaseValue; } else { /** * crop height of texture * * texture * ----------------------- * |---------------------| * | | * | viewport | * | | * |---------------------| * ----------------------- * */ mViewportWidth = sBaseValue; mViewportHeight = sBaseValue / viewportRatio; mTextureWidth = sBaseValue; mTextureHeight = sBaseValue / textureRatio; } break; case MDVRLibrary.PROJECTION_MODE_PLANE_FIT: default: if (viewportRatio > textureRatio){ /** * fit height of viewport * * viewport * --------------------- * | | | | * | | texture | | * | | | | * --------------------- * */ mViewportWidth = sBaseValue * viewportRatio ; mViewportHeight = sBaseValue; mTextureWidth = sBaseValue * textureRatio; mTextureHeight = sBaseValue; } else { /** * fit width of viewport * * viewport * ----------------------- * |---------------------| * | | * | texture | * | | * |---------------------| * ----------------------- * */ mViewportWidth = sBaseValue; mViewportHeight = sBaseValue / viewportRatio; mTextureWidth = sBaseValue; mTextureHeight = sBaseValue / textureRatio; } break; } } public float getViewportWidth(){ return mViewportWidth; } public float getViewportHeight(){ return mViewportHeight; } public float getTextureWidth(){ return mTextureWidth; } public float getTextureHeight(){ return mTextureHeight; } } private class OrthogonalDirectorFactory extends MD360DirectorFactory{ @Override public MD360Director createDirector(int index) { return new OrthogonalDirector(new MD360Director.Builder()); } } private class OrthogonalDirector extends MD360Director{ private OrthogonalDirector(Builder builder) { super(builder); } @Override public void setDeltaX(float mDeltaX) { // nop } @Override public void setDeltaY(float mDeltaY) { // nop } @Override public void updateSensorMatrix(float[] sensorMatrix) { // nop } @Override protected void updateProjection(){ planeScaleCalculator.setViewportRatio(getRatio()); planeScaleCalculator.calculate(); final float left = - planeScaleCalculator.getViewportWidth()/2; final float right = planeScaleCalculator.getViewportWidth()/2; final float bottom = - planeScaleCalculator.getViewportHeight()/2; final float top = planeScaleCalculator.getViewportHeight()/2; final float far = 500; Matrix.orthoM(getProjectionMatrix(), 0, left, right, bottom, top, getNear(), far); } } }