23 #include <type_traits>
30 for (
int i = 0;
i < 6; ++
i)
32 axis_positions[
i] = 0.0f;
33 axis_activation_min[
i] = 0.15f;
34 axis_activation_max[
i] = 0.98f;
41 axis_activation_min[
static_cast<std::underlying_type_t<gamepad_axis>
>(axis)] = min;
42 axis_activation_max[
static_cast<std::underlying_type_t<gamepad_axis>
>(axis)] = max;
47 axis_response_curves[
static_cast<std::underlying_type_t<gamepad_axis>
>(axis)] = curve;
52 left_deadzone_cross =
cross;
57 right_deadzone_cross =
cross;
62 left_deadzone_roundness = roundness;
67 right_deadzone_roundness = roundness;
72 button_pressed_publisher.publish({
this, button});
77 button_released_publisher.publish({
this, button});
82 const auto axis_index =
static_cast<std::underlying_type_t<gamepad_axis>
>(axis);
89 axis_positions[axis_index] =
position;
95 if (left_deadzone_cross)
96 handle_axial_motion(axis);
103 if (right_deadzone_cross)
104 handle_axial_motion(axis);
112 handle_axial_motion(axis);
119 const auto axis_index =
static_cast<std::underlying_type_t<gamepad_axis>
>(axis);
122 const float activation_min = axis_activation_min[axis_index];
123 const float activation_max = axis_activation_max[axis_index];
124 const float axis_position = axis_positions[axis_index];
128 float remapped_position = 0.0f;
129 if (
std::abs(axis_position) > activation_min)
132 float response =
math::map(
std::abs(axis_position), activation_min, activation_max, 0.0f, 1.0f);
136 response = curve_response(axis, response);
139 response = (axis_position < 0.0f) ? -response : response;
141 remapped_position = response;
144 axis_moved_publisher.publish({
this, axis, remapped_position});
150 const int x_axis_index =
static_cast<std::underlying_type_t<gamepad_axis>
>(axis_x);
151 const int y_axis_index =
static_cast<std::underlying_type_t<gamepad_axis>
>(axis_y);
152 const float x_activation_min = axis_activation_min[x_axis_index];
153 const float x_activation_max = axis_activation_max[x_axis_index];
154 const float y_activation_min = axis_activation_min[y_axis_index];
155 const float y_activation_max = axis_activation_max[y_axis_index];
156 const float x_axis_position = axis_positions[x_axis_index];
157 const float y_axis_position = axis_positions[y_axis_index];
162 const float radius = std::min<float>(x_activation_min, y_activation_min) * deadzone_roundness;
163 const float dx = std::max<float>(0.0f,
std::abs(x_axis_position) - x_activation_min + radius);
164 const float dy = std::max<float>(0.0f,
std::abs(y_axis_position) - y_activation_min + radius);
171 const float ndx = (
distance - x_activation_min) / (x_activation_max - x_activation_min);
172 const float ndy = (
distance - y_activation_min) / (y_activation_max - y_activation_min);
174 float response_x =
std::clamp(nx * ndx, 0.0f, 1.0f);
175 float response_y =
std::clamp(ny * ndy, 0.0f, 1.0f);
177 response_x = curve_response(axis_x, response_x);
178 response_y = curve_response(axis_y, response_y);
181 response_x = (x_axis_position < 0.0f) ? -response_x : response_x;
182 response_y = (y_axis_position < 0.0f) ? -response_y : response_y;
184 axis_moved_publisher.publish({
this, axis_x, response_x});
185 axis_moved_publisher.publish({
this, axis_y, response_y});
189 axis_moved_publisher.publish({
this, axis_x, 0.0f});
190 axis_moved_publisher.publish({
this, axis_y, 0.0f});
194 float gamepad::curve_response(
gamepad_axis axis,
float response)
const
196 const auto axis_index =
static_cast<std::underlying_type_t<gamepad_axis>
>(axis);
199 switch (response_curve)
205 response = response * response;
209 response = response * response * response;
constexpr T map(T x, T from_min, T from_max, T to_min, T to_max) noexcept
Remaps a number from one range to another.
constexpr vector< T, N > abs(const vector< T, N > &x)
Returns the absolute values of each element.
T distance(const vector< T, N > &p0, const vector< T, N > &p1)
Calculates the distance between two points.
constexpr vector< T, N > clamp(const vector< T, N > &x, const vector< T, N > &min, const vector< T, N > &max)
Clamps the values of a vector's elements.
constexpr vector< T, 3 > cross(const vector< T, 3 > &x, const vector< T, 3 > &y) noexcept
Calculates the cross product of two vectors.
vector< T, N > sqrt(const vector< T, N > &x)
Takes the square root of each element.
@ position
Vertex position (vec3)