Add raw strength value for internal use

This commit is contained in:
Aaron Franke 2020-10-24 05:22:35 -04:00
parent 10fd107599
commit 195d58be0f
No known key found for this signature in database
GPG Key ID: 40A1750B977E56BF
6 changed files with 74 additions and 27 deletions

View File

@ -326,6 +326,15 @@ float Input::get_action_strength(const StringName &p_action) const {
return E->get().strength; return E->get().strength;
} }
float Input::get_action_raw_strength(const StringName &p_action) const {
const Map<StringName, Action>::Element *E = action_state.find(p_action);
if (!E) {
return 0.0f;
}
return E->get().raw_strength;
}
float Input::get_joy_axis(int p_device, int p_axis) const { float Input::get_joy_axis(int p_device, int p_axis) const {
_THREAD_SAFE_METHOD_ _THREAD_SAFE_METHOD_
int c = _combine_device(p_axis, p_device); int c = _combine_device(p_axis, p_device);
@ -603,10 +612,12 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
action.physics_frame = Engine::get_singleton()->get_physics_frames(); action.physics_frame = Engine::get_singleton()->get_physics_frames();
action.idle_frame = Engine::get_singleton()->get_idle_frames(); action.idle_frame = Engine::get_singleton()->get_idle_frames();
action.pressed = p_event->is_action_pressed(E->key()); action.pressed = p_event->is_action_pressed(E->key());
action.strength = 0.f; action.strength = 0.0f;
action.raw_strength = 0.0f;
action_state[E->key()] = action; action_state[E->key()] = action;
} }
action_state[E->key()].strength = p_event->get_action_strength(E->key()); action_state[E->key()].strength = p_event->get_action_strength(E->key());
action_state[E->key()].raw_strength = p_event->get_action_raw_strength(E->key());
} }
} }

View File

@ -117,6 +117,7 @@ private:
uint64_t idle_frame; uint64_t idle_frame;
bool pressed; bool pressed;
float strength; float strength;
float raw_strength;
}; };
Map<StringName, Action> action_state; Map<StringName, Action> action_state;
@ -266,6 +267,7 @@ public:
bool is_action_just_pressed(const StringName &p_action) const; bool is_action_just_pressed(const StringName &p_action) const;
bool is_action_just_released(const StringName &p_action) const; bool is_action_just_released(const StringName &p_action) const;
float get_action_strength(const StringName &p_action) const; float get_action_strength(const StringName &p_action) const;
float get_action_raw_strength(const StringName &p_action) const;
float get_joy_axis(int p_device, int p_axis) const; float get_joy_axis(int p_device, int p_axis) const;
String get_joy_name(int p_idx); String get_joy_name(int p_idx);

View File

@ -61,12 +61,17 @@ bool InputEvent::is_action_released(const StringName &p_action) const {
} }
float InputEvent::get_action_strength(const StringName &p_action) const { float InputEvent::get_action_strength(const StringName &p_action) const {
bool pressed;
float strength; float strength;
bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, &pressed, &strength); bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, nullptr, &strength);
return valid ? strength : 0.0f; return valid ? strength : 0.0f;
} }
float InputEvent::get_action_raw_strength(const StringName &p_action) const {
float raw_strength;
bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, nullptr, nullptr, &raw_strength);
return valid ? raw_strength : 0.0f;
}
bool InputEvent::is_pressed() const { bool InputEvent::is_pressed() const {
return false; return false;
} }
@ -83,7 +88,7 @@ String InputEvent::as_text() const {
return String(); return String();
} }
bool InputEvent::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { bool InputEvent::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const {
return false; return false;
} }
@ -307,7 +312,7 @@ String InputEventKey::as_text() const {
return kc; return kc;
} }
bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const {
Ref<InputEventKey> key = p_event; Ref<InputEventKey> key = p_event;
if (key.is_null()) { if (key.is_null()) {
return false; return false;
@ -329,8 +334,12 @@ bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed
if (p_pressed != nullptr) { if (p_pressed != nullptr) {
*p_pressed = key->is_pressed(); *p_pressed = key->is_pressed();
} }
float strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
if (p_strength != nullptr) { if (p_strength != nullptr) {
*p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f; *p_strength = strength;
}
if (p_raw_strength != nullptr) {
*p_raw_strength = strength;
} }
} }
return match; return match;
@ -470,7 +479,7 @@ Ref<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, co
return mb; return mb;
} }
bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const {
Ref<InputEventMouseButton> mb = p_event; Ref<InputEventMouseButton> mb = p_event;
if (mb.is_null()) { if (mb.is_null()) {
return false; return false;
@ -481,8 +490,12 @@ bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool *p
if (p_pressed != nullptr) { if (p_pressed != nullptr) {
*p_pressed = mb->is_pressed(); *p_pressed = mb->is_pressed();
} }
float strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
if (p_strength != nullptr) { if (p_strength != nullptr) {
*p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f; *p_strength = strength;
}
if (p_raw_strength != nullptr) {
*p_raw_strength = strength;
} }
} }
@ -713,7 +726,7 @@ bool InputEventJoypadMotion::is_pressed() const {
return Math::abs(axis_value) >= 0.5f; return Math::abs(axis_value) >= 0.5f;
} }
bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const {
Ref<InputEventJoypadMotion> jm = p_event; Ref<InputEventJoypadMotion> jm = p_event;
if (jm.is_null()) { if (jm.is_null()) {
return false; return false;
@ -721,8 +734,9 @@ bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool *
bool match = (axis == jm->axis); // Matches even if not in the same direction, but returns a "not pressed" event. bool match = (axis == jm->axis); // Matches even if not in the same direction, but returns a "not pressed" event.
if (match) { if (match) {
float jm_abs_axis_value = Math::abs(jm->get_axis_value());
bool same_direction = (((axis_value < 0) == (jm->axis_value < 0)) || jm->axis_value == 0); bool same_direction = (((axis_value < 0) == (jm->axis_value < 0)) || jm->axis_value == 0);
bool pressed = same_direction ? Math::abs(jm->get_axis_value()) >= p_deadzone : false; bool pressed = same_direction && jm_abs_axis_value >= p_deadzone;
if (p_pressed != nullptr) { if (p_pressed != nullptr) {
*p_pressed = pressed; *p_pressed = pressed;
} }
@ -731,12 +745,19 @@ bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool *
if (p_deadzone == 1.0f) { if (p_deadzone == 1.0f) {
*p_strength = 1.0f; *p_strength = 1.0f;
} else { } else {
*p_strength = CLAMP(Math::inverse_lerp(p_deadzone, 1.0f, Math::abs(jm->get_axis_value())), 0.0f, 1.0f); *p_strength = CLAMP(Math::inverse_lerp(p_deadzone, 1.0f, jm_abs_axis_value), 0.0f, 1.0f);
} }
} else { } else {
*p_strength = 0.0f; *p_strength = 0.0f;
} }
} }
if (p_raw_strength != nullptr) {
if (same_direction) { // NOT pressed, because we want to ignore the deadzone.
*p_raw_strength = jm_abs_axis_value;
} else {
*p_raw_strength = 0.0f;
}
}
} }
return match; return match;
} }
@ -782,7 +803,7 @@ float InputEventJoypadButton::get_pressure() const {
return pressure; return pressure;
} }
bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const {
Ref<InputEventJoypadButton> jb = p_event; Ref<InputEventJoypadButton> jb = p_event;
if (jb.is_null()) { if (jb.is_null()) {
return false; return false;
@ -793,8 +814,12 @@ bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool *
if (p_pressed != nullptr) { if (p_pressed != nullptr) {
*p_pressed = jb->is_pressed(); *p_pressed = jb->is_pressed();
} }
float strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
if (p_strength != nullptr) { if (p_strength != nullptr) {
*p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f; *p_strength = strength;
}
if (p_raw_strength != nullptr) {
*p_raw_strength = strength;
} }
} }
@ -997,7 +1022,7 @@ bool InputEventAction::is_action(const StringName &p_action) const {
return action == p_action; return action == p_action;
} }
bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const { bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const {
Ref<InputEventAction> act = p_event; Ref<InputEventAction> act = p_event;
if (act.is_null()) { if (act.is_null()) {
return false; return false;
@ -1008,8 +1033,12 @@ bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool *p_pres
if (p_pressed != nullptr) { if (p_pressed != nullptr) {
*p_pressed = act->pressed; *p_pressed = act->pressed;
} }
float strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
if (p_strength != nullptr) { if (p_strength != nullptr) {
*p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f; *p_strength = strength;
}
if (p_raw_strength != nullptr) {
*p_raw_strength = strength;
} }
} }
return match; return match;

View File

@ -173,6 +173,7 @@ public:
bool is_action_pressed(const StringName &p_action, bool p_allow_echo = false) const; bool is_action_pressed(const StringName &p_action, bool p_allow_echo = false) const;
bool is_action_released(const StringName &p_action) const; bool is_action_released(const StringName &p_action) const;
float get_action_strength(const StringName &p_action) const; float get_action_strength(const StringName &p_action) const;
float get_action_raw_strength(const StringName &p_action) const;
// To be removed someday, since they do not make sense for all events // To be removed someday, since they do not make sense for all events
virtual bool is_pressed() const; virtual bool is_pressed() const;
@ -182,7 +183,7 @@ public:
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const; virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const;
virtual bool shortcut_match(const Ref<InputEvent> &p_event) const; virtual bool shortcut_match(const Ref<InputEvent> &p_event) const;
virtual bool is_action_type() const; virtual bool is_action_type() const;
@ -283,7 +284,7 @@ public:
uint32_t get_keycode_with_modifiers() const; uint32_t get_keycode_with_modifiers() const;
uint32_t get_physical_keycode_with_modifiers() const; uint32_t get_physical_keycode_with_modifiers() const;
virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const override; virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override;
virtual bool shortcut_match(const Ref<InputEvent> &p_event) const override; virtual bool shortcut_match(const Ref<InputEvent> &p_event) const override;
virtual bool is_action_type() const override { return true; } virtual bool is_action_type() const override { return true; }
@ -342,7 +343,7 @@ public:
bool is_doubleclick() const; bool is_doubleclick() const;
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override; virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const override; virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override;
virtual bool is_action_type() const override { return true; } virtual bool is_action_type() const override { return true; }
virtual String as_text() const override; virtual String as_text() const override;
@ -399,7 +400,7 @@ public:
virtual bool is_pressed() const override; virtual bool is_pressed() const override;
virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const override; virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override;
virtual bool is_action_type() const override { return true; } virtual bool is_action_type() const override { return true; }
virtual String as_text() const override; virtual String as_text() const override;
@ -426,7 +427,7 @@ public:
void set_pressure(float p_pressure); void set_pressure(float p_pressure);
float get_pressure() const; float get_pressure() const;
virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const override; virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override;
virtual bool shortcut_match(const Ref<InputEvent> &p_event) const override; virtual bool shortcut_match(const Ref<InputEvent> &p_event) const override;
virtual bool is_action_type() const override { return true; } virtual bool is_action_type() const override { return true; }
@ -511,7 +512,7 @@ public:
virtual bool is_action(const StringName &p_action) const; virtual bool is_action(const StringName &p_action) const;
virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const override; virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override;
virtual bool shortcut_match(const Ref<InputEvent> &p_event) const override; virtual bool shortcut_match(const Ref<InputEvent> &p_event) const override;
virtual bool is_action_type() const override { return true; } virtual bool is_action_type() const override { return true; }

View File

@ -94,7 +94,7 @@ List<StringName> InputMap::get_actions() const {
return actions; return actions;
} }
List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength) const { List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength) const {
ERR_FAIL_COND_V(!p_event.is_valid(), nullptr); ERR_FAIL_COND_V(!p_event.is_valid(), nullptr);
for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) { for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) {
@ -105,7 +105,7 @@ List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Re
int device = e->get_device(); int device = e->get_device();
if (device == ALL_DEVICES || device == p_event->get_device()) { if (device == ALL_DEVICES || device == p_event->get_device()) {
if (e->action_match(p_event, p_pressed, p_strength, p_action.deadzone)) { if (e->action_match(p_event, p_pressed, p_strength, p_raw_strength, p_action.deadzone)) {
return E; return E;
} }
} }
@ -179,7 +179,7 @@ bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName
return event_get_action_status(p_event, p_action); return event_get_action_status(p_event, p_action);
} }
bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool *p_pressed, float *p_strength) const { bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool *p_pressed, float *p_strength, float *p_raw_strength) const {
Map<StringName, Action>::Element *E = input_map.find(p_action); Map<StringName, Action>::Element *E = input_map.find(p_action);
ERR_FAIL_COND_V_MSG(!E, false, "Request for nonexistent InputMap action '" + String(p_action) + "'."); ERR_FAIL_COND_V_MSG(!E, false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
@ -196,7 +196,8 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str
bool pressed; bool pressed;
float strength; float strength;
List<Ref<InputEvent>>::Element *event = _find_event(E->get(), p_event, &pressed, &strength); float raw_strength;
List<Ref<InputEvent>>::Element *event = _find_event(E->get(), p_event, &pressed, &strength, &raw_strength);
if (event != nullptr) { if (event != nullptr) {
if (p_pressed != nullptr) { if (p_pressed != nullptr) {
*p_pressed = pressed; *p_pressed = pressed;
@ -204,6 +205,9 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str
if (p_strength != nullptr) { if (p_strength != nullptr) {
*p_strength = strength; *p_strength = strength;
} }
if (p_raw_strength != nullptr) {
*p_raw_strength = raw_strength;
}
return true; return true;
} else { } else {
return false; return false;

View File

@ -54,7 +54,7 @@ private:
mutable Map<StringName, Action> input_map; mutable Map<StringName, Action> input_map;
List<Ref<InputEvent>>::Element *_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed = nullptr, float *p_strength = nullptr) const; List<Ref<InputEvent>>::Element *_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed = nullptr, float *p_strength = nullptr, float *p_raw_strength = nullptr) const;
Array _action_get_events(const StringName &p_action); Array _action_get_events(const StringName &p_action);
Array _get_actions(); Array _get_actions();
@ -78,7 +78,7 @@ public:
const List<Ref<InputEvent>> *action_get_events(const StringName &p_action); const List<Ref<InputEvent>> *action_get_events(const StringName &p_action);
bool event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action) const; bool event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action) const;
bool event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool *p_pressed = nullptr, float *p_strength = nullptr) const; bool event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool *p_pressed = nullptr, float *p_strength = nullptr, float *p_raw_strength = nullptr) const;
const Map<StringName, Action> &get_action_map() const; const Map<StringName, Action> &get_action_map() const;
void load_from_globals(); void load_from_globals();