Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Control.set_global_position(global_position) doesn't work after rotated around custom pivot #87354

Closed
abcjjy opened this issue Jan 19, 2024 · 1 comment · Fixed by #87432
Closed
Milestone

Comments

@abcjjy
Copy link

abcjjy commented Jan 19, 2024

Tested versions

Godot v4.2.stable

System information

Godot v4.2.stable - macOS 13.6.1 - GLES3 (Compatibility) - ANGLE (AMD, ANGLE Metal Renderer: AMD Radeon Pro 560X, 版本13.6.1(版号22G313)) - Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz (12 Threads)

Issue description

When a Control's pivot offset is set to somewhere other than (0, 0) and rotated, set_global_position(global_position) will move the Control far away.

Steps to reproduce

extends ColorRect

func _ready():
    pivot_offset = size
    rotation_degrees = 90
    for i in 36:
        set_global_position(global_position)
        await get_tree().process_frame
        print('%s %s %s'%[position, global_position, size])

Minimal reproduction project (MRP)

N/A

@Rindbee
Copy link
Contributor

Rindbee commented Jan 20, 2024

By default, the upper left corner is used as the pivot point for transformation. This issue occurs when the pivot point is not in the upper left corner.

When the pivot point is not in the upper left corner, the transformation order is:

var piv_tran := Transform2D()
piv_tran.origin -= pivot_offset
piv_tran = piv_tran.rotated(rotation)
piv_tran.origin += pivot_offset

var local_tran_in_parent := Transform2D()
local_tran_in_parent.origin += position

var p_g : Transform2D = get_parent().get_global_transform()

var tran := p_g * (local_tran_in_parent * piv_tran)

var global_position = tran * Vector2.ZERO

godot/scene/gui/control.cpp

Lines 1420 to 1429 in 0bcc0e9

void Control::set_global_position(const Point2 &p_point, bool p_keep_offsets) {
ERR_MAIN_THREAD_GUARD;
Transform2D inv;
if (data.parent_canvas_item) {
inv = data.parent_canvas_item->get_global_transform().affine_inverse();
}
set_position(inv.xform(p_point), p_keep_offsets);
}

The new position set is local_tran_in_parent * piv_tran * Vector2.ZERO.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants