Example #1
0
        public unsafe void ProcessARFrame(ARSession session, ARFrame frame)
        {
            var arcamera  = frame?.Camera;
            var transform = arcamera.Transform;

            var   viewportSize = new CoreGraphics.CGSize(Application.Graphics.Width, Application.Graphics.Height);
            float near         = 0.001f;
            float far          = 1000f;
            var   prj          = arcamera.GetProjectionMatrix(Orientation.Value, viewportSize, near, far);
            var   dt           = frame.GetDisplayTransform(Orientation.Value, viewportSize);

            var urhoProjection = *(Matrix4 *)(void *)&prj;

            urhoProjection.M43 /= 2f;
            urhoProjection.M33  = far / (far - near);
            urhoProjection.M34 *= -1;
            //prj.M13 = 0; //center of projection
            //prj.M23 = 0;
            //urhoProjection.Row2 *= -1;
            urhoProjection.Transpose();

            Camera.SetProjection(urhoProjection);
            ApplyOpenTkTransform(Camera.Node, transform);

            if (!yuvTexturesInited)
            {
                var img = frame.CapturedImage;

                // texture for UV-plane;
                cameraUVtexture = new Texture2D();
                cameraUVtexture.SetNumLevels(1);
                cameraUVtexture.SetSize((int)img.GetWidthOfPlane(1), (int)img.GetHeightOfPlane(1), Graphics.LuminanceAlphaFormat, TextureUsage.Dynamic);
                cameraUVtexture.FilterMode = TextureFilterMode.Bilinear;
                cameraUVtexture.SetAddressMode(TextureCoordinate.U, TextureAddressMode.Clamp);
                cameraUVtexture.SetAddressMode(TextureCoordinate.V, TextureAddressMode.Clamp);
                cameraUVtexture.Name = nameof(cameraUVtexture);
                Application.ResourceCache.AddManualResource(cameraUVtexture);

                // texture for Y-plane;
                cameraYtexture = new Texture2D();
                cameraYtexture.SetNumLevels(1);
                cameraYtexture.FilterMode = TextureFilterMode.Bilinear;
                cameraYtexture.SetAddressMode(TextureCoordinate.U, TextureAddressMode.Clamp);
                cameraYtexture.SetAddressMode(TextureCoordinate.V, TextureAddressMode.Clamp);
                cameraYtexture.SetSize((int)img.Width, (int)img.Height, Graphics.LuminanceFormat, TextureUsage.Dynamic);
                cameraYtexture.Name = nameof(cameraYtexture);
                Application.ResourceCache.AddManualResource(cameraYtexture);

                var viewport = Application.Renderer.GetViewport(0);

                var videoRp = new RenderPathCommand(RenderCommandType.Quad);
                videoRp.PixelShaderName  = (UrhoString)ArkitShader;
                videoRp.VertexShaderName = (UrhoString)ArkitShader;
                videoRp.SetOutput(0, "viewport");
                videoRp.SetTextureName(TextureUnit.Diffuse, cameraYtexture.Name);                 //sDiffMap
                videoRp.SetTextureName(TextureUnit.Normal, cameraUVtexture.Name);                 //sNormalMap

                if (Orientation != UIInterfaceOrientation.Portrait)
                {
                    videoRp.PixelShaderDefines = new UrhoString("ARKIT_LANDSCAPE");
                }

                viewport.RenderPath.InsertCommand(1, videoRp);

                var vrp = viewport.RenderPath.GetCommand(1);
                vrp->SetShaderParameter("Tx", (float)dt.x0);
                vrp->SetShaderParameter("Ty", (float)dt.y0);
                vrp->SetShaderParameter("ScaleX", (float)dt.xx);
                vrp->SetShaderParameter("ScaleY", (float)dt.yy);
                vrp->SetShaderParameter("ScaleYX", (float)dt.yx);
                vrp->SetShaderParameter("ScaleXY", (float)dt.xy);

                float imageAspect = (float)img.Width / img.Height;

                float yoffset;
                if (ARConfiguration is ARFaceTrackingConfiguration)
                {
                    yoffset = 0.013f;
                }
                else
                {
                    yoffset = 64.0f / Math.Max(img.Width, img.Height);
                }
                vrp->SetShaderParameter("YOffset", yoffset);

                yuvTexturesInited = true;
            }

            if (yuvTexturesInited)
            {
                UpdateBackground(frame);
            }

            ARFrame?.Invoke(frame);

            // required!
            frame.Dispose();
        }