예제 #1
0
 internal void Init()
 {
     _vrPointer            = Resources.FindObjectsOfTypeAll <VRPointer>().First();
     _triggerTime          = 0;
     _vrControllerTriggerd = false;
     _state = CalState.WebCamPosition;
     if (_vrPointer == null)
     {
         Logger.log.Error($"VRController Null");
     }
 }
        public CalibrationAdjusterAutoForm(CalibrationAdjuster caladjust, MouseController mc)
        {
            ca            = caladjust;
            controller    = mc;
            numCircles    = ca.adjGrid.Length;
            currentCircle = 0;
            graphics      = CreateGraphics();
            Load         += new EventHandler(CalibrationAdjusterAutoForm_Load);
            FormClosing  += CalibrationAdjusterAutoForm_FormClosing;
            KeyDown      += new KeyEventHandler(CalibrationAdjusterAutoForm_KeyDown);

            calstate = CalState.WAITING_FOCUS;
        }
        //whenever this method is called, it paints from scratch and does not append to what's already on the screen
        //this method is typically called whenever RefreshScreen is called (60 fps)
        protected override void OnPaint(PaintEventArgs e)
        {
            //Draw overall target circle (which shrinks with duration)
            int       radius   = GetTargetCircleRadius(iteration);
            Point     calpoint = ca.adjGrid[currentCircle];
            Rectangle rec      = new Rectangle(calpoint.X - radius, calpoint.Y - radius, radius * 2, radius * 2);

            if (iteration == 0)
            {
                e.Graphics.DrawEllipse(Pens.White, rec);
            }
            else if (iteration < ConfigManager.calibrationIterationCountMax - 1)
            {
                e.Graphics.DrawEllipse(Pens.DarkCyan, rec);
                //also draw inner circles to guide
                radius = GetTargetCircleRadius(iteration + 1);
                rec    = new Rectangle(calpoint.X - radius, calpoint.Y - radius, radius * 2, radius * 2);
                e.Graphics.DrawEllipse(Pens.DarkMagenta, rec);
            }
            else
            {
                e.Graphics.FillEllipse(Brushes.DarkMagenta, rec);
                e.Graphics.DrawEllipse(Pens.DarkCyan, rec);
            }

            //Reset the iterations and calibrating this point if user has already been trying longer than expected
            if (iteration > ConfigManager.calibrationIterationCountMax + 1)
            {
                calstate  = CalState.WAITING_FOCUS;
                iteration = 0;
            }


            Point gp = controller.WarpPointer.GetNextPoint(controller.WarpPointer.GetGazePoint());

            //detect whether gaze point is close to the calibration circle (at most 7cm of screen away)
            if (PointHelper.GetPointDistance(gp, calpoint) < ScreenPixelHelper.ConvertMmToPixels(70))
            {
                //draw gray gaze point as long as it's not the final iteration(s)
                int   gazeRadius = ScreenPixelHelper.ConvertMmToPixels(1) / 2;
                Point p          = controller.WarpPointer.GetNextPoint(controller.WarpPointer.GetGazePoint());
                p.Offset(ca.adjGridOffset[currentCircle]);
                rec = new Rectangle(p.X - gazeRadius, p.Y - gazeRadius, gazeRadius * 2, gazeRadius * 2);

                if (iteration < ConfigManager.calibrationIterationCountMax)
                {
                    e.Graphics.FillEllipse(Brushes.Gray, rec);

                    if (iteration > 0)
                    {
                        //Get antipoint, which is basically located on other cide of currentCircle
                        int   xDiff = p.X - ca.adjGrid[currentCircle].X;
                        int   yDiff = p.Y - ca.adjGrid[currentCircle].Y;
                        Point ap    = new Point(p.X - xDiff * 2, p.Y - yDiff * 2);

                        rec = new Rectangle(ap.X - gazeRadius, ap.Y - gazeRadius, gazeRadius * 2, gazeRadius * 2);
                        e.Graphics.FillEllipse(Brushes.Gray, rec);
                    }
                }


                if (calstate == CalState.WAITING_FOCUS)
                {
                    StartTimer();
                    calstate = CalState.FOCUS_IN_PROGRESS;
                    return;
                }
                else if (calstate == CalState.FOCUS_IN_PROGRESS)
                {
                    if (DoneWaitingTime(150))
                    {
                        calstate = CalState.FOCUSED;
                    }
                    else
                    {
                        return;
                    }
                }
                else if (calstate == CalState.FOCUSED)
                {
                    //Done waiting the focus time and eyes are focussed
                    UpdateCalibrationAdjustmentWithCurrentGaze();

                    StartTimer();
                    sampleCollectionStartTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
                    calstate  = CalState.COLLECTING_SAMPLES;
                    iteration = 0;
                    return;
                }
                else if (calstate == CalState.COLLECTING_SAMPLES)
                {
                    //Done waiting time to start collecting samples

                    //We don't want the gaze to lag across the screen so we trick the user thinking it's centered already
                    if (iteration == 0 || iteration == 1)
                    {
                        UpdateCalibrationAdjustmentWithCurrentGaze();
                    }

                    if (DoneWaitingTime(ConfigManager.calibrationIterationTimeMs))
                    {
                        //Check if current gaze point is close to the center of the target circle
                        iteration++;
                        Point  wp                     = controller.WarpPointer.GetWarpPoint();
                        double pointDistance          = PointHelper.GetPointDistance(calpoint, wp);
                        int    pointDistanceThreshold = ScreenPixelHelper.ConvertMmToPixels(ConfigManager.calibrationCompletedThresholdMm);
                        UpdateCalibrationAdjustmentWithCurrentGaze();
                        if (iteration >= ConfigManager.calibrationIterationCountMax &&
                            pointDistance < pointDistanceThreshold)
                        {
                            //calibration for this point is successful
                            currentCircle++;
                            if (currentCircle == 9)
                            {
                                ca.writeCalibrationAdjustmentCsv();
                                currentCircle = 0;
                                Cursor.Show();
                                this.Close();
                            }
                        }
                        else
                        {
                            StartTimer();
                        }
                        this.Invalidate();// This forces the form to repaint
                    }
                }
            }
            else
            {
                iteration = 0;
                calstate  = CalState.WAITING_FOCUS;
            }
        }
예제 #4
0
        private void Update()
        {
            if (_vrPointer != null)
            {
                if (_vrPointer.vrController.triggerValue > 0.9f)
                {
                    _vrControllerTriggerd = true;
                    if (_triggerTime == 0)
                    {
                        _triggerTime = Time.time;
                    }
                }
                else if (_vrControllerTriggerd)
                {
                    _vrControllerTriggerd = false;
                    _triggerTime          = 0;
                    switch (_state)
                    {
                    case CalState.None:
                        break;

                    case CalState.WebCamPosition:
                        _camPosition = _vrPointer.vrController.transform.position;
                        _state       = CalState.CenterPosition;
                        _targetBehaviour.ThirdPersonPos  = _camPosition;
                        _targetBehaviour.Config.Position = _camPosition;
                        CalibratorCenter();
                        break;

                    case CalState.CenterPosition:
                        _centerPosition = _vrPointer.vrController.transform.position;
                        _state          = CalState.LeftPosition;
                        CalibratorLeft();
                        break;

                    case CalState.LeftPosition:
                        _leftPosition = _vrPointer.vrController.transform.position;
                        _state        = CalState.RightPosition;
                        CalibratorRight();
                        break;

                    case CalState.RightPosition:
                        _rightPosition = _vrPointer.vrController.transform.position;

                        _state = CalState.None;

                        var normalVector = _camPosition - _centerPosition;
                        var x            = _centerPosition;
                        var basePosition = _camPosition;
                        var mLeft        = _leftPosition - _camPosition;
                        var mRight       = _rightPosition - _camPosition;
                        var h            = Vector3.Dot(normalVector, x);

                        Vector3 leftNormalize  = basePosition + ((h - Vector3.Dot(normalVector, basePosition)) / (Vector3.Dot(normalVector, mLeft))) * mLeft;
                        Vector3 rightNormalize = basePosition + ((h - Vector3.Dot(normalVector, basePosition)) / (Vector3.Dot(normalVector, mRight))) * mRight;

                        float fov = Vector3.Angle(leftNormalize - _camPosition, rightNormalize - _camPosition);
                        float rot = Mathf.Atan2(leftNormalize.y - rightNormalize.y, Vector3.Distance(rightNormalize, leftNormalize)) * Mathf.Rad2Deg;

                        _targetBehaviour.ThirdPersonRot   = Quaternion.LookRotation(_centerPosition - _camPosition).eulerAngles;
                        _targetBehaviour.ThirdPersonRot.z = rot;
                        _targetBehaviour.Config.Rotation  = Quaternion.LookRotation(_centerPosition - _camPosition).eulerAngles;
                        _targetBehaviour.Config.RotationZ = rot;

                        _targetBehaviour.FOV        = fov;
                        _targetBehaviour.Config.fov = fov;

                        Plugin.cameraController.DestroyCalScreen();
                        break;
                    }
                }
            }
        }