Implemented gyroscope controls, no camera rotation and no filtering algorithm yet
This commit is contained in:
parent
64e0c6312e
commit
572132be46
@ -202,7 +202,8 @@ bool EventHandler::OnEvent (const SEvent &event)
|
||||
event.EventType == EET_TOUCH_INPUT_EVENT ||
|
||||
event.EventType == EET_KEY_INPUT_EVENT ||
|
||||
event.EventType == EET_JOYSTICK_INPUT_EVENT ||
|
||||
event.EventType == EET_ACCELEROMETER_EVENT)
|
||||
event.EventType == EET_ACCELEROMETER_EVENT ||
|
||||
event.EventType == EET_GYROSCOPE_EVENT)
|
||||
{
|
||||
// Remember the mouse position
|
||||
if (event.EventType == EET_MOUSE_INPUT_EVENT &&
|
||||
|
@ -937,6 +937,7 @@ bool InputManager::masterPlayerOnly() const
|
||||
*/
|
||||
EventPropagation InputManager::input(const SEvent& event)
|
||||
{
|
||||
const float ORIENTATION_MULTIPLIER = 10.0f;
|
||||
if (event.EventType == EET_JOYSTICK_INPUT_EVENT)
|
||||
{
|
||||
// Axes - FIXME, instead of checking all of them, ask the bindings
|
||||
@ -1238,7 +1239,29 @@ EventPropagation InputManager::input(const SEvent& event)
|
||||
|
||||
float factor = UserConfigParams::m_multitouch_tilt_factor;
|
||||
factor = std::max(factor, 0.1f);
|
||||
device->updateAxisX(float(event.AccelerometerEvent.Y) / factor);
|
||||
if (UserConfigParams::m_multitouch_controls == MULTITOUCH_CONTROLS_GYROSCOPE)
|
||||
{
|
||||
device->updateOrientationFromAccelerometer(event.AccelerometerEvent.X, event.AccelerometerEvent.Y);
|
||||
device->updateAxisX(device->getOrientation() * ORIENTATION_MULTIPLIER / factor);
|
||||
}
|
||||
else
|
||||
{
|
||||
device->updateAxisX(float(event.AccelerometerEvent.Y) / factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.EventType == EET_GYROSCOPE_EVENT)
|
||||
{
|
||||
MultitouchDevice* device = m_device_manager->getMultitouchDevice();
|
||||
|
||||
if (device && device->isGyroscopeActive())
|
||||
{
|
||||
m_device_manager->updateMultitouchDevice();
|
||||
|
||||
float factor = UserConfigParams::m_multitouch_tilt_factor;
|
||||
factor = std::max(factor, 0.1f);
|
||||
device->updateOrientationFromGyroscope(event.GyroscopeEvent.Z);
|
||||
device->updateAxisX(device->getOrientation() * ORIENTATION_MULTIPLIER / factor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,6 +171,9 @@ void MultitouchDevice::reset()
|
||||
event.x = 0;
|
||||
event.y = 0;
|
||||
}
|
||||
|
||||
m_orientation = 0.0f;
|
||||
m_gyro_time = 0.0;
|
||||
} // reset
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -212,6 +215,45 @@ bool MultitouchDevice::isAccelerometerActive()
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Activates gyroscope
|
||||
*/
|
||||
void MultitouchDevice::activateGyroscope()
|
||||
{
|
||||
#ifdef ANDROID
|
||||
if (!m_android_device->isGyroscopeActive())
|
||||
{
|
||||
m_android_device->activateGyroscope(1.0f / 60); // Assume 60 FPS, some phones can do 90 and 120 FPS but we won't handle them now
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Deativates gyroscope
|
||||
*/
|
||||
void MultitouchDevice::deactivateGyroscope()
|
||||
{
|
||||
#ifdef ANDROID
|
||||
if (m_android_device->isGyroscopeActive())
|
||||
{
|
||||
m_android_device->deactivateGyroscope();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Get gyroscope state
|
||||
* \return true if gyroscope is active
|
||||
*/
|
||||
bool MultitouchDevice::isGyroscopeActive()
|
||||
{
|
||||
#ifdef ANDROID
|
||||
return m_android_device->isGyroscopeActive();
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** The function that is executed when touch event occurs. It updates the
|
||||
* buttons state when it's needed.
|
||||
@ -382,6 +424,87 @@ void MultitouchDevice::updateAxisY(float value)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
float MultitouchDevice::getOrientation()
|
||||
{
|
||||
return m_orientation;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void MultitouchDevice::updateOrientationFromAccelerometer(float x, float y)
|
||||
{
|
||||
const float ACCEL_DISCARD_THRESHOLD = 4.0f;
|
||||
const float ACCEL_MULTIPLIER = 0.05f; // Slowly adjust the angle over time, this prevents shaking
|
||||
const float ACCEL_CHANGE_THRESHOLD = 0.01f; // ~0.5 degrees
|
||||
|
||||
if (fabsf(x) + fabsf(y) < ACCEL_DISCARD_THRESHOLD)
|
||||
{
|
||||
// The device is flat on the table, cannot reliably determine the orientation
|
||||
return;
|
||||
}
|
||||
|
||||
float angle = atan2f(y, x);
|
||||
if (angle > (M_PI / 2.0))
|
||||
{
|
||||
angle = (M_PI / 2.0);
|
||||
}
|
||||
if (angle < -(M_PI / 2.0))
|
||||
{
|
||||
angle = -(M_PI / 2.0);
|
||||
}
|
||||
|
||||
float delta = angle - m_orientation;
|
||||
delta *= ACCEL_MULTIPLIER;
|
||||
if (delta > ACCEL_CHANGE_THRESHOLD)
|
||||
{
|
||||
delta = ACCEL_CHANGE_THRESHOLD;
|
||||
}
|
||||
if (delta < -ACCEL_CHANGE_THRESHOLD)
|
||||
{
|
||||
delta = -ACCEL_CHANGE_THRESHOLD;
|
||||
}
|
||||
|
||||
m_orientation += delta;
|
||||
|
||||
//Log::warn("Accel", "X %03.4f Y %03.4f angle %03.4f delta %03.4f orientation %03.4f", x, y, angle, delta, m_orientation);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void MultitouchDevice::updateOrientationFromGyroscope(float z)
|
||||
{
|
||||
const float GYRO_SPEED_THRESHOLD = 0.005f;
|
||||
|
||||
double now = StkTime::getRealTime();
|
||||
float timedelta = now - m_gyro_time;
|
||||
m_gyro_time = now;
|
||||
if (timedelta > 0.5f)
|
||||
{
|
||||
timedelta = 0.1f;
|
||||
}
|
||||
|
||||
float angular_speed = -z;
|
||||
|
||||
if (fabsf(angular_speed) < GYRO_SPEED_THRESHOLD)
|
||||
{
|
||||
angular_speed = 0.0f;
|
||||
}
|
||||
|
||||
m_orientation += angular_speed * timedelta;
|
||||
if (m_orientation > (M_PI / 2.0))
|
||||
{
|
||||
m_orientation = (M_PI / 2.0);
|
||||
}
|
||||
if (m_orientation < -(M_PI / 2.0))
|
||||
{
|
||||
m_orientation = -(M_PI / 2.0);
|
||||
}
|
||||
|
||||
//Log::warn("Gyro", "Z %03.4f angular_speed %03.4f delta %03.4f orientation %03.4f", z, angular_speed, angular_speed * timedelta, m_orientation);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** Sends proper action for player controller depending on the button type
|
||||
* and state.
|
||||
* \param button The button that should be handled.
|
||||
|
@ -87,6 +87,9 @@ private:
|
||||
* at the edge of button */
|
||||
float m_deadzone_edge;
|
||||
|
||||
float m_orientation;
|
||||
double m_gyro_time;
|
||||
|
||||
#ifdef ANDROID
|
||||
/** Pointer to the Android irrlicht device */
|
||||
CIrrDeviceAndroid* m_android_device;
|
||||
@ -125,9 +128,16 @@ public:
|
||||
void activateAccelerometer();
|
||||
void deactivateAccelerometer();
|
||||
bool isAccelerometerActive();
|
||||
|
||||
|
||||
void activateGyroscope();
|
||||
void deactivateGyroscope();
|
||||
bool isGyroscopeActive();
|
||||
|
||||
void updateAxisX(float value);
|
||||
void updateAxisY(float value);
|
||||
float getOrientation();
|
||||
void updateOrientationFromAccelerometer(float x, float y);
|
||||
void updateOrientationFromGyroscope(float z);
|
||||
void updateDeviceState(unsigned int event_id);
|
||||
void updateController();
|
||||
void updateConfigParams();
|
||||
|
@ -104,6 +104,11 @@ void RaceGUIMultitouch::close()
|
||||
{
|
||||
m_device->deactivateAccelerometer();
|
||||
}
|
||||
|
||||
if (m_device->isGyroscopeActive())
|
||||
{
|
||||
m_device->deactivateGyroscope();
|
||||
}
|
||||
} // close
|
||||
|
||||
|
||||
@ -120,6 +125,11 @@ void RaceGUIMultitouch::init()
|
||||
{
|
||||
m_device->activateAccelerometer();
|
||||
}
|
||||
if (UserConfigParams::m_multitouch_controls == MULTITOUCH_CONTROLS_GYROSCOPE)
|
||||
{
|
||||
m_device->activateAccelerometer();
|
||||
m_device->activateGyroscope();
|
||||
}
|
||||
|
||||
const float scale = UserConfigParams::m_multitouch_scale;
|
||||
|
||||
@ -155,7 +165,7 @@ void RaceGUIMultitouch::init()
|
||||
|
||||
m_height = (unsigned int)(2 * col_size + margin / 2);
|
||||
|
||||
if (m_device->isAccelerometerActive())
|
||||
if (m_device->isAccelerometerActive() || m_device->isGyroscopeActive())
|
||||
{
|
||||
m_device->addButton(BUTTON_UP_DOWN,
|
||||
int(steering_accel_x), int(steering_accel_y),
|
||||
|
Loading…
x
Reference in New Issue
Block a user