From 847a37b1966ef1051cc6525dbebc7dd9e78de6a8 Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Sun, 28 Feb 2021 10:30:15 +0000 Subject: [PATCH] Change 2d transform snapping from floor to round Two common problems have emerged as a result of transform snapping: 1) Camera jitter with a camera following a snapped object 2) Pixel gaps between e.g. a platform and a player, where a platform rounds down and a player rounds up Using round seems to greatly reduce problems due to camera jitter. It also may prove better for pixel gaps because pixel art is often designed on a grid, so whole numbers are too expected, which are unstable with floor(). --- scene/2d/animated_sprite.cpp | 2 ++ scene/2d/sprite.cpp | 9 +++++++-- servers/visual/visual_server_canvas.cpp | 2 +- servers/visual/visual_server_viewport.cpp | 4 ++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 42a0a878070..4d9378c47a1 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -453,6 +453,8 @@ void AnimatedSprite::_notification(int p_what) { ofs -= s / 2; if (Engine::get_singleton()->get_snap_2d_transforms()) { + ofs = ofs.round(); + } else if (Engine::get_singleton()->get_use_pixel_snap()) { ofs = ofs.floor(); } Rect2 dst_rect(ofs, s); diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index 688b03c4479..adcabc93341 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -99,7 +99,10 @@ void Sprite::_get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_cli Point2 dest_offset = offset; if (centered) dest_offset -= frame_size / 2; - if (Engine::get_singleton()->get_use_pixel_snap()) { + + if (Engine::get_singleton()->get_snap_2d_transforms()) { + dest_offset = dest_offset.round(); + } else if (Engine::get_singleton()->get_use_pixel_snap()) { dest_offset = dest_offset.floor(); } @@ -378,7 +381,9 @@ Rect2 Sprite::get_rect() const { Point2 ofs = offset; if (centered) ofs -= Size2(s) / 2; - if (Engine::get_singleton()->get_use_pixel_snap()) { + if (Engine::get_singleton()->get_snap_2d_transforms()) { + ofs = ofs.round(); + } else if (Engine::get_singleton()->get_use_pixel_snap()) { ofs = ofs.floor(); } diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp index 51bd8925e7e..060cd8b652e 100644 --- a/servers/visual/visual_server_canvas.cpp +++ b/servers/visual/visual_server_canvas.cpp @@ -100,7 +100,7 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor Rect2 rect = ci->get_rect(); Transform2D xform = ci->xform; if (snap_2d_transforms) { - xform.elements[2] = xform.elements[2].floor(); + xform.elements[2] = xform.elements[2].round(); } xform = p_transform * xform; diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp index c2032b03f7b..0c64be8cbd7 100644 --- a/servers/visual/visual_server_viewport.cpp +++ b/servers/visual/visual_server_viewport.cpp @@ -47,7 +47,7 @@ static Transform2D _canvas_get_transform(VisualServerViewport::Viewport *p_viewp Transform2D c_xform = p_viewport->canvas_map[p_canvas->parent].transform; if (snap) { - c_xform.elements[2] = c_xform.elements[2].floor(); + c_xform.elements[2] = c_xform.elements[2].round(); } xf = xf * c_xform; scale = p_canvas->parent_scale; @@ -55,7 +55,7 @@ static Transform2D _canvas_get_transform(VisualServerViewport::Viewport *p_viewp Transform2D c_xform = p_canvas_data->transform; if (snap) { - c_xform.elements[2] = c_xform.elements[2].floor(); + c_xform.elements[2] = c_xform.elements[2].round(); } xf = xf * c_xform;