opaque_to_polygons gives empty array as input

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By sygi

I would like to programatically create a simple polygon based on a sprite. I am doing:

var bm = BitMap.new()
bm.create_from_image_alpha(texture.get_data())
var rect = Rect2(position.x, position.y, texture.get_width(), texture.get_height())
var my_array = bm.opaque_to_polygons(rect)

but the received my_array is empty. I confirmed that the bitmap itself is not empty (146/396 bits on). I tried it with a two images (including default godot.png that comes with the engine), yet the array is always empty.

Any idea why it may be the case?

Similar questions: 1, 2.

:bust_in_silhouette: Reply From: MrEliptik

I think you should not use the position when creating your rect. Because the position will not be 0,0, the rect won’t represent your image size.

So, if you try with:

var bm = BitMap.new()
bm.create_from_image_alpha(texture.get_data())
var rect = Rect2(0, 0, texture.get_width(), texture.get_height())
var my_array = bm.opaque_to_polygons(rect)

my_array won’t be empty. You can then use the sprite position and add it to your points if you want to draw your polygon at the sprite location and not centered on (0, 0).

EDIT: Just to make the reply more complete, here’s how you would add the polygon based on the points

# Create the polygon
var poly = Polygon2D.new()
var pointArr = PoolVector2Array()
for p in my_array[0]:
    pointArr.append(p)
poly.polygon = pointArr
poly.texture = load("res://sometexture.png")

add_child(poly)

# Place the polygon at sprite location
# We need to offset by width and height because sprite position is from the center, whereas the polygon position is from the top left
poly.position = $Sprite.position - Vector2($Sprite.texture.get_width()/2, $Sprite.texture.get_height()/2)

Geez, thanks so much! I spend hours trying to figure out what’s going on.

sygi | 2021-03-21 13:32