From 223a612c0c79563047eee80edf3552bcb5e112e1 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Fri, 23 Dec 2022 17:37:45 +0200 Subject: [iOS] Add Apple Pencil pressure and tilt support. --- core/input/input.cpp | 6 ++++++ core/input/input_event.cpp | 41 +++++++++++++++++++++++++++++++++++- core/input/input_event.h | 12 +++++++++++ doc/classes/InputEventScreenDrag.xml | 9 ++++++++ platform/ios/display_server_ios.h | 4 ++-- platform/ios/display_server_ios.mm | 4 +++- platform/ios/godot_view.mm | 4 +++- 7 files changed, 75 insertions(+), 5 deletions(-) diff --git a/core/input/input.cpp b/core/input/input.cpp index cb65d2569c..554f8fad00 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -540,6 +540,9 @@ void Input::_parse_input_event_impl(const Ref &p_event, bool p_is_em drag_event->set_position(position); drag_event->set_relative(relative); + drag_event->set_tilt(mm->get_tilt()); + drag_event->set_pen_inverted(mm->get_pen_inverted()); + drag_event->set_pressure(mm->get_pressure()); drag_event->set_velocity(get_last_mouse_velocity()); event_dispatch_function(drag_event); @@ -605,6 +608,9 @@ void Input::_parse_input_event_impl(const Ref &p_event, bool p_is_em motion_event.instantiate(); motion_event->set_device(InputEvent::DEVICE_ID_TOUCH_MOUSE); + motion_event->set_tilt(sd->get_tilt()); + motion_event->set_pen_inverted(sd->get_pen_inverted()); + motion_event->set_pressure(sd->get_pressure()); motion_event->set_position(sd->get_position()); motion_event->set_global_position(sd->get_position()); motion_event->set_relative(sd->get_relative()); diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 0a32b4bf68..4859490230 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -1223,6 +1223,30 @@ int InputEventScreenDrag::get_index() const { return index; } +void InputEventScreenDrag::set_tilt(const Vector2 &p_tilt) { + tilt = p_tilt; +} + +Vector2 InputEventScreenDrag::get_tilt() const { + return tilt; +} + +void InputEventScreenDrag::set_pressure(float p_pressure) { + pressure = p_pressure; +} + +float InputEventScreenDrag::get_pressure() const { + return pressure; +} + +void InputEventScreenDrag::set_pen_inverted(bool p_inverted) { + pen_inverted = p_inverted; +} + +bool InputEventScreenDrag::get_pen_inverted() const { + return pen_inverted; +} + void InputEventScreenDrag::set_position(const Vector2 &p_pos) { pos = p_pos; } @@ -1256,6 +1280,9 @@ Ref InputEventScreenDrag::xformed_by(const Transform2D &p_xform, con sd->set_window_id(get_window_id()); sd->set_index(index); + sd->set_pressure(get_pressure()); + sd->set_pen_inverted(get_pen_inverted()); + sd->set_tilt(get_tilt()); sd->set_position(p_xform.xform(pos + p_local_ofs)); sd->set_relative(p_xform.basis_xform(relative)); sd->set_velocity(p_xform.basis_xform(velocity)); @@ -1268,7 +1295,7 @@ String InputEventScreenDrag::as_text() const { } String InputEventScreenDrag::to_string() { - return vformat("InputEventScreenDrag: index=%d, position=(%s), relative=(%s), velocity=(%s)", index, String(get_position()), String(get_relative()), String(get_velocity())); + return vformat("InputEventScreenDrag: index=%d, position=(%s), relative=(%s), velocity=(%s), pressure=%.2f, tilt=(%s), pen_inverted=(%s)", index, String(get_position()), String(get_relative()), String(get_velocity()), get_pressure(), String(get_tilt()), get_pen_inverted()); } bool InputEventScreenDrag::accumulate(const Ref &p_event) { @@ -1292,6 +1319,15 @@ void InputEventScreenDrag::_bind_methods() { ClassDB::bind_method(D_METHOD("set_index", "index"), &InputEventScreenDrag::set_index); ClassDB::bind_method(D_METHOD("get_index"), &InputEventScreenDrag::get_index); + ClassDB::bind_method(D_METHOD("set_tilt", "tilt"), &InputEventScreenDrag::set_tilt); + ClassDB::bind_method(D_METHOD("get_tilt"), &InputEventScreenDrag::get_tilt); + + ClassDB::bind_method(D_METHOD("set_pressure", "pressure"), &InputEventScreenDrag::set_pressure); + ClassDB::bind_method(D_METHOD("get_pressure"), &InputEventScreenDrag::get_pressure); + + ClassDB::bind_method(D_METHOD("set_pen_inverted", "pen_inverted"), &InputEventScreenDrag::set_pen_inverted); + ClassDB::bind_method(D_METHOD("get_pen_inverted"), &InputEventScreenDrag::get_pen_inverted); + ClassDB::bind_method(D_METHOD("set_position", "position"), &InputEventScreenDrag::set_position); ClassDB::bind_method(D_METHOD("get_position"), &InputEventScreenDrag::get_position); @@ -1302,6 +1338,9 @@ void InputEventScreenDrag::_bind_methods() { ClassDB::bind_method(D_METHOD("get_velocity"), &InputEventScreenDrag::get_velocity); ADD_PROPERTY(PropertyInfo(Variant::INT, "index"), "set_index", "get_index"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "tilt"), "set_tilt", "get_tilt"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure"), "set_pressure", "get_pressure"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pen_inverted"), "set_pen_inverted", "get_pen_inverted"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position", PROPERTY_HINT_NONE, "suffix:px"), "set_position", "get_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative", PROPERTY_HINT_NONE, "suffix:px"), "set_relative", "get_relative"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "velocity", PROPERTY_HINT_NONE, "suffix:px/s"), "set_velocity", "get_velocity"); diff --git a/core/input/input_event.h b/core/input/input_event.h index adbcb7cf68..06c3118abc 100644 --- a/core/input/input_event.h +++ b/core/input/input_event.h @@ -384,6 +384,9 @@ class InputEventScreenDrag : public InputEventFromWindow { Vector2 pos; Vector2 relative; Vector2 velocity; + Vector2 tilt; + float pressure = 0; + bool pen_inverted = false; protected: static void _bind_methods(); @@ -392,6 +395,15 @@ public: void set_index(int p_index); int get_index() const; + void set_tilt(const Vector2 &p_tilt); + Vector2 get_tilt() const; + + void set_pressure(float p_pressure); + float get_pressure() const; + + void set_pen_inverted(bool p_inverted); + bool get_pen_inverted() const; + void set_position(const Vector2 &p_pos); Vector2 get_position() const; diff --git a/doc/classes/InputEventScreenDrag.xml b/doc/classes/InputEventScreenDrag.xml index e5cc522b21..c1d126ca4a 100644 --- a/doc/classes/InputEventScreenDrag.xml +++ b/doc/classes/InputEventScreenDrag.xml @@ -13,12 +13,21 @@ The drag event index in the case of a multi-drag event. + + Returns [code]true[/code] when using the eraser end of a stylus pen. + The drag position. + + Represents the pressure the user puts on the pen. Ranges from [code]0.0[/code] to [code]1.0[/code]. + The drag position relative to the previous position (position at the last frame). + + Represents the angles of tilt of the pen. Positive X-coordinate value indicates a tilt to the right. Positive Y-coordinate value indicates a tilt toward the user. Ranges from [code]-1.0[/code] to [code]1.0[/code] for both axes. + The drag velocity. diff --git a/platform/ios/display_server_ios.h b/platform/ios/display_server_ios.h index 0ca0d3d1fe..82351a536b 100644 --- a/platform/ios/display_server_ios.h +++ b/platform/ios/display_server_ios.h @@ -105,10 +105,10 @@ public: // MARK: - Input - // MARK: Touches + // MARK: Touches and Apple Pencil void touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_double_click); - void touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y); + void touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y, float p_pressure, Vector2 p_tilt); void touches_cancelled(int p_idx); // MARK: Keyboard diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm index 3f4a406116..ad1a1ae673 100644 --- a/platform/ios/display_server_ios.mm +++ b/platform/ios/display_server_ios.mm @@ -237,10 +237,12 @@ void DisplayServerIOS::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, perform_event(ev); } -void DisplayServerIOS::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y) { +void DisplayServerIOS::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y, float p_pressure, Vector2 p_tilt) { Ref ev; ev.instantiate(); ev->set_index(p_idx); + ev->set_pressure(p_pressure); + ev->set_tilt(p_tilt); ev->set_position(Vector2(p_x, p_y)); ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y)); perform_event(ev); diff --git a/platform/ios/godot_view.mm b/platform/ios/godot_view.mm index 4537dc2985..02b8e748ef 100644 --- a/platform/ios/godot_view.mm +++ b/platform/ios/godot_view.mm @@ -363,7 +363,9 @@ static const float earth_gravity = 9.80665; ERR_FAIL_COND(tid == -1); CGPoint touchPoint = [touch locationInView:self]; CGPoint prev_point = [touch previousLocationInView:self]; - DisplayServerIOS::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor); + CGFloat alt = [touch altitudeAngle]; + CGVector azim = [touch azimuthUnitVectorInView:self]; + DisplayServerIOS::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, [touch force] / [touch maximumPossibleForce], Vector2(azim.dx, azim.dy) * Math::cos(alt)); } } } -- cgit v1.2.3