SetupIntrinsic() private method

Pass the camera intrinsics to both PostProcess and ARScreen shader. The camera intrinsics are needed for undistortion or distortion.
private SetupIntrinsic ( TangoCameraIntrinsics intrinsics ) : void
intrinsics Tango.TangoCameraIntrinsics Color camera intrinsics.
return void
 /// <summary>
 /// Update AR screen material with camera texture size data
 /// (and distortion parameters if using distortion post-process filter).
 /// </summary>
 /// <param name="mat">Material to update.</param>
 /// <param name="arPostProcess">ARCameraPostProcess script that handles distortion for this material instance
 /// (null if none).</param>
 /// <param name="intrinsics">Tango camera intrinsics for the color camera.</param>
 private static void _MaterialUpdateForIntrinsics(Material mat, ARCameraPostProcess arPostProcess, TangoCameraIntrinsics intrinsics)
 {
     if (arPostProcess != null)
     {
         // ARCameraPostProcess should take care of setting everything up for all materials involved.
         arPostProcess.SetupIntrinsic(intrinsics, mat);
     }
     else
     {
         // If not handling distortion, all the material needs to know is camera image dimensions.
         mat.SetFloat("_Width", (float)intrinsics.width);
         mat.SetFloat("_Height", (float)intrinsics.height);
     }
 }
Esempio n. 2
0
    /// <summary>
    /// This is called when succesfully connected to the Tango service.
    /// </summary>
    public void OnTangoServiceConnected()
    {
        // Set up the size of ARScreen based on camera intrinsics.
        TangoCameraIntrinsics intrinsics = new TangoCameraIntrinsics();

        VideoOverlayProvider.GetIntrinsics(TangoEnums.TangoCameraId.TANGO_CAMERA_COLOR, intrinsics);

        if (intrinsics.width != 0 && intrinsics.height != 0)
        {
            m_arCameraPostProcess.SetupIntrinsic(intrinsics);
            Camera.main.projectionMatrix = ProjectionMatrixForCameraIntrinsics((float)intrinsics.width,
                                                                               (float)intrinsics.height,
                                                                               (float)intrinsics.fx,
                                                                               (float)intrinsics.fy,
                                                                               (float)intrinsics.cx,
                                                                               (float)intrinsics.cy,
                                                                               0.1f,
                                                                               1000.0f);

            // Here we are scaling the image plane to make sure the image plane's ratio is set as the
            // color camera image ratio.
            // If we don't do this, because we are drawing the texture fullscreen, the image plane will
            // be set to the screen's ratio.
            float widthRatio  = (float)Screen.width / (float)intrinsics.width;
            float heightRatio = (float)Screen.height / (float)intrinsics.height;
            if (widthRatio >= heightRatio)
            {
                float normalizedOffset = ((widthRatio / heightRatio) - 1.0f) / 2.0f;
                _SetScreenVertices(0, normalizedOffset);
            }
            else
            {
                float normalizedOffset = ((heightRatio / widthRatio) - 1.0f) / 2.0f;
                _SetScreenVertices(normalizedOffset, 0);
            }
        }
        else
        {
            m_arCameraPostProcess.enabled = false;
        }
    }
Esempio n. 3
0
    /// <summary>
    /// This is called when succesfully connected to the Tango service.
    /// </summary>
    public void OnTangoServiceConnected()
    {
        // Set up the size of ARScreen based on camera intrinsics.
        TangoCameraIntrinsics intrinsics = new TangoCameraIntrinsics();

        VideoOverlayProvider.GetIntrinsics(TangoEnums.TangoCameraId.TANGO_CAMERA_COLOR, intrinsics);

        if (intrinsics.width != 0 && intrinsics.height != 0)
        {
            Camera camera = GetComponent <Camera>();
            if (camera != null)
            {
                // If this script is attached to a camera, then the camera is an Augmented Reality camera.  The color
                // camera image then must fill the viewport.  That means we must clip the color camera image to make
                // its ratio the same as the Unity camera.  If we don't do this the color camera image will be
                // stretched non-uniformly, making a circle into an ellipse.
                float widthRatio  = (float)camera.pixelWidth / (float)intrinsics.width;
                float heightRatio = (float)camera.pixelHeight / (float)intrinsics.height;
                if (widthRatio >= heightRatio)
                {
                    m_uOffset = 0;
                    m_vOffset = (1 - (heightRatio / widthRatio)) / 2;
                }
                else
                {
                    m_uOffset = (1 - (widthRatio / heightRatio)) / 2;
                    m_vOffset = 0;
                }

                m_arCameraPostProcess.SetupIntrinsic(intrinsics);
                _MeshUpdateForIntrinsics(GetComponent <MeshFilter>().mesh, m_uOffset, m_vOffset);
                _CameraUpdateForIntrinsics(camera, intrinsics, m_uOffset, m_vOffset);
            }
        }
        else
        {
            m_uOffset = 0;
            m_vOffset = 0;
            m_arCameraPostProcess.enabled = false;
        }
    }
Esempio n. 4
0
    /// <summary>
    /// Update AR screen rendering and attached Camera's projection matrix.
    /// </summary>
    /// <param name="displayRotation">Activity (screen) rotation.</param>
    /// <param name="colorCameraRotation">Color camera sensor rotation.</param>
    private void _SetRenderAndCamera(OrientationManager.Rotation displayRotation,
                                     OrientationManager.Rotation colorCameraRotation)
    {
        float cameraWidth  = (float)Screen.width;
        float cameraHeight = (float)Screen.height;

        #pragma warning disable 0219
        // Here we are computing if current display orientation is landscape or portrait.
        // AndroidHelper.GetAndroidDefaultOrientation() returns 1 if device default orientation is in portrait,
        // returns 2 if device default orientation is landscape. Adding device default orientation with
        // how much the display is rotated from default orientation will get us the result of current display
        // orientation. (landscape vs. portrait)
        bool  isLandscape           = (AndroidHelper.GetDefaultOrientation() + (int)displayRotation) % 2 == 0;
        bool  needToFlipCameraRatio = false;
        float cameraRatio           = (float)Screen.width / (float)Screen.height;
        #pragma warning restore 0219

#if !UNITY_EDITOR
        // In most cases, we don't need to flip the camera width and height. However, in some cases Unity camera
        // only updates a couple of frames after the display changed callback from Android; thus, we need to flip the width
        // and height in this case.
        //
        // This does not happen in the editor, because the emulated device does not ever rotate.
        needToFlipCameraRatio = (!isLandscape & (cameraRatio > 1.0f)) || (isLandscape & (cameraRatio < 1.0f));

        if (needToFlipCameraRatio)
        {
            cameraRatio = 1.0f / cameraRatio;
            float tmp = cameraWidth;
            cameraWidth  = cameraHeight;
            cameraHeight = tmp;
        }
#endif

        TangoCameraIntrinsics alignedIntrinsics = new TangoCameraIntrinsics();
        TangoCameraIntrinsics intrinsics        = new TangoCameraIntrinsics();
        VideoOverlayProvider.GetDeviceOrientationAlignedIntrinsics(TangoEnums.TangoCameraId.TANGO_CAMERA_COLOR,
                                                                   alignedIntrinsics);
        VideoOverlayProvider.GetIntrinsics(TangoEnums.TangoCameraId.TANGO_CAMERA_COLOR,
                                           intrinsics);

        if (alignedIntrinsics.width != 0 && alignedIntrinsics.height != 0)
        {
            // The camera to which this script is attached is an Augmented Reality camera.  The color camera
            // image must fill that camera's viewport.  That means we must clip the color camera image to make
            // its ratio the same as the Unity camera.  If we don't do this the color camera image will be
            // stretched non-uniformly, making a circle into an ellipse.
            float widthRatio  = (float)cameraWidth / (float)alignedIntrinsics.width;
            float heightRatio = (float)cameraHeight / (float)alignedIntrinsics.height;

            if (widthRatio >= heightRatio)
            {
                m_uOffset = 0;
                m_vOffset = (1 - (heightRatio / widthRatio)) / 2;
            }
            else
            {
                m_uOffset = (1 - (widthRatio / heightRatio)) / 2;
                m_vOffset = 0;
            }

            // Note that here we are passing in non-inverted intrinsics, because the YUV conversion is still operating
            // on native buffer layout.
            OrientationManager.Rotation rotation = TangoSupport.RotateFromAToB(displayRotation, colorCameraRotation);
            _MaterialUpdateForIntrinsics(m_uOffset, m_vOffset, rotation);
            _CameraUpdateForIntrinsics(m_camera, alignedIntrinsics, m_uOffset, m_vOffset);
            if (m_arCameraPostProcess != null)
            {
                m_arCameraPostProcess.SetupIntrinsic(intrinsics);
            }
        }
        else
        {
            Debug.LogError("AR Camera intrinsic is not valid.");
        }
    }