32 const PN_stdfloat DriveInterface::_hpr_quantize = 0.001;
34 DriveInterface::KeyHeld::
39 _effect_at_change = 0.0f;
42 PN_stdfloat DriveInterface::KeyHeld::
43 get_effect(PN_stdfloat ramp_up_time, PN_stdfloat ramp_down_time) {
48 if (ramp_up_time == 0.0f) {
52 PN_stdfloat change = elapsed / ramp_up_time;
53 _effect = min(_effect_at_change + change, (PN_stdfloat)1.0);
58 if (ramp_down_time == 0.0f) {
62 PN_stdfloat change = elapsed / ramp_down_time;
63 _effect = max(_effect_at_change - change, (PN_stdfloat)0.0);
69 void DriveInterface::KeyHeld::
74 _effect_at_change = _effect;
78 void DriveInterface::KeyHeld::
83 _effect_at_change = 0.0f;
86 bool DriveInterface::KeyHeld::
87 operator < (
const DriveInterface::KeyHeld &other)
const {
88 if (_down != other._down) {
94 return _changed_time > other._changed_time;
101 DriveInterface(
const std::string &name) :
104 _xy_input = define_input(
"xy", EventStoreVec2::get_class_type());
105 _button_events_input = define_input(
"button_events", ButtonEventList::get_class_type());
107 _transform_output = define_output(
"transform", TransformState::get_class_type());
108 _velocity_output = define_output(
"velocity", EventStoreVec3::get_class_type());
110 _transform = TransformState::make_identity();
113 _forward_speed = drive_forward_speed;
114 _reverse_speed = drive_reverse_speed;
115 _rotate_speed = drive_rotate_speed;
116 _vertical_dead_zone = drive_vertical_dead_zone;
117 _horizontal_dead_zone = drive_horizontal_dead_zone;
118 _vertical_center = drive_vertical_center;
119 _horizontal_center = drive_horizontal_center;
121 _vertical_ramp_up_time = drive_vertical_ramp_up_time;
122 _vertical_ramp_down_time = drive_vertical_ramp_down_time;
123 _horizontal_ramp_up_time = drive_horizontal_ramp_up_time;
124 _horizontal_ramp_down_time = drive_horizontal_ramp_down_time;
129 _xyz.set(0.0f, 0.0f, 0.0f);
130 _hpr.set(0.0f, 0.0f, 0.0f);
132 _ignore_mouse =
false;
133 _force_mouse =
false;
134 _stop_this_frame =
false;
154 _xyz.set(0.0f, 0.0f, 0.0f);
155 _hpr.set(0.0f, 0.0f, 0.0f);
159 _right_arrow.clear();
175 LVecBase3 scale, shear;
176 decompose_matrix(mat, scale, shear, _hpr, _xyz);
185 LVecBase3(1.0f, 1.0f, 1.0f),
186 LVecBase3(0.0f, 0.0f, 0.0f),
199 _transform = TransformState::make_pos_hpr(_xyz, _hpr);
200 _velocity->set_value(_vel);
217 void DriveInterface::
218 apply(
double x,
double y,
bool any_button) {
223 if (any_button || _force_mouse) {
234 PN_stdfloat dead_zone_top = _vertical_center + _vertical_dead_zone;
235 PN_stdfloat dead_zone_bottom = _vertical_center - _vertical_dead_zone;
237 if (y >= dead_zone_top) {
240 PN_stdfloat throttle =
242 (min(y, 1.0) - dead_zone_top) /
243 (1.0f - dead_zone_top);
244 _speed = throttle * _forward_speed;
246 }
else if (y <= dead_zone_bottom) {
248 PN_stdfloat throttle =
249 (max(y, -1.0) - dead_zone_bottom) /
250 (-1.0f - dead_zone_bottom);
251 _speed = -throttle * _reverse_speed;
256 PN_stdfloat dead_zone_right = _horizontal_center + _horizontal_dead_zone;
257 PN_stdfloat dead_zone_left = _horizontal_center - _horizontal_dead_zone;
259 if (x >= dead_zone_right) {
262 PN_stdfloat throttle =
263 (min(x, 1.0) - dead_zone_right) /
264 (1.0f - dead_zone_right);
265 _rot_speed = throttle * _rotate_speed;
267 }
else if (x <= dead_zone_left) {
269 PN_stdfloat throttle =
270 (max(x, -1.0) - dead_zone_left) /
271 (-1.0f - dead_zone_left);
272 _rot_speed = -throttle * _rotate_speed;
280 PN_stdfloat throttle;
282 if (_up_arrow < _down_arrow) {
283 throttle = _up_arrow.get_effect(_vertical_ramp_up_time,
284 _vertical_ramp_down_time);
285 _speed = throttle * _forward_speed;
286 _down_arrow._effect = 0.0f;
289 throttle = _down_arrow.get_effect(_vertical_ramp_up_time,
290 _vertical_ramp_down_time);
291 _speed = -throttle * _reverse_speed;
292 _up_arrow._effect = 0.0f;
296 if (_right_arrow < _left_arrow) {
297 throttle = _right_arrow.get_effect(_horizontal_ramp_up_time,
298 _horizontal_ramp_down_time);
299 _rot_speed = throttle * _rotate_speed;
300 _left_arrow._effect = 0.0f;
303 throttle = _left_arrow.get_effect(_horizontal_ramp_up_time,
304 _horizontal_ramp_down_time);
305 _rot_speed = -throttle * _rotate_speed;
306 _right_arrow._effect = 0.0f;
308 _right_arrow._effect = throttle;
309 _left_arrow._effect = throttle;
312 if (_speed == 0.0f && _rot_speed == 0.0f) {
313 _vel.set(0.0f, 0.0f, 0.0f);
320 if (_stop_this_frame) {
323 _stop_this_frame =
false;
330 rot_mat.set_rotate_mat_normaxis(_hpr[0], LVector3::up());
333 _vel = LVector3::forward() * distance;
334 LVector3 step = (_vel * rot_mat);
338 switch (get_default_coordinate_system()) {
365 void DriveInterface::
369 bool required_buttons_match;
370 const ButtonEventList *button_events = check_button_events(input, required_buttons_match);
378 if (required_buttons_match && input.
has_data(_xy_input)) {
389 if (required_buttons_match && button_events !=
nullptr) {
392 for (
int i = 0; i < num_events; i++) {
394 if (be._type != ButtonEvent::T_keystroke) {
395 bool down = (be._type != ButtonEvent::T_up);
397 if (be._button == KeyboardButton::up()) {
398 _up_arrow.set_key(down);
399 }
else if (be._button == KeyboardButton::down()) {
400 _down_arrow.set_key(down);
401 }
else if (be._button == KeyboardButton::left()) {
402 _left_arrow.set_key(down);
403 }
else if (be._button == KeyboardButton::right()) {
404 _right_arrow.set_key(down);
411 _transform = TransformState::make_pos_hpr(_xyz, _hpr);
412 _velocity->set_value(_vel);