Files
kaizen/lib/source/gainput/builtin/GainputInputDeviceBuiltInAndroid.h
Simone 4e42229bdd Squashed 'external/gainput/' content from commit 2be0a50
git-subtree-dir: external/gainput
git-subtree-split: 2be0a50089eafcc6fccb66142180082e48f27f4c
2024-01-22 08:51:55 +01:00

204 lines
6.0 KiB
C++

#ifndef GAINPUTINPUTDEVICEBUILTINANDROID_H_
#define GAINPUTINPUTDEVICEBUILTINANDROID_H_
#include <android/sensor.h>
namespace gainput
{
class InputDeviceBuiltInImplAndroid : public InputDeviceBuiltInImpl
{
public:
InputDeviceBuiltInImplAndroid(InputManager& manager, InputDevice& device, unsigned index, InputState& state, InputState& previousState) :
manager_(manager),
device_(device),
state_(state),
previousState_(previousState),
deviceState_(InputDevice::DS_UNAVAILABLE),
buttonDialect_(manager_.GetAllocator()),
sensorManager_(0),
accelerometerSensor_(0),
gyroscopeSensor_(0),
sensorEventQueue_(0),
gravityInitialized_(false)
{
ALooper* looper = ALooper_forThread();
if (!looper)
{
looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
}
if (!looper)
{
return;
}
sensorManager_ = ASensorManager_getInstance();
if (!sensorManager_)
{
return;
}
sensorEventQueue_ = ASensorManager_createEventQueue(sensorManager_, looper, ALOOPER_POLL_CALLBACK, NULL, NULL);
if (!sensorEventQueue_)
{
return;
}
accelerometerSensor_ = ASensorManager_getDefaultSensor(sensorManager_, ASENSOR_TYPE_ACCELEROMETER);
if (accelerometerSensor_)
{
ASensorEventQueue_setEventRate(sensorEventQueue_, accelerometerSensor_, ASensor_getMinDelay(accelerometerSensor_));
ASensorEventQueue_enableSensor(sensorEventQueue_, accelerometerSensor_);
}
gyroscopeSensor_ = ASensorManager_getDefaultSensor(sensorManager_, ASENSOR_TYPE_GYROSCOPE);
if (gyroscopeSensor_)
{
ASensorEventQueue_setEventRate(sensorEventQueue_, gyroscopeSensor_, ASensor_getMinDelay(gyroscopeSensor_));
ASensorEventQueue_enableSensor(sensorEventQueue_, gyroscopeSensor_);
}
magneticFieldSensor_ = ASensorManager_getDefaultSensor(sensorManager_, ASENSOR_TYPE_MAGNETIC_FIELD);
if (magneticFieldSensor_)
{
ASensorEventQueue_setEventRate(sensorEventQueue_, magneticFieldSensor_, ASensor_getMinDelay(magneticFieldSensor_));
ASensorEventQueue_enableSensor(sensorEventQueue_, magneticFieldSensor_);
}
deviceState_ = InputDevice::DS_OK;
}
~InputDeviceBuiltInImplAndroid()
{
if (!sensorManager_)
{
return;
}
if (!sensorEventQueue_)
{
return;
}
if (accelerometerSensor_)
{
ASensorEventQueue_disableSensor(sensorEventQueue_, accelerometerSensor_);
}
if (gyroscopeSensor_)
{
ASensorEventQueue_disableSensor(sensorEventQueue_, gyroscopeSensor_);
}
if (magneticFieldSensor_)
{
ASensorEventQueue_disableSensor(sensorEventQueue_, magneticFieldSensor_);
}
ASensorManager_destroyEventQueue(sensorManager_, sensorEventQueue_);
}
InputDevice::DeviceVariant GetVariant() const
{
return InputDevice::DV_STANDARD;
}
void Update(InputDeltaState* delta)
{
ASensorEvent event;
while (ASensorEventQueue_getEvents(sensorEventQueue_, &event, 1) > 0)
{
if (event.type == ASENSOR_TYPE_ACCELEROMETER)
{
// https://developer.android.com/reference/android/hardware/SensorEvent.html#values
static const float kAlpha = 0.8f;
if (!gravityInitialized_)
{
gravity_[0] = event.acceleration.x / ASENSOR_STANDARD_GRAVITY;
gravity_[1] = event.acceleration.y / ASENSOR_STANDARD_GRAVITY;
gravity_[2] = event.acceleration.z / ASENSOR_STANDARD_GRAVITY;
gravityInitialized_ = true;
}
gravity_[0] = kAlpha * gravity_[0] + (1.0f - kAlpha) * (event.acceleration.x / ASENSOR_STANDARD_GRAVITY);
gravity_[1] = kAlpha * gravity_[1] + (1.0f - kAlpha) * (event.acceleration.y / ASENSOR_STANDARD_GRAVITY);
gravity_[2] = kAlpha * gravity_[2] + (1.0f - kAlpha) * (event.acceleration.z / ASENSOR_STANDARD_GRAVITY);
float accel[3];
accel[0] = (event.acceleration.x / ASENSOR_STANDARD_GRAVITY) - gravity_[0];
accel[1] = (event.acceleration.y / ASENSOR_STANDARD_GRAVITY) - gravity_[1];
accel[2] = (event.acceleration.z / ASENSOR_STANDARD_GRAVITY) - gravity_[2];
HandleAxis(device_, state_, delta, BuiltInButtonGravityX, gravity_[0]);
HandleAxis(device_, state_, delta, BuiltInButtonGravityY, gravity_[1]);
HandleAxis(device_, state_, delta, BuiltInButtonGravityZ, gravity_[2]);
HandleAxis(device_, state_, delta, BuiltInButtonAccelerationX, accel[0]);
HandleAxis(device_, state_, delta, BuiltInButtonAccelerationY, accel[1]);
HandleAxis(device_, state_, delta, BuiltInButtonAccelerationZ, accel[2]);
}
else if (event.type == ASENSOR_TYPE_GYROSCOPE)
{
HandleAxis(device_, state_, delta, BuiltInButtonGyroscopeX, event.vector.x / ASENSOR_STANDARD_GRAVITY);
HandleAxis(device_, state_, delta, BuiltInButtonGyroscopeY, event.vector.y / ASENSOR_STANDARD_GRAVITY);
HandleAxis(device_, state_, delta, BuiltInButtonGyroscopeZ, event.vector.z / ASENSOR_STANDARD_GRAVITY);
}
else if (event.type == ASENSOR_TYPE_MAGNETIC_FIELD)
{
HandleAxis(device_, state_, delta, BuiltInButtonMagneticFieldX, event.magnetic.x / ASENSOR_MAGNETIC_FIELD_EARTH_MAX);
HandleAxis(device_, state_, delta, BuiltInButtonMagneticFieldY, event.magnetic.y / ASENSOR_MAGNETIC_FIELD_EARTH_MAX);
HandleAxis(device_, state_, delta, BuiltInButtonMagneticFieldZ, event.magnetic.z / ASENSOR_MAGNETIC_FIELD_EARTH_MAX);
}
}
}
InputDevice::DeviceState GetState() const
{
return deviceState_;
}
bool IsValidButton(DeviceButtonId deviceButton) const
{
if (deviceButton <= BuiltInButtonAccelerationZ && accelerometerSensor_)
{
return true;
}
if (deviceButton >= BuiltInButtonGyroscopeX && deviceButton <= BuiltInButtonGyroscopeZ && gyroscopeSensor_)
{
return true;
}
if (deviceButton >= BuiltInButtonMagneticFieldX && deviceButton <= BuiltInButtonMagneticFieldZ && magneticFieldSensor_)
{
return true;
}
return false;
}
private:
InputManager& manager_;
InputDevice& device_;
InputState& state_;
InputState& previousState_;
InputDevice::DeviceState deviceState_;
HashMap<unsigned, DeviceButtonId> buttonDialect_;
ASensorManager* sensorManager_;
const ASensor* accelerometerSensor_;
const ASensor* gyroscopeSensor_;
const ASensor* magneticFieldSensor_;
ASensorEventQueue* sensorEventQueue_;
float gravity_[3];
bool gravityInitialized_;
};
}
#endif