예제 #1
0
        /// <summary>
        /// Callback from the EasyAR component whic renders the foreground nodes.
        /// </summary>
        /// <param name="oFrame"></param>
        /// <param name="cameraParameters"></param>
        /// <param name="aspectRatio"></param>
        /// <param name="rotation"></param>
        protected void OnARFrameUpdated(OutputFrame oFrame, CameraParameters cameraParameters, float aspectRatio, int rotation)
        {
            var       far  = 100f;
            var       near = 0.01f;
            Matrix44F sp   = cameraParameters.projection(near, far, aspectRatio, rotation, true, false);

            foreach (Optional <FrameFilterResult> unTypedResult in oFrame.results())
            {
                if (unTypedResult.OnSome)
                {
                    if (unTypedResult.Some is ImageTrackerResult result)
                    {
                        int targetIndex = 0;
                        List <TargetInstance> targetInstances = result.targetInstances();
                        foreach (TargetInstance targetInstance in targetInstances)
                        {
                            TargetStatus status = targetInstance.status();
                            if (status == TargetStatus.Tracked)
                            {
                                Optional <Target> optionalTarget = targetInstance.target();
                                if (optionalTarget.OnSome)
                                {
                                    Target target = optionalTarget.Some;
                                    if (target is ImageTarget imageTarget)
                                    {
                                        List <Image> images      = imageTarget.images();
                                        Image        targetImage = images[0];

                                        Matrix4 prj = sp.ToUrhoMatrix();
                                        prj.M34 /= 2f;
                                        prj.M33  = far / (far - near);
                                        prj.M43 *= -1;
                                        fgCamera.SetProjection(prj);

                                        Matrix4 convertedPoseMatrix = targetInstance.pose().ToUrhoMatrix();
                                        Vector3 scale = new Vector3(imageTarget.scale(), imageTarget.scale() * targetImage.height() / targetImage.width(), 1);
                                        UpdateArScene(targetIndex, convertedPoseMatrix, scale);
                                        foreach (Image targetImageToRelease in images)
                                        {
                                            targetImageToRelease.Dispose();
                                        }
                                    }
                                    target.Dispose();
                                }
                            }
                            targetInstance.Dispose();
                            targetIndex++;
                        }

                        // Remove any targets that can no longer be located
                        while (targetNodes.Count > targetIndex)
                        {
                            Node node = targetNodes[targetIndex];
                            targetNodes.RemoveAt(targetIndex);
                            node.Remove();
                        }
                    }
                    unTypedResult.Some.Dispose();
                }
            }
        }
        /// <summary>
        /// Detects new output frames and updates the camera, then passes the output frame through an event to update the foreground
        /// </summary>
        /// <param name="timeStep"></param>
        protected override void OnUpdate(float timeStep)
        {
            if (paused)
            {
                return;
            }

            Optional <OutputFrame> optionalOframe = OutputFrameBuffer.peek();

            if (optionalOframe.OnSome)
            {
                OutputFrame           oframe         = optionalOframe.Some;
                Optional <InputFrame> optionalIframe = oframe.inputFrame();
                if (optionalIframe.OnSome)
                {
                    InputFrame       iframe           = optionalIframe.Some;
                    CameraParameters cameraParameters = iframe.cameraParameters();
                    if (cameraParameters != null)
                    {
                        Image image       = iframe.image();
                        float aspectRatio = (float)(DeviceDisplay.MainDisplayInfo.Width / DeviceDisplay.MainDisplayInfo.Height);

                        int rotation = 0;
                        switch (DeviceDisplay.MainDisplayInfo.Rotation)
                        {
                        case DisplayRotation.Rotation90:
                            rotation = 90;
                            break;

                        case DisplayRotation.Rotation180:
                            rotation = 180;
                            break;

                        case DisplayRotation.Rotation270:
                            rotation = 270;
                            break;
                        }

                        if (iframe.index() != previousInputFrameIndex)
                        {
                            Matrix44F ip   = cameraParameters.imageProjection(aspectRatio, rotation, true, false);
                            Matrix4   iprj = ip.ToUrhoMatrix();
                            bgCamera.SetProjection(iprj);
                            EasyAR.Buffer buffer = image.buffer();
                            try
                            {
                                backgroundUpdater.UpdateTexture(Application, image.format(), image.width(), image.height(), buffer);
                            }
                            finally
                            {
                                buffer.Dispose();
                            }
                            previousInputFrameIndex = iframe.index();
                        }

                        ARFrameUpdated?.Invoke(oframe, cameraParameters, aspectRatio, rotation);

                        image.Dispose();
                        cameraParameters.Dispose();
                    }
                    iframe.Dispose();
                }
                oframe.Dispose();
            }

            base.OnUpdate(timeStep);
        }