public void ReadState(ControllerState outState)
{
if (error) {
outState.connectionState = GvrConnectionState.Error;
outState.errorDetails = errorDetails;
return;
}
gvr_controller_read_state(api, ref state);
outState.connectionState = ConvertConnectionState(state.connection_state);
// Note: for accelerometer, gyro and orientation, we have to convert from the space used by
// the GVR API to Unity space. They are different.
// GVR API: X = right, Y = up, Z = back, right-handed.
// Unity: X = right, Y = up, Z = forward, left-handed
//
// So for orientation and gyro, we must invert the signs of X, Y, and Z due to chiral
// conversion, and then must flip Z because of the difference in the Z axis direction.
// So, in the end, the conversion is: -x, -y, z.
//
// For the accelerometer, there is no chirality conversion because it doesn't express
// a rotation. But we still need to flip Z.
outState.accel = new Vector3(state.accel.x, state.accel.y, -state.accel.z);
outState.gyro = new Vector3(-state.gyro.x, -state.gyro.y, state.gyro.z);
outState.orientation = new Quaternion(
-state.orientation.x, -state.orientation.y, state.orientation.z, state.orientation.w);
outState.isTouching = 0 != state.is_touching;
outState.touchPos = new Vector2(state.touch_pos.x, state.touch_pos.y);
outState.touchDown = 0 != state.touch_down;
outState.touchUp = 0 != state.touch_up;
outState.appButtonDown = 0 != state.button_down[GVR_CONTROLLER_BUTTON_APP];
outState.appButtonState = 0 != state.button_state[GVR_CONTROLLER_BUTTON_APP];
outState.appButtonUp = 0 != state.button_up[GVR_CONTROLLER_BUTTON_APP];
outState.clickButtonDown = 0 != state.button_down[GVR_CONTROLLER_BUTTON_CLICK];
outState.clickButtonState = 0 != state.button_state[GVR_CONTROLLER_BUTTON_CLICK];
outState.clickButtonUp = 0 != state.button_up[GVR_CONTROLLER_BUTTON_CLICK];
outState.recentering = 0 != state.recentering;
outState.recentered = 0 != state.recentered;
}