private Vector3 GetCameraControlRotation(MouseDelta mouseDelta)
        {
            float inversionFactor = profile.IsControllerLookInverted ? -1.0f : 1.0f;

            Vector3 rot = Vector3.zero;

            if (this.isGamepadLookEnabled)
            {
                try
                {
                    // Get the axes information from the right stick of X360 controller
                    rot.x += InputCurve(UnityEngine.Input.GetAxis(profile.LookVertical)) * inversionFactor;
                    rot.y += InputCurve(UnityEngine.Input.GetAxis(profile.LookHorizontal));
                }
                catch (System.Exception)
                {
                    this.isGamepadLookEnabled = false;
                }
            }

            mouseRotation.Update(profile.MouseLookButton, cancelRotationKey, profile.MouseLookToggle);
            if (mouseRotation.IsRotating)
            {
                rot.x += -InputCurve(mouseDelta.screenDelta.y * profile.MouseRotationSensitivity);
                rot.y += InputCurve(mouseDelta.screenDelta.x * profile.MouseRotationSensitivity);
                rot.z += InputCurve(mouseDelta.screenDelta.z * profile.MouseRotationSensitivity);
            }

            rot *= profile.MouseLookSpeed;

            return(rot);
        }
예제 #2
0
 /// Apply changes to one controller and update tracking
 internal abstract void SimulateInput(
     ref long lastHandTrackedTimestamp,
     SimulatedControllerState state,
     bool isSimulating,
     bool isAlwaysVisible,
     MouseDelta mouseDelta,
     bool useMouseRotation);
        /// <summary>
        /// Update hand state based on keyboard and mouse input
        /// </summary>
        private void SimulateUserInput(MouseDelta mouseDelta)
        {
            float time = Time.time;

            if (KeyInputSystem.GetKeyDown(profile.ToggleLeftHandKey))
            {
                IsAlwaysVisibleLeft = !IsAlwaysVisibleLeft;
            }
            if (KeyInputSystem.GetKeyDown(profile.ToggleRightHandKey))
            {
                IsAlwaysVisibleRight = !IsAlwaysVisibleRight;
            }

            if (!Application.isFocused)
            {
                isSimulatingLeft  = false;
                isSimulatingRight = false;
            }
            else
            {
                if (KeyInputSystem.GetKeyDown(profile.LeftHandManipulationKey))
                {
                    isSimulatingLeft = true;
                    if (lastSimulationLeft > 0.0f && time - lastSimulationLeft <= profile.DoublePressTime)
                    {
                        IsAlwaysVisibleLeft = !IsAlwaysVisibleLeft;
                    }
                    lastSimulationLeft = time;
                }
                if (KeyInputSystem.GetKeyUp(profile.LeftHandManipulationKey))
                {
                    isSimulatingLeft = false;
                }

                if (KeyInputSystem.GetKeyDown(profile.RightHandManipulationKey))
                {
                    isSimulatingRight = true;
                    if (lastSimulationRight > 0.0f && time - lastSimulationRight <= profile.DoublePressTime)
                    {
                        IsAlwaysVisibleRight = !IsAlwaysVisibleRight;
                    }
                    lastSimulationRight = time;
                }
                if (KeyInputSystem.GetKeyUp(profile.RightHandManipulationKey))
                {
                    isSimulatingRight = false;
                }
            }

            mouseRotation.Update(profile.HandRotateButton, cancelRotationKey, false);

            SimulateHandInput(ref lastHandTrackedTimestampLeft, HandStateLeft, isSimulatingLeft, IsAlwaysVisibleLeft, mouseDelta, mouseRotation.IsRotating);
            SimulateHandInput(ref lastHandTrackedTimestampRight, HandStateRight, isSimulatingRight, IsAlwaysVisibleRight, mouseDelta, mouseRotation.IsRotating);

            float gestureAnimDelta = profile.HandGestureAnimationSpeed * Time.deltaTime;

            HandStateLeft.GestureBlending  += gestureAnimDelta;
            HandStateRight.GestureBlending += gestureAnimDelta;
        }
예제 #4
0
        /// <summary>
        /// Update controller state based on keyboard and mouse input
        /// </summary>
        protected virtual void SimulateUserInput(MouseDelta mouseDelta)
        {
            float time = Time.time;

            if (KeyInputSystem.GetKeyDown(profile.ToggleLeftControllerKey))
            {
                IsAlwaysVisibleLeft = !IsAlwaysVisibleLeft;
            }
            if (KeyInputSystem.GetKeyDown(profile.ToggleRightControllerKey))
            {
                IsAlwaysVisibleRight = !IsAlwaysVisibleRight;
            }

            if (!Application.isFocused && !KeyInputSystem.SimulatingInput)
            {
                IsSimulatingLeft  = false;
                IsSimulatingRight = false;
            }
            else
            {
                if (KeyInputSystem.GetKeyDown(profile.LeftControllerManipulationKey))
                {
                    IsSimulatingLeft = true;
                    if (lastSimulationLeft > 0.0f && time - lastSimulationLeft <= profile.DoublePressTime)
                    {
                        IsAlwaysVisibleLeft = !IsAlwaysVisibleLeft;
                    }
                    lastSimulationLeft = time;
                }
                if (KeyInputSystem.GetKeyUp(profile.LeftControllerManipulationKey))
                {
                    IsSimulatingLeft = false;
                }

                if (KeyInputSystem.GetKeyDown(profile.RightControllerManipulationKey))
                {
                    IsSimulatingRight = true;
                    if (lastSimulationRight > 0.0f && time - lastSimulationRight <= profile.DoublePressTime)
                    {
                        IsAlwaysVisibleRight = !IsAlwaysVisibleRight;
                    }
                    lastSimulationRight = time;
                }
                if (KeyInputSystem.GetKeyUp(profile.RightControllerManipulationKey))
                {
                    IsSimulatingRight = false;
                }
                if (isSimulatingGaze)
                {
                    lastSimulationGaze = time;
                }
            }

            mouseRotation.Update(profile.ControllerRotateButton, cancelRotationKey, false);

            SimulateInput(ref lastInputTrackedTimestampLeft, InputStateLeft, IsSimulatingLeft, IsAlwaysVisibleLeft, mouseDelta, mouseRotation.IsRotating);
            SimulateInput(ref lastInputTrackedTimestampRight, InputStateRight, IsSimulatingRight, IsAlwaysVisibleRight, mouseDelta, mouseRotation.IsRotating);
            SimulateInput(ref lastInputTrackedTimestampGaze, InputStateGaze, isSimulatingGaze, false, mouseDelta, mouseRotation.IsRotating);
        }
        /// Apply changes to one hand and update tracking
        internal override void SimulateInput(
            ref long lastHandTrackedTimestamp,
            SimulatedControllerState state,
            bool isSimulating,
            bool isAlwaysVisible,
            MouseDelta mouseDelta,
            bool useMouseRotation)
        {
            var  handState      = state as SimulatedHandState;
            bool enableTracking = isAlwaysVisible || isSimulating;

            if (!handState.IsTracked && enableTracking)
            {
                ResetInput(handState, isSimulating);
            }

            if (isSimulating)
            {
                handState.SimulateInput(mouseDelta, useMouseRotation, profile.MouseRotationSensitivity, profile.MouseControllerRotationSpeed, profile.ControllerJitterAmount);

                if (isAlwaysVisible)
                {
                    // Toggle gestures on/off
                    handState.Gesture = ToggleGesture(handState.Gesture);
                }
                else
                {
                    // Enable gesture while mouse button is pressed
                    handState.Gesture = SelectGesture();
                }
            }

            // Update tracked state of a hand.
            // If hideTimeout value is null, hands will stay visible after tracking stops.
            // TODO: DateTime.UtcNow can be quite imprecise, better use Stopwatch.GetTimestamp
            // https://stackoverflow.com/questions/2143140/c-sharp-datetime-now-precision
            DateTime currentTime = DateTime.UtcNow;

            if (enableTracking)
            {
                handState.IsTracked      = true;
                lastHandTrackedTimestamp = currentTime.Ticks;
            }
            else
            {
                float timeSinceTracking = (float)currentTime.Subtract(new DateTime(lastHandTrackedTimestamp)).TotalSeconds;
                if (timeSinceTracking > profile.ControllerHideTimeout)
                {
                    handState.IsTracked = false;
                }
            }
        }
        /// <summary>
        /// Update hand state based on keyboard and mouse input
        /// </summary>
        protected override void SimulateUserInput(MouseDelta mouseDelta)
        {
            base.SimulateUserInput(mouseDelta);

            SimulatedHandState handStateLeft  = InputStateLeft as SimulatedHandState;
            SimulatedHandState handStateRight = InputStateRight as SimulatedHandState;
            SimulatedHandState handStateGaze  = InputStateGaze as SimulatedHandState;

            // This line explicitly uses unscaledDeltaTime because we don't want input simulation
            // to lag when the time scale is set to a value other than 1. Input should still continue
            // to move freely.
            float gestureAnimDelta = profile.HandGestureAnimationSpeed * Time.unscaledDeltaTime;

            handStateLeft.GestureBlending  += gestureAnimDelta;
            handStateRight.GestureBlending += gestureAnimDelta;
            handStateGaze.GestureBlending   = 1.0f;
        }
        /// <summary>
        /// Translate and rotate the camera transform based on keyboard and mouse input.
        /// </summary>
        public void UpdateTransform(Transform transform, MouseDelta mouseDelta)
        {
            // Undo the last tracker to Unity transforms applied
            transform.Translate(-this.lastTrackerToUnityTranslation, Space.World);
            transform.Rotate(-this.lastTrackerToUnityRotation.eulerAngles, Space.World);

            // Calculate and apply the camera control movement this frame
            Vector3 rotate    = GetCameraControlRotation(mouseDelta);
            Vector3 translate = GetCameraControlTranslation(transform);

            transform.Rotate(rotate.x, 0.0f, 0.0f);
            transform.Rotate(0.0f, rotate.y, 0.0f, Space.World);
            transform.Rotate(0.0f, 0.0f, rotate.z);
            transform.Translate(translate, Space.World);

            transform.Rotate(this.lastTrackerToUnityRotation.eulerAngles, Space.World);
            transform.Translate(this.lastTrackerToUnityTranslation, Space.World);
        }
        public void SimulateInput(MouseDelta mouseDelta, bool useMouseRotation, float rotationSensitivity, float rotationScale, float noiseAmount)
        {
            if (useMouseRotation)
            {
                Vector3 rotationDeltaEulerAngles = Vector3.zero;
                rotationDeltaEulerAngles.x += -mouseDelta.screenDelta.y * rotationSensitivity;
                rotationDeltaEulerAngles.y += mouseDelta.screenDelta.x * rotationSensitivity;
                rotationDeltaEulerAngles.z += mouseDelta.screenDelta.z * rotationSensitivity;
                rotationDeltaEulerAngles   *= rotationScale;

                ViewportRotation = ViewportRotation + rotationDeltaEulerAngles;
            }
            else
            {
                ViewportPosition += mouseDelta.viewportDelta;
            }

            JitterOffset = UnityEngine.Random.insideUnitSphere * noiseAmount;
        }
        /// <summary>
        /// Capture a snapshot of simulated hand data based on current state.
        /// </summary>
        public bool UpdateHandData(SimulatedHandData handDataLeft, SimulatedHandData handDataRight, SimulatedHandData handDataGaze, MouseDelta mouseDelta)
        {
            SimulateUserInput(mouseDelta);

            SimulatedHandState handStateLeft  = InputStateLeft as SimulatedHandState;
            SimulatedHandState handStateRight = InputStateRight as SimulatedHandState;
            SimulatedHandState handStateGaze  = InputStateGaze as SimulatedHandState;

            handStateLeft.Update();
            handStateRight.Update();
            handStateGaze.Update();

            bool handDataChanged = false;

            // Cache the generator delegates so we don't gc alloc every frame
            if (generatorLeft == null)
            {
                generatorLeft = handStateLeft.FillCurrentFrame;
            }

            if (generatorRight == null)
            {
                generatorRight = handStateRight.FillCurrentFrame;
            }

            if (generatorGaze == null)
            {
                generatorGaze = handStateGaze.FillCurrentFrame;
            }

            handDataChanged |= handDataLeft.Update(handStateLeft.IsTracked, handStateLeft.IsPinching, generatorLeft);
            handDataChanged |= handDataRight.Update(handStateRight.IsTracked, handStateRight.IsPinching, generatorRight);
            handDataChanged |= handDataGaze.Update(handStateGaze.IsTracked, handStateGaze.IsPinching, generatorGaze);

            return(handDataChanged);
        }
        /// <summary>
        /// Update hand state based on keyboard and mouse input
        /// </summary>
        private void SimulateUserInput(MouseDelta mouseDelta)
        {
            float time = Time.time;

            if (KeyInputSystem.GetKeyDown(profile.ToggleLeftHandKey))
            {
                IsAlwaysVisibleLeft = !IsAlwaysVisibleLeft;
            }
            if (KeyInputSystem.GetKeyDown(profile.ToggleRightHandKey))
            {
                IsAlwaysVisibleRight = !IsAlwaysVisibleRight;
            }

            if (!Application.isFocused && !KeyInputSystem.SimulatingInput)
            {
                isSimulatingLeft  = false;
                isSimulatingRight = false;
            }
            else
            {
                if (KeyInputSystem.GetKeyDown(profile.LeftHandManipulationKey))
                {
                    isSimulatingLeft = true;
                    if (lastSimulationLeft > 0.0f && time - lastSimulationLeft <= profile.DoublePressTime)
                    {
                        IsAlwaysVisibleLeft = !IsAlwaysVisibleLeft;
                    }
                    lastSimulationLeft = time;
                }
                if (KeyInputSystem.GetKeyUp(profile.LeftHandManipulationKey))
                {
                    isSimulatingLeft = false;
                }

                if (KeyInputSystem.GetKeyDown(profile.RightHandManipulationKey))
                {
                    isSimulatingRight = true;
                    if (lastSimulationRight > 0.0f && time - lastSimulationRight <= profile.DoublePressTime)
                    {
                        IsAlwaysVisibleRight = !IsAlwaysVisibleRight;
                    }
                    lastSimulationRight = time;
                }
                if (KeyInputSystem.GetKeyUp(profile.RightHandManipulationKey))
                {
                    isSimulatingRight = false;
                }
                if (isSimulatingGaze)
                {
                    lastSimulationGaze = time;
                }
            }

            mouseRotation.Update(profile.HandRotateButton, cancelRotationKey, false);

            SimulateHandInput(ref lastHandTrackedTimestampLeft, HandStateLeft, isSimulatingLeft, IsAlwaysVisibleLeft, mouseDelta, mouseRotation.IsRotating);
            SimulateHandInput(ref lastHandTrackedTimestampRight, HandStateRight, isSimulatingRight, IsAlwaysVisibleRight, mouseDelta, mouseRotation.IsRotating);
            SimulateHandInput(ref lastHandTrackedTimestampGaze, HandStateGaze, isSimulatingGaze, false, mouseDelta, mouseRotation.IsRotating);

            // This line explicitly uses unscaledDeltaTime because we don't want input simulation
            // to lag when the time scale is set to a value other than 1. Input should still continue
            // to move freely.
            float gestureAnimDelta = profile.HandGestureAnimationSpeed * Time.unscaledDeltaTime;

            HandStateLeft.GestureBlending  += gestureAnimDelta;
            HandStateRight.GestureBlending += gestureAnimDelta;
            HandStateGaze.GestureBlending   = 1.0f;
        }
        /// <inheritdoc />
        internal override void SimulateInput(ref long lastMotionControllerTrackedTimestamp, SimulatedControllerState state, bool isSimulating, bool isAlwaysVisible, MouseDelta mouseDelta, bool useMouseRotation)
        {
            if (!(state is SimulatedMotionControllerState motionControllerState))
            {
                return;
            }
            bool enableTracking = isAlwaysVisible || isSimulating;

            if (!motionControllerState.IsTracked && enableTracking)
            {
                ResetInput(motionControllerState, isSimulating);
            }
            if (isSimulating)
            {
                motionControllerState.SimulateInput(mouseDelta, useMouseRotation, profile.MouseRotationSensitivity, profile.MouseControllerRotationSpeed, profile.ControllerJitterAmount);

                motionControllerState.ButtonState = new SimulatedMotionControllerButtonState
                {
                    IsSelecting    = KeyInputSystem.GetKey(profile.MotionControllerTriggerKey),
                    IsGrabbing     = KeyInputSystem.GetKey(profile.MotionControllerGrabKey),
                    IsPressingMenu = KeyInputSystem.GetKey(profile.MotionControllerMenuKey)
                };
            }

            // Update tracked state of a motion controller.
            // If hideTimeout value is null, motion controllers will stay visible after tracking stops.
            // TODO: DateTime.UtcNow can be quite imprecise, better use Stopwatch.GetTimestamp
            // https://stackoverflow.com/questions/2143140/c-sharp-datetime-now-precision
            DateTime currentTime = DateTime.UtcNow;

            if (enableTracking)
            {
                motionControllerState.IsTracked      = true;
                lastMotionControllerTrackedTimestamp = currentTime.Ticks;
            }
            else
            {
                float timeSinceTracking = (float)currentTime.Subtract(new DateTime(lastMotionControllerTrackedTimestamp)).TotalSeconds;
                if (timeSinceTracking > profile.ControllerHideTimeout)
                {
                    motionControllerState.IsTracked = false;
                }
            }
        }
        /// <summary>
        /// Capture a snapshot of simulated motion controller data based on current state.
        /// </summary>
        public void UpdateControllerData(SimulatedMotionControllerData motionControllerDataLeft, SimulatedMotionControllerData motionControllerDataRight, MouseDelta mouseDelta)
        {
            SimulateUserInput(mouseDelta);

            SimulatedMotionControllerState motionControllerStateLeft  = InputStateLeft as SimulatedMotionControllerState;
            SimulatedMotionControllerState motionControllerStateRight = InputStateRight as SimulatedMotionControllerState;

            motionControllerStateLeft.Update();
            motionControllerStateRight.Update();

            // Cache the generator delegates so we don't gc alloc every frame
            if (updaterLeft == null)
            {
                updaterLeft = motionControllerStateLeft.UpdateControllerPose;
            }

            if (updaterRight == null)
            {
                updaterRight = motionControllerStateRight.UpdateControllerPose;
            }

            motionControllerDataLeft.Update(motionControllerStateLeft.IsTracked, motionControllerStateLeft.ButtonState, updaterLeft);
            motionControllerDataRight.Update(motionControllerStateRight.IsTracked, motionControllerStateRight.ButtonState, updaterRight);
        }