/// <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);
        }
        internal void UpdateState(SimulatedMotionControllerData motionControllerData)
        {
            lastPose             = currentPose;
            currentPose.Position = motionControllerData.Position;
            currentPose.Rotation = motionControllerData.Rotation;
            IsPositionAvailable  = IsRotationAvailable = motionControllerData.Position != Vector3.zero;

            if (lastPose != currentPose)
            {
                if (IsPositionAvailable && IsRotationAvailable)
                {
                    CoreServices.InputSystem?.RaiseSourcePoseChanged(InputSource, this, currentPose);
                }
            }

            for (int i = 0; i < Interactions?.Length; i++)
            {
                switch (Interactions[i].InputType)
                {
                case DeviceInputType.SpatialPointer:
                case DeviceInputType.SpatialGrip:
                    Interactions[i].PoseData = currentPose;
                    if (Interactions[i].Changed)
                    {
                        CoreServices.InputSystem?.RaisePoseInputChanged(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction, currentPose);
                    }
                    break;

                case DeviceInputType.Select:
                    Interactions[i].BoolData = motionControllerData.ButtonState.IsSelecting;
                    if (Interactions[i].Changed)
                    {
                        if (Interactions[i].BoolData)
                        {
                            CoreServices.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction);
                        }
                        else
                        {
                            CoreServices.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction);
                        }
                    }
                    break;

                case DeviceInputType.GripPress:
                case DeviceInputType.TriggerPress:
                    Interactions[i].FloatData = motionControllerData.ButtonState.IsGrabbing ? 1 : 0;
                    if (Interactions[i].Changed)
                    {
                        CoreServices.InputSystem?.RaiseFloatInputChanged(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction, motionControllerData.ButtonState.IsGrabbing ? 1 : 0);
                    }
                    break;

                case DeviceInputType.Menu:
                    Interactions[i].BoolData = motionControllerData.ButtonState.IsPressingMenu;
                    if (Interactions[i].Changed)
                    {
                        if (Interactions[i].BoolData)
                        {
                            CoreServices.InputSystem?.RaiseOnInputDown(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction);
                        }
                        else
                        {
                            CoreServices.InputSystem?.RaiseOnInputUp(InputSource, ControllerHandedness, Interactions[i].MixedRealityInputAction);
                        }
                    }
                    break;
                }
            }
        }