How to rotate using canvas_item_set_transform?

Viewed 79

I'm trying to copy a Sprite node and display it on screen through a VisualServer and so far this has been my progress based on this example

ci_rid = VisualServer.canvas_item_create()
VisualServer.canvas_item_set_parent(ci_rid, get_canvas_item())

self.remove_child(sprite_node);
sprite_node.queue_free();

var texture = load(sprite_node.texture.resource_path);
var pos_and_size=Rect2(Vector2(0,0), sprite_node.region_rect.size);

if(sprite_node.region_enabled==true):
    VisualServer.canvas_item_add_texture_rect_region(ci_rid,pos_and_size, texture,sprite_node.region_rect);
    var transform_matrix=Transform2D.IDENTITY;
    
    VisualServer.canvas_item_set_transform(ci_rid,transform_matrix.translated(sprite_node.position-sprite_node.region_rect.size / 2))

but when I try to replicate the rotation on it's own axis like this:

VisualServer.canvas_item_set_transform(ci_rid,
 transform_matrix.rotated(deg2rad(sprite_node.rotation_degrees)).translated(sprite_node.position-sprite_node.region_rect.size / 2)
) 

it doesn't give the desired result and moves the entire image to another position

Original Sprite node:
enter image description here

VisualServer copy:
enter image description here

1 Answers

You can take the global_transform before you remove it:

var sprite_transform := sprite_node.global_transform

Or you can reconstruct it after you removed it:

var sprite_transform = global_transform * Transform2D(sprite_node.rotation, sprite_node.position).scaled(sprite_node.scale)

I'm using global_transform here because the node used to be a child of where the code is running. So its transform is relative to it.


I really don't know how you are not getting errors with your texture. This is the way I ended up going about it:

var image:Image = sprite_node.texture.get_data()
var texture_rid := VisualServer.texture_create_from_image(image)

Then the region and size are handled like this:

var texture_size:Vector2 = image.get_size()
var region:Rect2 = sprite_node.region_rect if sprite_node.region_enabled else Rect2(Vector2.ZERO, texture_size)
var pos_and_size := Rect2(region.size * -0.5 if sprite_node.centered else Vector2.ZERO, region.size)

And these are my VisualServer calls:

var ci_rid := VisualServer.canvas_item_create()
VisualServer.canvas_item_set_parent(ci_rid, get_canvas_item())
VisualServer.canvas_item_add_texture_rect_region(ci_rid, pos_and_size, texture_rid, region);
VisualServer.canvas_item_set_transform(ci_rid, sprite_transform)
Related