private void UpdateFieldOfView(FieldOfView leftEyeFov, FieldOfView rightEyeFov) { CardboardDeviceParams cdp = mHmd.getCardboard(); ScreenParams screen = mHmd.getScreen(); Distortion distortion = cdp.getDistortion(); float idealFovAngle = (float)Math.ToDegrees(Math.Atan2(cdp.getLensDiameter() / 2.0F, cdp.getEyeToLensDistance())); float eyeToScreenDist = cdp.getEyeToLensDistance() + cdp.getScreenToLensDistance(); float outerDist = (screen.getWidthMeters() - cdp.getInterpupillaryDistance()) / 2.0F; float innerDist = cdp.getInterpupillaryDistance() / 2.0F; float bottomDist = cdp.getVerticalDistanceToLensCenter() - screen.getBorderSizeMeters(); float topDist = screen.getHeightMeters() + screen.getBorderSizeMeters() - cdp.getVerticalDistanceToLensCenter(); float outerAngle = (float)Math.ToDegrees(Math.Atan2(distortion.distort(outerDist), eyeToScreenDist)); float innerAngle = (float)Math.ToDegrees(Math.Atan2(distortion.distort(innerDist), eyeToScreenDist)); float bottomAngle = (float)Math.ToDegrees(Math.Atan2(distortion.distort(bottomDist), eyeToScreenDist)); float topAngle = (float)Math.ToDegrees(Math.Atan2(distortion.distort(topDist), eyeToScreenDist)); leftEyeFov.setLeft(Math.Min(outerAngle, idealFovAngle)); leftEyeFov.setRight(Math.Min(innerAngle, idealFovAngle)); leftEyeFov.setBottom(Math.Min(bottomAngle, idealFovAngle)); leftEyeFov.setTop(Math.Min(topAngle, idealFovAngle)); rightEyeFov.setLeft(Math.Min(innerAngle, idealFovAngle)); rightEyeFov.setRight(Math.Min(outerAngle, idealFovAngle)); rightEyeFov.setBottom(Math.Min(bottomAngle, idealFovAngle)); rightEyeFov.setTop(Math.Min(topAngle, idealFovAngle)); }
private EyeViewport initViewportForEye(EyeParams eye, float xOffsetM) { ScreenParams screen = mHmd.getScreen(); CardboardDeviceParams cdp = mHmd.getCardboard(); float eyeToScreenDistanceM = cdp.getEyeToLensDistance() + cdp.getScreenToLensDistance(); float leftM = (float)Math.Tan(Math.ToRadians(eye.getFov().getLeft())) * eyeToScreenDistanceM; float rightM = (float)Math.Tan(Math.ToRadians(eye.getFov().getRight())) * eyeToScreenDistanceM; float bottomM = (float)Math.Tan(Math.ToRadians(eye.getFov().getBottom())) * eyeToScreenDistanceM; float topM = (float)Math.Tan(Math.ToRadians(eye.getFov().getTop())) * eyeToScreenDistanceM; EyeViewport vp = new EyeViewport(); vp.x = xOffsetM; vp.y = 0.0F; vp.width = (leftM + rightM); vp.height = (bottomM + topM); vp.eyeX = (leftM + xOffsetM); vp.eyeY = bottomM; float xPxPerM = screen.getWidth() / screen.getWidthMeters(); float yPxPerM = screen.getHeight() / screen.getHeightMeters(); eye.getViewport().x = Math.Round(vp.x * xPxPerM); eye.getViewport().y = Math.Round(vp.y * xPxPerM); eye.getViewport().width = Math.Round(vp.width * xPxPerM); eye.getViewport().height = Math.Round(vp.height * xPxPerM); return(vp); }
public void OnSurfaceChanged(IGL10 gl, int width, int height) { if (mShuttingDown) { return; } ScreenParams screen = mHmd.getScreen(); if ((width != screen.getWidth()) || (height != screen.getHeight())) { if (!mInvalidSurfaceSize) { GLES20.GlClear(GLES20.GlColorBufferBit); Android.Util.Log.Warn("CardboardView", "Surface size " + width + "x" + height + " does not match the expected screen size " + screen.getWidth() + "x" + screen.getHeight() + ". Rendering is disabled."); } mInvalidSurfaceSize = true; } else { mInvalidSurfaceSize = false; } mRenderer.OnSurfaceChanged(width, height); }
public ScreenParams(ScreenParams param) { mWidth = param.mWidth; mHeight = param.mHeight; mXMetersPerPixel = param.mXMetersPerPixel; mYMetersPerPixel = param.mYMetersPerPixel; mBorderSizeMeters = param.mBorderSizeMeters; }
public void SetScreenParams(ScreenParams newParams) { ScreenParams screenParams = new ScreenParams(newParams); mView.QueueEvent(() => { mHmd.setScreen(screenParams); mProjectionChanged = true; }); }
public void UpdateScreenParams(ScreenParams screenParams) { if ((screenParams == null) || (screenParams.equals(mHmd.getScreen()))) { return; } mHmd.setScreen(screenParams); if (mRendererHelper != null) { mRendererHelper.SetScreenParams(screenParams); } }
public bool equals(Object other) { if (other == null) { return(false); } if (other == this) { return(true); } if (!(other is ScreenParams)) { return(false); } ScreenParams o = (ScreenParams)other; return((mWidth == o.mWidth) && (mHeight == o.mHeight) && (mXMetersPerPixel == o.mXMetersPerPixel) && (mYMetersPerPixel == o.mYMetersPerPixel) && (mBorderSizeMeters == o.mBorderSizeMeters)); }
public void onProjectionChanged(HeadMountedDisplay hmd, EyeParams leftEye, EyeParams rightEye, float zNear, float zFar) { mHmd = new HeadMountedDisplay(hmd); mLeftEyeFov = new FieldOfView(leftEye.getFov()); mRightEyeFov = new FieldOfView(rightEye.getFov()); ScreenParams screen = mHmd.getScreen(); CardboardDeviceParams cdp = mHmd.getCardboard(); if (mProgramHolder == null) { mProgramHolder = createProgramHolder(); } EyeViewport leftEyeViewport = initViewportForEye(leftEye, 0.0F); EyeViewport rightEyeViewport = initViewportForEye(rightEye, leftEyeViewport.width); leftEye.getFov().toPerspectiveMatrix(zNear, zFar, leftEye.getTransform().GetPerspective(), 0); rightEye.getFov().toPerspectiveMatrix(zNear, zFar, rightEye.getTransform().GetPerspective(), 0); float textureWidthM = leftEyeViewport.width + rightEyeViewport.width; float textureHeightM = Math.Max(leftEyeViewport.height, rightEyeViewport.height); float xPxPerM = screen.getWidth() / screen.getWidthMeters(); float yPxPerM = screen.getHeight() / screen.getHeightMeters(); int textureWidthPx = Math.Round(textureWidthM * xPxPerM); int textureHeightPx = Math.Round(textureHeightM * yPxPerM); float xEyeOffsetMScreen = screen.getWidthMeters() / 2.0F - cdp.getInterpupillaryDistance() / 2.0F; float yEyeOffsetMScreen = cdp.getVerticalDistanceToLensCenter() - screen.getBorderSizeMeters(); mLeftEyeDistortionMesh = createDistortionMesh(leftEye, leftEyeViewport, textureWidthM, textureHeightM, xEyeOffsetMScreen, yEyeOffsetMScreen); xEyeOffsetMScreen = screen.getWidthMeters() - xEyeOffsetMScreen; mRightEyeDistortionMesh = createDistortionMesh(rightEye, rightEyeViewport, textureWidthM, textureHeightM, xEyeOffsetMScreen, yEyeOffsetMScreen); setupRenderTextureAndRenderbuffer(textureWidthPx, textureHeightPx); }
public void OnDrawFrame(IGL10 gl) { if ((mShuttingDown) || (mInvalidSurfaceSize)) { return; } ScreenParams screen = mHmd.getScreen(); CardboardDeviceParams cdp = mHmd.getCardboard(); mView.mHeadTracker.getLastHeadView(mHeadTransform.getHeadView(), 0); float halfInterpupillaryDistance = cdp.getInterpupillaryDistance() * 0.5F; if (mVRMode) { Android.Opengl.Matrix.SetIdentityM(mLeftEyeTranslate, 0); Android.Opengl.Matrix.SetIdentityM(mRightEyeTranslate, 0); Android.Opengl.Matrix.TranslateM(mLeftEyeTranslate, 0, halfInterpupillaryDistance, 0.0F, 0.0F); Android.Opengl.Matrix.TranslateM(mRightEyeTranslate, 0, -halfInterpupillaryDistance, 0.0F, 0.0F); Android.Opengl.Matrix.MultiplyMM(mLeftEye.getTransform().GetEyeView(), 0, mLeftEyeTranslate, 0, mHeadTransform.getHeadView(), 0); Android.Opengl.Matrix.MultiplyMM(mRightEye.getTransform().GetEyeView(), 0, mRightEyeTranslate, 0, mHeadTransform.getHeadView(), 0); } else { //Java.Lang.JavaSystem.Arraycopy(mHeadTransform.getHeadView(), 0, mMonocular.getTransform().GetEyeView(), 0, mHeadTransform.getHeadView().Length); Array.Copy(mHeadTransform.getHeadView(), 0, mMonocular.getTransform().GetEyeView(), 0, mHeadTransform.getHeadView().Length); } if (mProjectionChanged) { mMonocular.getViewport().setViewport(0, 0, screen.getWidth(), screen.getHeight()); if (!mVRMode) { float aspectRatio = screen.getWidth() / screen.getHeight(); Android.Opengl.Matrix.PerspectiveM(mMonocular.getTransform().GetPerspective(), 0, cdp.getFovY(), aspectRatio, mZNear, mZFar); } else if (mDistortionCorrectionEnabled) { UpdateFieldOfView(mLeftEye.getFov(), mRightEye.getFov()); mView.mDistortionRenderer.onProjectionChanged(mHmd, mLeftEye, mRightEye, mZNear, mZFar); } else { float distEyeToScreen = cdp.getVisibleViewportSize() / 2.0F / (float)Math.Tan(Math.ToRadians(cdp.getFovY()) / 2.0D); float left = screen.getWidthMeters() / 2.0F - halfInterpupillaryDistance; float right = halfInterpupillaryDistance; float bottom = cdp.getVerticalDistanceToLensCenter() - screen.getBorderSizeMeters(); float top = screen.getBorderSizeMeters() + screen.getHeightMeters() - cdp.getVerticalDistanceToLensCenter(); FieldOfView leftEyeFov = mLeftEye.getFov(); leftEyeFov.setLeft((float)Math.ToDegrees(Math.Atan2(left, distEyeToScreen))); leftEyeFov.setRight((float)Math.ToDegrees(Math.Atan2(right, distEyeToScreen))); leftEyeFov.setBottom((float)Math.ToDegrees(Math.Atan2(bottom, distEyeToScreen))); leftEyeFov.setTop((float)Math.ToDegrees(Math.Atan2(top, distEyeToScreen))); FieldOfView rightEyeFov = mRightEye.getFov(); rightEyeFov.setLeft(leftEyeFov.getRight()); rightEyeFov.setRight(leftEyeFov.getLeft()); rightEyeFov.setBottom(leftEyeFov.getBottom()); rightEyeFov.setTop(leftEyeFov.getTop()); leftEyeFov.toPerspectiveMatrix(mZNear, mZFar, mLeftEye.getTransform().GetPerspective(), 0); rightEyeFov.toPerspectiveMatrix(mZNear, mZFar, mRightEye.getTransform().GetPerspective(), 0); mLeftEye.getViewport().setViewport(0, 0, screen.getWidth() / 2, screen.getHeight()); mRightEye.getViewport().setViewport(screen.getWidth() / 2, 0, screen.getWidth() / 2, screen.getHeight()); } mProjectionChanged = false; } if (mVRMode) { if (mDistortionCorrectionEnabled) { mView.mDistortionRenderer.beforeDrawFrame(); if (mDistortionCorrectionScale == 1.0F) { mRenderer.OnDrawFrame(mHeadTransform, mLeftEye, mRightEye); } else { int leftX = mLeftEye.getViewport().x; int leftY = mLeftEye.getViewport().y; int leftWidth = mLeftEye.getViewport().width; int leftHeight = mLeftEye.getViewport().height; int rightX = mRightEye.getViewport().x; int rightY = mRightEye.getViewport().y; int rightWidth = mRightEye.getViewport().width; int rightHeight = mRightEye.getViewport().height; mLeftEye.getViewport().setViewport((int)(leftX * mDistortionCorrectionScale), (int)(leftY * mDistortionCorrectionScale), (int)(leftWidth * mDistortionCorrectionScale), (int)(leftHeight * mDistortionCorrectionScale)); mRightEye.getViewport().setViewport((int)(rightX * mDistortionCorrectionScale), (int)(rightY * mDistortionCorrectionScale), (int)(rightWidth * mDistortionCorrectionScale), (int)(rightHeight * mDistortionCorrectionScale)); mRenderer.OnDrawFrame(mHeadTransform, mLeftEye, mRightEye); mLeftEye.getViewport().setViewport(leftX, leftY, leftWidth, leftHeight); mRightEye.getViewport().setViewport(rightX, rightY, rightWidth, rightHeight); } mView.mDistortionRenderer.afterDrawFrame(); } else { mRenderer.OnDrawFrame(mHeadTransform, mLeftEye, mRightEye); } } else { mRenderer.OnDrawFrame(mHeadTransform, mMonocular, null); } mRenderer.OnFinishFrame(mMonocular.getViewport()); }
public void setScreen(ScreenParams screen) { mScreen = new ScreenParams(screen); }
public HeadMountedDisplay(HeadMountedDisplay hmd) { mScreen = new ScreenParams(hmd.mScreen); mCardboard = new CardboardDeviceParams(hmd.mCardboard); }
public HeadMountedDisplay(Display display) { mScreen = new ScreenParams(display); mCardboard = new CardboardDeviceParams(); }