PSMove_3AxisVector
psmove_orientation_get_gravity_calibration_direction(PSMoveOrientation *orientation_state)
{
	psmove_return_val_if_fail(orientation_state != NULL, *k_psmove_vector_zero);

	PSMove_3AxisVector identity_g;
	psmove_get_identity_gravity_calibration_direction(orientation_state->move, &identity_g);

	// First apply the calibration data transform.
	// This allows us to pretend the "identity pose" was some other orientation the vertical during calibration
	identity_g= psmove_3axisvector_apply_transform(&identity_g, &orientation_state->calibration_transform);

	// Next apply the sensor data transform.
	// This allows us to pretend the sensors are in some other coordinate system (like OpenGL where +Y is up)
	identity_g= psmove_3axisvector_apply_transform(&identity_g, &orientation_state->sensor_transform);

	return identity_g;
}
//-- private methods -----
static bool
is_move_stable_and_aligned_with_gravity(PSMove *move)
{
	const float k_cosine_10_degrees = 0.984808f;

	PSMove_3AxisVector k_identity_gravity_vector;
	PSMove_3AxisVector acceleration_direction;
	float acceleration_magnitude;
	bool isOk;

	// Get the direction the gravity vector should be pointing 
	// while the controller is in cradle pose.
	psmove_get_identity_gravity_calibration_direction(move, &k_identity_gravity_vector);
	psmove_get_accelerometer_frame(move, Frame_SecondHalf, 
		&acceleration_direction.x, &acceleration_direction.y, &acceleration_direction.z);
	acceleration_magnitude = psmove_3axisvector_normalize_with_default(&acceleration_direction, k_psmove_vector_zero);

	isOk =
		is_nearly_equal(1.f, acceleration_magnitude, 0.1f) &&
		psmove_3axisvector_dot(&k_identity_gravity_vector, &acceleration_direction) >= k_cosine_10_degrees;

	return isOk;
}