diff --git a/libraries/controllers/src/controllers/AxisValue.cpp b/libraries/controllers/src/controllers/AxisValue.cpp
new file mode 100644
index 0000000000..49201dbf7a
--- /dev/null
+++ b/libraries/controllers/src/controllers/AxisValue.cpp
@@ -0,0 +1,18 @@
+//
+//  AxisValue.cpp
+//
+//  Created by David Rowe on 14 Dec 2018.
+//  Copyright 2018 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#include "AxisValue.h"
+
+namespace controller {
+
+    AxisValue::AxisValue(const float value, const quint64 timestamp) :
+        value(value), timestamp(timestamp) { }
+
+}
diff --git a/libraries/controllers/src/controllers/AxisValue.h b/libraries/controllers/src/controllers/AxisValue.h
new file mode 100644
index 0000000000..67fd5736b8
--- /dev/null
+++ b/libraries/controllers/src/controllers/AxisValue.h
@@ -0,0 +1,31 @@
+//
+//  AxisValue.h
+//
+//  Created by David Rowe on 13 Dec 2018.
+//  Copyright 2018 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#pragma once
+#ifndef hifi_controllers_AxisValue_h
+#define hifi_controllers_AxisValue_h
+
+#include <QtCore/qglobal.h>
+
+namespace controller {
+
+    struct AxisValue {
+    public:
+        float value { 0.0f };
+        // The value can be timestamped to determine if consecutive identical values should be output (e.g., mouse movement).
+        quint64 timestamp { 0 };
+
+        AxisValue() {}
+        AxisValue(const float value, const quint64 timestamp);
+    };
+
+}
+
+#endif // hifi_controllers_AxisValue_h
diff --git a/libraries/controllers/src/controllers/InputDevice.cpp b/libraries/controllers/src/controllers/InputDevice.cpp
index a907842a17..e46bb3c8b5 100644
--- a/libraries/controllers/src/controllers/InputDevice.cpp
+++ b/libraries/controllers/src/controllers/InputDevice.cpp
@@ -26,12 +26,12 @@ namespace controller {
         return 0.0f;
     }
 
-    float InputDevice::getAxis(int channel) const {
+    AxisValue InputDevice::getAxis(int channel) const {
         auto axis = _axisStateMap.find(channel);
         if (axis != _axisStateMap.end()) {
             return (*axis).second;
         } else {
-            return 0.0f;
+            return AxisValue();
         }
     }
 
@@ -71,7 +71,7 @@ namespace controller {
     float InputDevice::getValue(ChannelType channelType, uint16_t channel) const {
         switch (channelType) {
             case ChannelType::AXIS:
-                return getAxis(channel);
+                return getAxis(channel).value;
 
             case ChannelType::BUTTON:
                 return getButton(channel);
diff --git a/libraries/controllers/src/controllers/InputDevice.h b/libraries/controllers/src/controllers/InputDevice.h
index 7479ef7b75..1d4ab1c5d8 100644
--- a/libraries/controllers/src/controllers/InputDevice.h
+++ b/libraries/controllers/src/controllers/InputDevice.h
@@ -16,6 +16,7 @@
 
 #include <QtCore/QString>
 
+#include "AxisValue.h"
 #include "Pose.h"
 #include "Input.h"
 #include "StandardControls.h"
@@ -103,12 +104,12 @@ public:
     using Pointer = std::shared_ptr<InputDevice>;
 
     typedef std::unordered_set<int> ButtonPressedMap;
-    typedef std::map<int, float> AxisStateMap;
+    typedef std::map<int, AxisValue> AxisStateMap;
     typedef std::map<int, Pose> PoseStateMap;
 
     // Get current state for each channel
     float getButton(int channel) const;
-    float getAxis(int channel) const;
+    AxisValue getAxis(int channel) const;
     Pose getPose(int channel) const;
 
     float getValue(const Input& input) const;
diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp
index c14db86ae9..ebc5a5cd3e 100755
--- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp
+++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp
@@ -27,15 +27,15 @@ void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputC
         _inputDevice->update(deltaTime, inputCalibrationData);
         eraseMouseClicked();
 
-        _inputDevice->_axisStateMap[MOUSE_AXIS_X] = _lastCursor.x();
-        _inputDevice->_axisStateMap[MOUSE_AXIS_Y] = _lastCursor.y();
+        _inputDevice->_axisStateMap[MOUSE_AXIS_X].value = _lastCursor.x();
+        _inputDevice->_axisStateMap[MOUSE_AXIS_Y].value = _lastCursor.y();
 
         QPoint currentMove = _lastCursor - _previousCursor;
-        _inputDevice->_axisStateMap[MOUSE_AXIS_X_POS] = (currentMove.x() > 0 ? currentMove.x() : 0.0f);
-        _inputDevice->_axisStateMap[MOUSE_AXIS_X_NEG] = (currentMove.x() < 0 ? -currentMove.x() : 0.0f);
+        _inputDevice->_axisStateMap[MOUSE_AXIS_X_POS].value = (currentMove.x() > 0 ? currentMove.x() : 0.0f);
+        _inputDevice->_axisStateMap[MOUSE_AXIS_X_NEG].value = (currentMove.x() < 0 ? -currentMove.x() : 0.0f);
         // Y mouse is inverted positive is pointing up the screen
-        _inputDevice->_axisStateMap[MOUSE_AXIS_Y_POS] = (currentMove.y() < 0 ? -currentMove.y() : 0.0f);
-        _inputDevice->_axisStateMap[MOUSE_AXIS_Y_NEG] = (currentMove.y() > 0 ? currentMove.y() : 0.0f);
+        _inputDevice->_axisStateMap[MOUSE_AXIS_Y_POS].value = (currentMove.y() < 0 ? -currentMove.y() : 0.0f);
+        _inputDevice->_axisStateMap[MOUSE_AXIS_Y_NEG].value = (currentMove.y() > 0 ? currentMove.y() : 0.0f);
         _previousCursor = _lastCursor;
     });
 
@@ -124,10 +124,11 @@ void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event) {
 void KeyboardMouseDevice::wheelEvent(QWheelEvent* event) {
     auto currentMove = event->angleDelta() / 120.0f;
 
-    _inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_X_POS).getChannel()] = (currentMove.x() > 0 ? currentMove.x() : 0.0f);
-    _inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_X_NEG).getChannel()] = (currentMove.x() < 0 ? -currentMove.x() : 0.0f);
-    _inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_Y_POS).getChannel()] = (currentMove.y() > 0 ? currentMove.y() : 0.0f);
-    _inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_Y_NEG).getChannel()] = (currentMove.y() < 0 ? -currentMove.y() : 0.0f);
+    // ####### TODO: Use AxisValue timestamps?
+    _inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_X_POS).getChannel()].value = (currentMove.x() > 0 ? currentMove.x() : 0, 0);
+    _inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_X_NEG).getChannel()].value = (currentMove.x() < 0 ? -currentMove.x() : 0, 0);
+    _inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_Y_POS).getChannel()].value = (currentMove.y() > 0 ? currentMove.y() : 0);
+    _inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_Y_NEG).getChannel()].value = (currentMove.y() < 0 ? -currentMove.y() : 0);
 }
 
 glm::vec2 evalAverageTouchPoints(const QList<QTouchEvent::TouchPoint>& points) {
@@ -167,11 +168,12 @@ void KeyboardMouseDevice::touchUpdateEvent(const QTouchEvent* event) {
         } else {
             auto currentMove = currentPos - _lastTouch;
 
-            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()] = (currentMove.x > 0 ? currentMove.x : 0.0f);
-            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_NEG).getChannel()] = (currentMove.x < 0 ? -currentMove.x : 0.0f);
+            // ####### TODO: Use AxisValue timestamp fields?
+            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()].value = (currentMove.x > 0 ? currentMove.x : 0.0f);
+            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_NEG).getChannel()].value = (currentMove.x < 0 ? -currentMove.x : 0.0f);
             // Y mouse is inverted positive is pointing up the screen
-            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_POS).getChannel()] = (currentMove.y < 0 ? -currentMove.y : 0.0f);
-            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_NEG).getChannel()] = (currentMove.y > 0 ? currentMove.y : 0.0f);
+            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_POS).getChannel()].value = (currentMove.y < 0 ? -currentMove.y : 0.0f);
+            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_NEG).getChannel()].value = (currentMove.y > 0 ? currentMove.y : 0.0f);
         }
 
         _lastTouch = currentPos;
diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp
index 20952df4d7..804ab3585b 100644
--- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp
+++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp
@@ -38,28 +38,29 @@ void TouchscreenDevice::pluginUpdate(float deltaTime, const controller::InputCal
         _inputDevice->update(deltaTime, inputCalibrationData);
     });
 
+    // ####### TODO: Use AxisValue timestamp fields?
     float distanceScaleX, distanceScaleY;
     if (_touchPointCount == 1) {
         if (_firstTouchVec.x < _currentTouchVec.x) {
             distanceScaleX = (_currentTouchVec.x - _firstTouchVec.x) / _screenDPIScale.x;
-            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()] = distanceScaleX;
+            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()].value = distanceScaleX;
         } else if (_firstTouchVec.x > _currentTouchVec.x) {
             distanceScaleX = (_firstTouchVec.x - _currentTouchVec.x) / _screenDPIScale.x;
-            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_NEG).getChannel()] = distanceScaleX;
+            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_NEG).getChannel()].value = distanceScaleX;
         }
         // Y axis is inverted, positive is pointing up the screen
         if (_firstTouchVec.y > _currentTouchVec.y) {
             distanceScaleY = (_firstTouchVec.y - _currentTouchVec.y) / _screenDPIScale.y;
-            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_POS).getChannel()] = distanceScaleY;
+            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_POS).getChannel()].value = distanceScaleY;
         } else if (_firstTouchVec.y < _currentTouchVec.y) {
             distanceScaleY = (_currentTouchVec.y - _firstTouchVec.y) / _screenDPIScale.y;
-            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_NEG).getChannel()] = distanceScaleY;
+            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_NEG).getChannel()].value = distanceScaleY;
         }
     } else  if (_touchPointCount == 2) {
         if (_pinchScale > _lastPinchScale && _pinchScale != 0) {
-            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_POS).getChannel()] = 1.0f;
+            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_POS).getChannel()].value = 1.0f;
         } else if (_pinchScale != 0) {
-            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_NEG).getChannel()] = 1.0f;
+            _inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_NEG).getChannel()].value = 1.0;
         }
         _lastPinchScale = _pinchScale;
     }
diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.cpp
index 32194e1b84..247f484c95 100644
--- a/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.cpp
+++ b/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.cpp
@@ -135,8 +135,8 @@ glm::vec2 TouchscreenVirtualPadDevice::clippedPointInCircle(float radius, glm::v
 void TouchscreenVirtualPadDevice::processInputDeviceForMove(VirtualPad::Manager& virtualPadManager) {
     vec2 clippedPoint = clippedPointInCircle(_fixedRadiusForCalc, _moveRefTouchPoint, _moveCurrentTouchPoint);
 
-    _inputDevice->_axisStateMap[controller::LX] = (clippedPoint.x - _moveRefTouchPoint.x) / _fixedRadiusForCalc;
-    _inputDevice->_axisStateMap[controller::LY] = (clippedPoint.y - _moveRefTouchPoint.y) / _fixedRadiusForCalc;
+    _inputDevice->_axisStateMap[controller::LX].value = (clippedPoint.x - _moveRefTouchPoint.x) / _fixedRadiusForCalc;
+    _inputDevice->_axisStateMap[controller::LY].value = (clippedPoint.y - _moveRefTouchPoint.y) / _fixedRadiusForCalc;
 
     virtualPadManager.getLeftVirtualPad()->setFirstTouch(_moveRefTouchPoint);
     virtualPadManager.getLeftVirtualPad()->setCurrentTouch(clippedPoint);
@@ -148,8 +148,10 @@ void TouchscreenVirtualPadDevice::processInputDeviceForView() {
     // We use average across how many times we've got touchUpdate events.
     // Using the average instead of the full deltaX and deltaY, makes deltaTime in MyAvatar dont't accelerate rotation when there is a low touchUpdate rate (heavier domains).
     // (Because it multiplies this input value by deltaTime (with a coefficient)).
-    _inputDevice->_axisStateMap[controller::RX] = _viewTouchUpdateCount == 0 ? 0 : (_viewCurrentTouchPoint.x - _viewRefTouchPoint.x) / _viewTouchUpdateCount;
-    _inputDevice->_axisStateMap[controller::RY] = _viewTouchUpdateCount == 0 ? 0 : (_viewCurrentTouchPoint.y - _viewRefTouchPoint.y) / _viewTouchUpdateCount;
+    _inputDevice->_axisStateMap[controller::RX].value = 
+        _viewTouchUpdateCount == 0 ? 0 : (_viewCurrentTouchPoint.x - _viewRefTouchPoint.x) / _viewTouchUpdateCount;
+    _inputDevice->_axisStateMap[controller::RY].value = 
+        _viewTouchUpdateCount == 0 ? 0 : (_viewCurrentTouchPoint.y - _viewRefTouchPoint.y) / _viewTouchUpdateCount;
 
     // after use, save last touch point as ref
     _viewRefTouchPoint = _viewCurrentTouchPoint;
@@ -442,8 +444,8 @@ void TouchscreenVirtualPadDevice::moveTouchUpdate(glm::vec2 touchPoint) {
 void TouchscreenVirtualPadDevice::moveTouchEnd() {
     if (_moveHasValidTouch) { // do stuff once
         _moveHasValidTouch = false;
-        _inputDevice->_axisStateMap[controller::LX] = 0;
-        _inputDevice->_axisStateMap[controller::LY] = 0;
+        _inputDevice->_axisStateMap[controller::LX].value = 0;
+        _inputDevice->_axisStateMap[controller::LY].value = 0;
     }
 }
 
@@ -465,8 +467,8 @@ void TouchscreenVirtualPadDevice::viewTouchUpdate(glm::vec2 touchPoint) {
 void TouchscreenVirtualPadDevice::viewTouchEnd() {
     if (_viewHasValidTouch) { // do stuff once
         _viewHasValidTouch = false;
-        _inputDevice->_axisStateMap[controller::RX] = 0;
-        _inputDevice->_axisStateMap[controller::RY] = 0;
+        _inputDevice->_axisStateMap[controller::RX].value = 0;
+        _inputDevice->_axisStateMap[controller::RY].value = 0;
     }
 }
 
diff --git a/plugins/hifiSdl2/src/Joystick.cpp b/plugins/hifiSdl2/src/Joystick.cpp
index be4ad6e4ee..ad0b459544 100644
--- a/plugins/hifiSdl2/src/Joystick.cpp
+++ b/plugins/hifiSdl2/src/Joystick.cpp
@@ -46,8 +46,8 @@ void Joystick::closeJoystick() {
 
 void Joystick::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
     for (auto axisState : _axisStateMap) {
-        if (fabsf(axisState.second) < CONTROLLER_THRESHOLD) {
-            _axisStateMap[axisState.first] = 0.0f;
+        if (fabsf(axisState.second.value) < CONTROLLER_THRESHOLD) {
+            _axisStateMap[axisState.first].value = 0.0f;
         }
     }
 }
@@ -59,7 +59,7 @@ void Joystick::focusOutEvent() {
 
 void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) {
     SDL_GameControllerAxis axis = (SDL_GameControllerAxis) event.axis;
-    _axisStateMap[makeInput((controller::StandardAxisChannel)axis).getChannel()] = (float)event.value / MAX_AXIS;
+    _axisStateMap[makeInput((controller::StandardAxisChannel)axis).getChannel()].value = (float)event.value / MAX_AXIS;
 }
 
 void Joystick::handleButtonEvent(const SDL_ControllerButtonEvent& event) {
diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp
index 392d990638..76ff4a1755 100644
--- a/plugins/oculus/src/OculusControllerManager.cpp
+++ b/plugins/oculus/src/OculusControllerManager.cpp
@@ -258,15 +258,15 @@ void OculusControllerManager::TouchDevice::update(float deltaTime,
     using namespace controller;
     // Axes
     const auto& inputState = _parent._touchInputState;
-    _axisStateMap[LX] = inputState.Thumbstick[ovrHand_Left].x;
-    _axisStateMap[LY] = inputState.Thumbstick[ovrHand_Left].y;
-    _axisStateMap[LT] = inputState.IndexTrigger[ovrHand_Left];
-    _axisStateMap[LEFT_GRIP] = inputState.HandTrigger[ovrHand_Left];
+    _axisStateMap[LX].value = inputState.Thumbstick[ovrHand_Left].x;
+    _axisStateMap[LY].value = inputState.Thumbstick[ovrHand_Left].y;
+    _axisStateMap[LT].value = inputState.IndexTrigger[ovrHand_Left];
+    _axisStateMap[LEFT_GRIP].value = inputState.HandTrigger[ovrHand_Left];
 
-    _axisStateMap[RX] = inputState.Thumbstick[ovrHand_Right].x;
-    _axisStateMap[RY] = inputState.Thumbstick[ovrHand_Right].y;
-    _axisStateMap[RT] = inputState.IndexTrigger[ovrHand_Right];
-    _axisStateMap[RIGHT_GRIP] = inputState.HandTrigger[ovrHand_Right];
+    _axisStateMap[RX].value = inputState.Thumbstick[ovrHand_Right].x;
+    _axisStateMap[RY].value = inputState.Thumbstick[ovrHand_Right].y;
+    _axisStateMap[RT].value = inputState.IndexTrigger[ovrHand_Right];
+    _axisStateMap[RIGHT_GRIP].value = inputState.HandTrigger[ovrHand_Right];
 
     // Buttons
     for (const auto& pair : BUTTON_MAP) {
diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp
index 53c23403a5..3aea5f1ce0 100644
--- a/plugins/openvr/src/ViveControllerManager.cpp
+++ b/plugins/openvr/src/ViveControllerManager.cpp
@@ -928,8 +928,8 @@ void ViveControllerManager::InputDevice::partitionTouchpad(int sButton, int xAxi
     const float CENTER_DEADBAND = 0.6f;
     const float DIAGONAL_DIVIDE_IN_RADIANS = PI / 4.0f;
     if (_buttonPressedMap.find(sButton) != _buttonPressedMap.end()) {
-        float absX = abs(_axisStateMap[xAxis]);
-        float absY = abs(_axisStateMap[yAxis]);
+        float absX = abs(_axisStateMap[xAxis].value);
+        float absY = abs(_axisStateMap[yAxis].value);
         glm::vec2 cartesianQuadrantI(absX, absY);
         float angle = glm::atan(cartesianQuadrantI.y / cartesianQuadrantI.x);
         float radius = glm::length(cartesianQuadrantI);
@@ -956,10 +956,10 @@ void ViveControllerManager::InputDevice::handleAxisEvent(float deltaTime, uint32
         } else {
             stick = _filteredRightStick.process(deltaTime, stick);
         }
-        _axisStateMap[isLeftHand ? LX : RX] = stick.x;
-        _axisStateMap[isLeftHand ? LY : RY] = stick.y;
+        _axisStateMap[isLeftHand ? LX : RX].value = stick.x;
+        _axisStateMap[isLeftHand ? LY : RY].value = stick.y;
     } else if (axis == vr::k_EButton_SteamVR_Trigger) {
-        _axisStateMap[isLeftHand ? LT : RT] = x;
+        _axisStateMap[isLeftHand ? LT : RT].value = x;
         // The click feeling on the Vive controller trigger represents a value of *precisely* 1.0,
         // so we can expose that as an additional button
         if (x >= 1.0f) {
@@ -1000,7 +1000,7 @@ void ViveControllerManager::InputDevice::handleButtonEvent(float deltaTime, uint
         if (button == vr::k_EButton_ApplicationMenu) {
             _buttonPressedMap.insert(isLeftHand ? LEFT_APP_MENU : RIGHT_APP_MENU);
         } else if (button == vr::k_EButton_Grip) {
-            _axisStateMap[isLeftHand ? LEFT_GRIP : RIGHT_GRIP] = 1.0f;
+            _axisStateMap[isLeftHand ? LEFT_GRIP : RIGHT_GRIP].value = 1.0f;
         } else if (button == vr::k_EButton_SteamVR_Trigger) {
             _buttonPressedMap.insert(isLeftHand ? LT : RT);
         } else if (button == vr::k_EButton_SteamVR_Touchpad) {
@@ -1008,7 +1008,7 @@ void ViveControllerManager::InputDevice::handleButtonEvent(float deltaTime, uint
         }
     } else {
         if (button == vr::k_EButton_Grip) {
-            _axisStateMap[isLeftHand ? LEFT_GRIP : RIGHT_GRIP] = 0.0f;
+            _axisStateMap[isLeftHand ? LEFT_GRIP : RIGHT_GRIP].value = 0.0f;
         }
     }