예제 #1
0
        private void OnFrameUpdate(OutputFrame outputFrame, InputFrame inputFrame, Matrix4x4 displayCompensation)
        {
            // world root
            if (Assembly.RequireWorldCenter && !WorldRootController)
            {
                Debug.Log("WorldRoot not found, create from " + typeof(ARSession));
                var gameObject = new GameObject("WorldRoot");
                WorldRootController = gameObject.AddComponent <WorldRootController>();
                if (WorldRootChanged != null)
                {
                    WorldRootChanged(WorldRootController);
                }
                previousWorldRootController = WorldRootController;
            }
            if (!Assembly.RequireWorldCenter && CenterMode == ARCenterMode.WorldRoot)
            {
                Debug.LogWarning("ARCenterMode.WorldRoot not available for target only tracking");
                CenterMode = ARCenterMode.FirstTarget;
            }

            // horizontal flip
            var hflip = HorizontalFlipNormal;

            using (var cameraParameters = inputFrame.cameraParameters())
            {
                if (cameraParameters.cameraDeviceType() == CameraDeviceType.Front)
                {
                    hflip = HorizontalFlipFront;
                }
            }
            var worldHFlip  = false;
            var targetHFlip = false;

            switch (hflip)
            {
            case ARHorizontalFlipMode.World:
                worldHFlip  = true;
                targetHFlip = false;
                break;

            case ARHorizontalFlipMode.Target:
                worldHFlip  = false;
                targetHFlip = true;
                break;

            default:
                break;
            }
            foreach (var renderCamera in Assembly.RenderCameras)
            {
                renderCamera.SetProjectHFlip(worldHFlip);
                renderCamera.SetRenderImageHFilp(worldHFlip || targetHFlip);
            }
            foreach (var filter in Assembly.FrameFilters)
            {
                filter.SetHFlip(targetHFlip);
            }

            // dispatch results
            var results = outputFrame.results();
            var motionTrackingStatus = Optional <MotionTrackingStatus> .CreateNone();

            if (inputFrame.hasSpatialInformation())
            {
                motionTrackingStatus = inputFrame.trackingStatus();
            }
            var resultControllers = DispatchResults(results, motionTrackingStatus);

            // get camera pose if available
            var cameraPose = Optional <Matrix44F> .Empty;

            if (Assembly.RequireWorldCenter)
            {
                if (motionTrackingStatus.OnSome)
                {
                    if (motionTrackingStatus.Value != MotionTrackingStatus.NotTracking)
                    {
                        cameraPose = inputFrame.cameraTransform();
                    }
                }
                else
                {
                    foreach (var result in resultControllers)
                    {
                        if (result.Key.OnNone)
                        {
                            cameraPose = result.Value;
                            break;
                        }
                    }
                }
            }

            // get center target pose if available
            var centerTargetPose = Optional <Matrix44F> .Empty;

            if (CenterMode == ARCenterMode.FirstTarget || CenterMode == ARCenterMode.SpecificTarget)
            {
                foreach (var result in resultControllers)
                {
                    if (!CenterTarget)
                    {
                        break;
                    }
                    if (result.Key.OnNone)
                    {
                        continue;
                    }
                    if (result.Key == CenterTarget)
                    {
                        centerTargetPose = result.Value;
                        break;
                    }
                }

                if (CenterMode == ARCenterMode.FirstTarget && centerTargetPose.OnNone)
                {
                    foreach (var result in resultControllers)
                    {
                        if (result.Key.OnNone)
                        {
                            continue;
                        }
                        CenterTarget     = result.Key.Value;
                        centerTargetPose = result.Value;
                        break;
                    }
                }
            }
            else
            {
                CenterTarget = null;
            }

            // set camera transform first
            if (CenterMode == ARCenterMode.FirstTarget || CenterMode == ARCenterMode.SpecificTarget)
            {
                if (CenterTarget && centerTargetPose.OnSome)
                {
                    TransformUtil.SetTargetPoseOnCamera(Assembly.CameraRoot, CenterTarget, centerTargetPose.Value, displayCompensation, targetHFlip);
                }
            }
            else if (CenterMode == ARCenterMode.WorldRoot)
            {
                if (WorldRootController && cameraPose.OnSome)
                {
                    TransformUtil.SetCameraPoseOnCamera(Assembly.CameraRoot, WorldRootController, cameraPose.Value, displayCompensation, targetHFlip);
                }
            }

            // set target and world root transform
            if (CenterMode == ARCenterMode.Camera)
            {
                foreach (var result in resultControllers)
                {
                    if (result.Key.OnSome)
                    {
                        TransformUtil.SetTargetPoseOnTarget(Assembly.CameraRoot, result.Key.Value, result.Value, displayCompensation, targetHFlip);
                    }
                }
                if (WorldRootController && cameraPose.OnSome)
                {
                    TransformUtil.SetCameraPoseOnWorldRoot(Assembly.CameraRoot, WorldRootController, cameraPose.Value, displayCompensation, targetHFlip);
                }
            }
            else if (CenterMode == ARCenterMode.WorldRoot)
            {
                foreach (var result in resultControllers)
                {
                    if (result.Key.OnSome)
                    {
                        TransformUtil.SetTargetPoseOnTarget(Assembly.CameraRoot, result.Key.Value, result.Value, displayCompensation, targetHFlip);
                    }
                }
            }
            else if (CenterMode == ARCenterMode.FirstTarget || CenterMode == ARCenterMode.SpecificTarget)
            {
                foreach (var result in resultControllers)
                {
                    if (result.Key.OnSome && result.Key.Value != CenterTarget)
                    {
                        TransformUtil.SetTargetPoseOnTarget(Assembly.CameraRoot, result.Key.Value, result.Value, displayCompensation, targetHFlip);
                    }
                }
                if (WorldRootController && cameraPose.OnSome)
                {
                    TransformUtil.SetCameraPoseOnWorldRoot(Assembly.CameraRoot, WorldRootController, cameraPose.Value, displayCompensation, targetHFlip);
                }
            }
            else if (CenterMode == ARCenterMode.ExternalControl)
            {
                foreach (var result in resultControllers)
                {
                    if (result.Key.OnSome)
                    {
                        TransformUtil.SetTargetPoseOnTarget(Assembly.CameraRoot, result.Key.Value, result.Value, displayCompensation, targetHFlip);
                    }
                }
            }

            // dispose results
            foreach (var result in results)
            {
                if (result.OnSome)
                {
                    result.Value.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);
        }