private void ApplyVirtualArmAndSimulateInput(IVRModuleDeviceStateRW ctrlState, IVRModuleDeviceStateRW headState, Vector3 handSideMultiplier)
        {
            if (!ctrlState.isConnected)
            {
                return;
            }
            if (!VIUSettings.waveVRAddVirtualArmTo3DoFController && !VIUSettings.simulateWaveVR6DofController)
            {
                return;
            }
            var deviceType = (int)s_index2type[ctrlState.deviceIndex];

#if VIU_WAVEVR_2_1_0_OR_NEWER && UNITY_EDITOR
            if (!WaveVR.Instance.isSimulatorOn || WaveVR_Utils.WVR_GetDegreeOfFreedom_S() == (int)WVR_NumDoF.WVR_NumDoF_6DoF)
            {
                return;
            }
#else
            if (Interop.WVR_GetDegreeOfFreedom((WVR_DeviceType)deviceType) == WVR_NumDoF.WVR_NumDoF_6DoF)
            {
                return;
            }
#endif

            if (VIUSettings.simulateWaveVR6DofController)
            {
                if (Input.GetKeyDown(KeyCode.Alpha1))
                {
                    s_simulationMode = Simulate6DoFControllerMode.KeyboardWASD;
                }
                if (Input.GetKeyDown(KeyCode.Alpha2))
                {
                    s_simulationMode = Simulate6DoFControllerMode.KeyboardModifierTrackpad;
                }
                if (Input.GetKeyDown(KeyCode.BackQuote))
                {
                    s_simulatedCtrlPosArray[deviceType] = Vector3.zero;
                }

                var deltaMove   = Time.unscaledDeltaTime;
                var rotY        = Quaternion.Euler(0f, ctrlState.rotation.eulerAngles.y, 0f);
                var moveForward = rotY * Vector3.forward;
                var moveRight   = rotY * Vector3.right;

                switch (s_simulationMode)
                {
                case Simulate6DoFControllerMode.KeyboardWASD:
                {
                    if (Input.GetKey(KeyCode.D))
                    {
                        s_simulatedCtrlPosArray[deviceType] += moveRight * deltaMove;
                    }
                    if (Input.GetKey(KeyCode.A))
                    {
                        s_simulatedCtrlPosArray[deviceType] -= moveRight * deltaMove;
                    }
                    if (Input.GetKey(KeyCode.E))
                    {
                        s_simulatedCtrlPosArray[deviceType] += Vector3.up * deltaMove;
                    }
                    if (Input.GetKey(KeyCode.Q))
                    {
                        s_simulatedCtrlPosArray[deviceType] -= Vector3.up * deltaMove;
                    }
                    if (Input.GetKey(KeyCode.W))
                    {
                        s_simulatedCtrlPosArray[deviceType] += moveForward * deltaMove;
                    }
                    if (Input.GetKey(KeyCode.S))
                    {
                        s_simulatedCtrlPosArray[deviceType] -= moveForward * deltaMove;
                    }

                    break;
                }

                case Simulate6DoFControllerMode.KeyboardModifierTrackpad:
                {
                    float speedModifier = 2f;
                    float x             = ctrlState.GetAxisValue(VRModuleRawAxis.TouchpadX) * speedModifier;
                    float y             = ctrlState.GetAxisValue(VRModuleRawAxis.TouchpadY) * speedModifier;

                    if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl))
                    {
                        s_simulatedCtrlPosArray[deviceType] += x * moveRight * deltaMove;
                        s_simulatedCtrlPosArray[deviceType] += y * moveForward * deltaMove;
                    }

                    if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
                    {
                        s_simulatedCtrlPosArray[deviceType] += x * moveRight * deltaMove;
                        s_simulatedCtrlPosArray[deviceType] += y * Vector3.up * deltaMove;
                    }

                    break;
                }
                }
            }

            if (VIUSettings.waveVRAddVirtualArmTo3DoFController)
            {
                var neckPose = new RigidPose(s_simulatedCtrlPosArray[deviceType], Quaternion.identity) * GetNeckPose(headState.pose);
                ctrlState.position = GetControllerPositionWithVirtualArm(neckPose, ctrlState.rotation, handSideMultiplier);
            }
            else
            {
                ctrlState.position += s_simulatedCtrlPosArray[deviceType];
            }
        }