Some improvements for touch device

This commit is contained in:
Deve
2018-04-10 00:22:09 +02:00
parent 8841200a1c
commit 3f69fd37ed
10 changed files with 212 additions and 144 deletions

View File

@@ -459,6 +459,8 @@ void DeviceManager::updateMultitouchDevice()
{
m_multitouch_device->setPlayer(NULL);
}
m_multitouch_device->updateController();
} // updateMultitouchDevice
//-----------------------------------------------------------------------------

View File

@@ -1192,20 +1192,10 @@ EventPropagation InputManager::input(const SEvent& event)
if (device && device->isAccelerometerActive())
{
m_device_manager->updateMultitouchDevice();
for (unsigned int i = 0; i < device->getButtonsCount(); i++)
{
MultitouchButton* button = device->getButton(i);
if (button->type != BUTTON_STEERING)
continue;
float factor = UserConfigParams::m_multitouch_tilt_factor;
factor = std::max(factor, 0.1f);
button->axis_x = (float)event.AccelerometerEvent.Y / factor;
device->handleControls(button);
}
float factor = UserConfigParams::m_multitouch_tilt_factor;
factor = std::max(factor, 0.1f);
device->updateAxisX(event.AccelerometerEvent.Y / factor);
}
}

View File

@@ -36,7 +36,7 @@ MultitouchDevice::MultitouchDevice()
m_type = DT_MULTITOUCH;
m_name = "Multitouch";
m_player = NULL;
m_accelerometer_active = false;
m_controller = NULL;
#ifdef ANDROID
m_android_device = dynamic_cast<CIrrDeviceAndroid*>(
irr_driver->getDevice());
@@ -136,22 +136,6 @@ void MultitouchDevice::addButton(MultitouchButtonType type, int x, int y,
}
m_buttons.push_back(button);
#ifdef ANDROID
if (button->type == MultitouchButtonType::BUTTON_STEERING)
{
if (UserConfigParams::m_multitouch_controls == 2 &&
!m_android_device->isAccelerometerActive())
{
m_android_device->activateAccelerometer(1.0f / 30);
if (m_android_device->isAccelerometerActive())
{
m_accelerometer_active = true;
}
}
}
#endif
} // addButton
// ----------------------------------------------------------------------------
@@ -159,15 +143,6 @@ void MultitouchDevice::addButton(MultitouchButtonType type, int x, int y,
*/
void MultitouchDevice::clearButtons()
{
#ifdef ANDROID
if (m_accelerometer_active == true &&
m_android_device->isAccelerometerActive())
{
m_android_device->deactivateAccelerometer();
m_accelerometer_active = false;
}
#endif
for (MultitouchButton* button : m_buttons)
{
delete button;
@@ -198,6 +173,45 @@ void MultitouchDevice::reset()
}
} // reset
// ----------------------------------------------------------------------------
/** Activates accelerometer
*/
void MultitouchDevice::activateAccelerometer()
{
#ifdef ANDROID
if (!m_android_device->isAccelerometerActive())
{
m_android_device->activateAccelerometer(1.0f / 30);
}
#endif
}
// ----------------------------------------------------------------------------
/** Deativates accelerometer
*/
void MultitouchDevice::deactivateAccelerometer()
{
#ifdef ANDROID
if (m_android_device->isAccelerometerActive())
{
m_android_device->deactivateAccelerometer();
}
#endif
}
// ----------------------------------------------------------------------------
/** Get accelerometer state
* \return true if accelerometer is active
*/
bool MultitouchDevice::isAccelerometerActive()
{
#ifdef ANDROID
return m_android_device->isAccelerometerActive();
#endif
return false;
}
// ----------------------------------------------------------------------------
/** The function that is executed when touch event occurs. It updates the
* buttons state when it's needed.
@@ -241,13 +255,15 @@ void MultitouchDevice::updateDeviceState(unsigned int event_id)
if (button->pressed == true)
{
updateButtonAxes(button,
(float)(event.x - button->x) / (button->width/2) - 1,
(float)(event.y - button->y) / (button->height/2) - 1);
button->axis_x =
(float)(event.x - button->x) / (button->width/2) - 1;
button->axis_y =
(float)(event.y - button->y) / (button->height/2) - 1;
}
else
{
updateButtonAxes(button, 0.0f, 0.0f);
button->axis_x = 0.0f;
button->axis_y = 0.0f;
}
if (prev_axis_x != button->axis_x ||
@@ -298,35 +314,95 @@ float MultitouchDevice::getSteeringFactor(float value)
m_deadzone_center), 1.0f);
}
/** Updates the button axes. It leaves X axis untouched if the accelerometer is
* used for turning left/right
* \param button A button that should be updated
* \param x A value from 0 to 1
* \param y A value from 0 to 1
*/
void MultitouchDevice::updateButtonAxes(MultitouchButton* button, float x,
float y)
{
if (m_accelerometer_active == false)
{
button->axis_x = x;
}
// ----------------------------------------------------------------------------
button->axis_y = y;
void MultitouchDevice::updateAxisX(float value)
{
if (m_controller == NULL)
return;
if (value < -m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(value));
m_controller->action(PA_STEER_LEFT, int(factor * Input::MAX_VALUE));
}
else if (value > m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(value));
m_controller->action(PA_STEER_RIGHT, int(factor * Input::MAX_VALUE));
}
else
{
m_controller->action(PA_STEER_LEFT, 0);
m_controller->action(PA_STEER_RIGHT, 0);
}
}
// ----------------------------------------------------------------------------
void MultitouchDevice::updateAxisY(float value)
{
if (m_controller == NULL)
return;
if (value < -m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(value));
m_controller->action(PA_ACCEL, int(factor * Input::MAX_VALUE));
}
else if (value > m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(value));
m_controller->action(PA_BRAKE, int(factor * Input::MAX_VALUE));
}
else
{
m_controller->action(PA_BRAKE, 0);
m_controller->action(PA_ACCEL, 0);
}
}
// ----------------------------------------------------------------------------
/** Sends proper action for player controller depending on the button type
* and state.
* \param button The button that should be handled.
*/
void MultitouchDevice::handleControls(MultitouchButton* button)
{
if (m_player == NULL)
if (m_controller == NULL)
return;
if (button->type == MultitouchButtonType::BUTTON_STEERING)
{
#ifdef ANDROID
if (!m_android_device->isAccelerometerActive())
#endif
{
updateAxisX(button->axis_x);
}
updateAxisY(button->axis_y);
}
else
{
if (button->action != PA_BEFORE_FIRST)
{
int value = button->pressed ? Input::MAX_VALUE : 0;
m_controller->action(button->action, value);
}
}
}
// ----------------------------------------------------------------------------
void MultitouchDevice::updateController()
{
if (m_player == NULL)
{
m_controller = NULL;
return;
}
// Handle multitouch events only when race is running. It avoids to process
// it when pause dialog is active during the race. And there is no reason
@@ -335,60 +411,20 @@ void MultitouchDevice::handleControls(MultitouchButton* button)
GUIEngine::ModalDialog::isADialogActive() ||
GUIEngine::ScreenKeyboard::isActive() ||
race_manager->isWatchingReplay())
{
m_controller = NULL;
return;
}
AbstractKart* pk = m_player->getKart();
if (pk == NULL)
return;
Controller* controller = pk->getController();
if (controller == NULL)
return;
if (button->type == MultitouchButtonType::BUTTON_STEERING)
{
if (button->axis_y < -m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(button->axis_y));
controller->action(PA_ACCEL, int(factor * Input::MAX_VALUE));
}
else if (button->axis_y > m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(button->axis_y));
controller->action(PA_BRAKE, int(factor * Input::MAX_VALUE));
}
else
{
controller->action(PA_BRAKE, 0);
controller->action(PA_ACCEL, 0);
}
m_controller = NULL;
return;
}
if (button->axis_x < -m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(button->axis_x));
controller->action(PA_STEER_LEFT, int(factor * Input::MAX_VALUE));
}
else if (button->axis_x > m_deadzone_center)
{
float factor = getSteeringFactor(std::abs(button->axis_x));
controller->action(PA_STEER_RIGHT, int(factor * Input::MAX_VALUE));
}
else
{
controller->action(PA_STEER_LEFT, 0);
controller->action(PA_STEER_RIGHT, 0);
}
}
else
{
if (button->action != PA_BEFORE_FIRST)
{
int value = button->pressed ? Input::MAX_VALUE : 0;
controller->action(button->action, value);
}
}
} // handleControls
m_controller = pk->getController();
}
// ----------------------------------------------------------------------------

View File

@@ -68,11 +68,15 @@ struct MultitouchButton
float axis_y;
};
class Controller;
class MultitouchDevice : public InputDevice
{
private:
/** The list of pointers to all created buttons */
std::vector<MultitouchButton*> m_buttons;
Controller* m_controller;
/** The parameter that is used for steering button and determines dead area
* in a center of button */
@@ -82,16 +86,13 @@ private:
* at the edge of button */
float m_deadzone_edge;
/** True if accelerometer is in use */
bool m_accelerometer_active;
#ifdef ANDROID
/** Pointer to the Android irrlicht device */
CIrrDeviceAndroid* m_android_device;
#endif
float getSteeringFactor(float value);
void updateButtonAxes(MultitouchButton* button, float x, float y);
void handleControls(MultitouchButton* button);
public:
/** The array that contains data for all multitouch input events */
@@ -119,12 +120,14 @@ public:
/** Returns pointer to the selected button */
MultitouchButton* getButton(unsigned int i) {return m_buttons.at(i);}
/** True if accelerometer is in use */
bool isAccelerometerActive() {return m_accelerometer_active;}
void activateAccelerometer();
void deactivateAccelerometer();
bool isAccelerometerActive();
void updateAxisX(float value);
void updateAxisY(float value);
void updateDeviceState(unsigned int event_id);
void handleControls(MultitouchButton* button);
void updateController();
void updateConfigParams();
}; // MultitouchDevice