Ejemplo n.º 1
0
            /// <summary>
            /// Initializes a new instance of the <see cref="Controller"/> class.
            /// </summary>
            /// <param name="inputTrackerHandle">The input tracker handle.</param>
            /// <param name="controllerId">The controller id.</param>
            /// <param name="inputHand">The hand that should be assigned.</param>
            public Controller(ulong inputTrackerHandle, byte controllerId, MLInput.Hand inputHand)
            {
                // InputTracker is still required, for LED Patterns & Control Vibrations.
                this.inputTrackerHandle = inputTrackerHandle;
                this.controllerId       = controllerId;

                this.Hand = inputHand;
                this.CurrentTouchpadGesture = new MLInput.Controller.TouchpadGesture();

                // Start the Unity gesture subsystem.
                MLDevice.RegisterGestureSubsystem();
                if (MLDevice.GestureSubsystem != null)
                {
                    MLDevice.GestureSubsystem.onTouchpadGestureChanged += this.HandleOnTouchpadGestureChanged;
                }
            }
Ejemplo n.º 2
0
        //Init:
        private void Start()
        {
            //sets:
            _previousHand = handedness;

            //startup:
            if (!MLInput.IsStarted)
            {
                MLResult result = MLInput.Start();
                if (!result.IsOk)
                {
                    enabled = false;
                }
            }

            GetControl();

            //hooks:
            MLInput.OnControllerConnected    += HandleControlConnected;
            MLInput.OnControllerDisconnected += HandleControlDisconnected;
        }
Ejemplo n.º 3
0
        //Loops:
        private void Update()
        {
            if (_previousHand != handedness)
            {
                _previousHand = handedness;
                GetControl();
            }

            //no control?
            if (Control == null)
            {
                return;
            }

            //control pose:
            Position    = Control.Position;
            Orientation = Control.Orientation;

            if (followControl)
            {
                transform.position = Position;
                transform.rotation = Orientation;
            }

            //touch down:
            if (!Touch && Control.Touch1Active)
            {
                Touch = true;
                StartCoroutine("TouchHold");

                //resets:
                TouchMoved       = false;
                TouchRadialDelta = 0;

                //current for comparisons:
                Vector4 tempTouch = GetTouch1Info();

                //double - must be close to last touch and quick enough:
                float distanceFromLastTouchDown = Vector2.Distance(tempTouch, TouchValue);
                float durationSinceLastTouch    = Time.realtimeSinceStartup - _lastTouchTime;
                if (distanceFromLastTouchDown <= _maxDoubleTouchDistance && durationSinceLastTouch < _touchDoubleDuration)
                {
                    OnDoubleTap?.Invoke(TouchValue);
                }

                //cache:
                TouchValue       = tempTouch;
                _touchBeganValue = TouchValue;
                _touchBeganTime  = Time.realtimeSinceStartup;
                _lastTouchTime   = Time.realtimeSinceStartup;

                OnTouchDown?.Invoke(TouchValue);
            }

            //touch movement:
            if (Touch)
            {
                //current for comparisons:
                Vector4 tempTouch = GetTouch1Info();

                //touch force delta tracking:
                if (tempTouch.z != TouchValue.z)
                {
                    if (tempTouch.z > TouchValue.z)
                    {
                        //touch is getting stronger:
                        if (!ForceTouch && tempTouch.z >= _forceTouchDownThreshold)
                        {
                            ForceTouch       = true;
                            _wasForceTouched = true;
                            OnForceTouchDown?.Invoke();
                        }
                    }
                    else
                    {
                        //touch is getting weaker:
                        if (ForceTouch && tempTouch.z <= _forceTouchUpThreshold)
                        {
                            ForceTouch = false;
                            OnForceTouchUp?.Invoke();
                        }
                    }
                }

                //since force touch can make values go crazy we ignore everything if it happened:
                if (!_wasForceTouched)
                {
                    //did we have an intentional initial move?
                    if (!TouchMoved)
                    {
                        //did we initially move far enough?
                        float movedFromInitialTouchDistance = Vector2.Distance(tempTouch, _touchBeganValue);

                        if (movedFromInitialTouchDistance > _touchBeganMovingThreshold)
                        {
                            TouchMoved = true;

                            OnTouchBeganMoving?.Invoke();
                        }
                    }

                    //only track subsequent moves if we initially began moving:
                    if (TouchMoved)
                    {
                        //did we have an intentional move?
                        float movedDistance = Vector2.Distance(TouchValue, tempTouch);
                        if (TouchValue != tempTouch && movedDistance > 0 && movedDistance > _minTouchMove)
                        {
                            //moved:
                            OnTouchMove?.Invoke(TouchValue);

                            //radial move:
                            float angleDelta = tempTouch.w - TouchValue.w;
                            if (OnTouchRadialMove != null)
                            {
                                TouchRadialDelta = angleDelta;
                                OnTouchRadialMove?.Invoke(angleDelta);
                            }

                            //cache:
                            TouchValue = tempTouch;
                        }
                    }
                }
            }

            //touch up:
            if (!Control.Touch1Active && Touch)
            {
                //status:
                Touch      = false;
                TouchMoved = false;
                TouchValue = GetTouch1Info();
                StopCoroutine("TouchHold");

                //meta on touch sequence:
                Vector2 start = _touchBeganValue;
                Vector2 end   = TouchValue;
                float   distanceFromTouchStart = Vector2.Distance(start, end);
                float   durationFromTouchStart = Time.realtimeSinceStartup - _touchBeganTime;

                //since force touch can make values go crazy we ignore everything if it happened:
                if (!_wasForceTouched)
                {
                    //swipe determinations:
                    if (distanceFromTouchStart >= _minSwipeDistance)
                    {
                        //swiped - we only calculate if the event is registered:
                        if (OnSwipe != null)
                        {
                            //swipes must be quicker than _maxSwipeDuration:
                            if (durationFromTouchStart < _maxSwipeDuration)
                            {
                                //get angle:
                                Vector2 swipe      = (end - start).normalized;
                                float   swipeAngle = Vector2.Angle(Vector2.up, swipe);

                                //swiped to the left? then we need to continue to 360 degrees:
                                if (end.x < start.x)
                                {
                                    swipeAngle = 360 - swipeAngle;
                                }

                                //determine swipe direction:
                                MLInputControllerTouchpadGestureDirection direction = MLInputControllerTouchpadGestureDirection.Left;
                                if (swipeAngle > 315 || swipeAngle <= 45)
                                {
                                    direction = MLInputControllerTouchpadGestureDirection.Up;
                                }
                                else if (swipeAngle > 45 && swipeAngle <= 135)
                                {
                                    direction = MLInputControllerTouchpadGestureDirection.Right;
                                }
                                else if (swipeAngle > 135 && swipeAngle <= 225)
                                {
                                    direction = MLInputControllerTouchpadGestureDirection.Down;
                                }

                                OnSwipe?.Invoke(direction);
                            }
                        }
                    }
                    else
                    {
                        //tapped - we only calculate if the event is registered:
                        if (OnTapped != null)
                        {
                            //taps must be quicker than _maxTapDuration:
                            if (durationFromTouchStart < _maxTapDuration)
                            {
                                //determine tap location:
                                MLInputControllerTouchpadGestureDirection direction = MLInputControllerTouchpadGestureDirection.Left;
                                if (TouchValue.w > 315 || TouchValue.w <= 45)
                                {
                                    direction = MLInputControllerTouchpadGestureDirection.Up;
                                }
                                else if (TouchValue.w > 45 && TouchValue.w <= 135)
                                {
                                    direction = MLInputControllerTouchpadGestureDirection.Right;
                                }
                                else if (TouchValue.w > 135 && TouchValue.w <= 225)
                                {
                                    direction = MLInputControllerTouchpadGestureDirection.Down;
                                }

                                OnTapped?.Invoke(direction);
                            }
                        }
                    }
                }

                //we ultimately released so fire that event:
                OnTouchUp?.Invoke(TouchValue);

                //reset force touch activity on full release only to avoid any slight swipes at the end of release:
                _wasForceTouched = false;

                //if a user releases rapidly after a force press this will catch the release:
                if (ForceTouch)
                {
                    ForceTouch = false;
                    OnForceTouchUp?.Invoke();
                }
            }

            //trigger:
            if (TriggerValue != Control.TriggerValue)
            {
                //trigger began moving:
                if (TriggerValue == 0)
                {
                    OnTriggerPressBegan?.Invoke();
                }

                //trigger moved:
                OnTriggerMove?.Invoke(Control.TriggerValue - TriggerValue);

                //trigger released:
                if (Control.TriggerValue == 0)
                {
                    OnTriggerPressEnded?.Invoke();
                }

                TriggerValue = Control.TriggerValue;
            }
        }