init commit
This commit is contained in:
86
addons/nklbdev.importality/sprite_sheet_builder/_.gd
Normal file
86
addons/nklbdev.importality/sprite_sheet_builder/_.gd
Normal file
@@ -0,0 +1,86 @@
|
||||
@tool
|
||||
extends RefCounted
|
||||
|
||||
const _Result = preload("../result.gd").Class
|
||||
const _Common = preload("../common.gd")
|
||||
|
||||
var _edges_artifacts_avoidance_method: _Common.EdgesArtifactsAvoidanceMethod
|
||||
var _sprites_surrounding_color: Color
|
||||
|
||||
func _init(
|
||||
edges_artifacts_avoidance_method: _Common.EdgesArtifactsAvoidanceMethod,
|
||||
sprites_surrounding_color: Color = Color.TRANSPARENT
|
||||
) -> void:
|
||||
_edges_artifacts_avoidance_method = edges_artifacts_avoidance_method
|
||||
_sprites_surrounding_color = sprites_surrounding_color
|
||||
|
||||
class SpriteSheetBuildingResult:
|
||||
extends _Result
|
||||
var sprite_sheet: _Common.SpriteSheetInfo
|
||||
var atlas_image: Image
|
||||
func _get_result_type_description() -> String:
|
||||
return "Sprite sheet building"
|
||||
func success(sprite_sheet: _Common.SpriteSheetInfo, atlas_image: Image) -> void:
|
||||
_success()
|
||||
self.sprite_sheet = sprite_sheet
|
||||
self.atlas_image = atlas_image
|
||||
|
||||
func build_sprite_sheet(images: Array[Image]) -> SpriteSheetBuildingResult:
|
||||
assert(false, "This method is abstract and must be overriden.")
|
||||
return null
|
||||
|
||||
static func __hash_combine(a: int, b: int) -> int:
|
||||
return a ^ (b + 0x9E3779B9 + (a<<6) + (a>>2))
|
||||
|
||||
const __hash_precision: int = 5
|
||||
static func _get_image_hash(image: Image) -> int:
|
||||
var image_size: Vector2i = image.get_size()
|
||||
if image_size.x * image_size.y == 0:
|
||||
return 0
|
||||
var hash: int = 0
|
||||
hash = __hash_combine(hash, image_size.x)
|
||||
hash = __hash_combine(hash, image_size.y)
|
||||
var grid_cell_size: Vector2i = image_size / __hash_precision
|
||||
for y in range(0, image_size.y, grid_cell_size.y):
|
||||
for x in range(0, image_size.x, grid_cell_size.x):
|
||||
var pixel: Color = image.get_pixel(x, y)
|
||||
hash = __hash_combine(hash, pixel.r8)
|
||||
hash = __hash_combine(hash, pixel.g8)
|
||||
hash = __hash_combine(hash, pixel.b8)
|
||||
hash = __hash_combine(hash, pixel.a8)
|
||||
return hash
|
||||
|
||||
static func _extrude_borders(image: Image, rect: Rect2i) -> void:
|
||||
if not rect.has_area():
|
||||
return
|
||||
# extrude borders
|
||||
# left border
|
||||
image.blit_rect(image,
|
||||
rect.grow_side(SIDE_RIGHT, 1 - rect.size.x),
|
||||
rect.position + Vector2i.LEFT)
|
||||
# top border
|
||||
image.blit_rect(image,
|
||||
rect.grow_side(SIDE_BOTTOM, 1 - rect.size.y),
|
||||
rect.position + Vector2i.UP)
|
||||
# right border
|
||||
image.blit_rect(image,
|
||||
rect.grow_side(SIDE_LEFT, 1 - rect.size.x),
|
||||
rect.position + Vector2i(rect.size.x, 0))
|
||||
# bottom border
|
||||
image.blit_rect(image,
|
||||
rect.grow_side(SIDE_TOP, 1 - rect.size.y),
|
||||
rect.position + Vector2i(0, rect.size.y))
|
||||
|
||||
# corner pixels
|
||||
# top left corner
|
||||
image.set_pixelv(rect.position - Vector2i.ONE,
|
||||
image.get_pixelv(rect.position))
|
||||
# top right corner
|
||||
image.set_pixelv(rect.position + Vector2i(rect.size.x, -1),
|
||||
image.get_pixelv(rect.position + Vector2i(rect.size.x - 1, 0)))
|
||||
# bottom right corner
|
||||
image.set_pixelv(rect.end,
|
||||
image.get_pixelv(rect.end - Vector2i.ONE))
|
||||
# bottom left corner
|
||||
image.set_pixelv(rect.position + Vector2i(-1, rect.size.y),
|
||||
image.get_pixelv(rect.position + Vector2i(0, rect.size.y -1)))
|
||||
1
addons/nklbdev.importality/sprite_sheet_builder/_.gd.uid
Normal file
1
addons/nklbdev.importality/sprite_sheet_builder/_.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://d1mx4gmvwjihh
|
||||
171
addons/nklbdev.importality/sprite_sheet_builder/grid_based.gd
Normal file
171
addons/nklbdev.importality/sprite_sheet_builder/grid_based.gd
Normal file
@@ -0,0 +1,171 @@
|
||||
@tool
|
||||
extends "_.gd"
|
||||
|
||||
const _RectPacker = preload("../rect_packer.gd")
|
||||
|
||||
enum StripDirection {
|
||||
HORIZONTAL = 0,
|
||||
VERTICAL = 1,
|
||||
}
|
||||
|
||||
var _strips_direction: StripDirection
|
||||
var _max_cells_in_strip: int
|
||||
var _trim_sprites_to_overall_min_size: bool
|
||||
var _collapse_transparent: bool
|
||||
var _merge_duplicates: bool
|
||||
|
||||
func _init(
|
||||
edges_artifacts_avoidance_method: _Common.EdgesArtifactsAvoidanceMethod,
|
||||
strips_direction: StripDirection,
|
||||
max_cells_in_strip: int,
|
||||
trim_sprites_to_overall_min_size: bool,
|
||||
collapse_transparent: bool,
|
||||
merge_duplicates: bool,
|
||||
sprites_surrounding_color: Color = Color.TRANSPARENT
|
||||
) -> void:
|
||||
super(edges_artifacts_avoidance_method, sprites_surrounding_color)
|
||||
_strips_direction = strips_direction
|
||||
_max_cells_in_strip = max_cells_in_strip
|
||||
_trim_sprites_to_overall_min_size = trim_sprites_to_overall_min_size
|
||||
_collapse_transparent = collapse_transparent
|
||||
_merge_duplicates = merge_duplicates
|
||||
|
||||
func build_sprite_sheet(images: Array[Image]) -> SpriteSheetBuildingResult:
|
||||
var result: SpriteSheetBuildingResult = SpriteSheetBuildingResult.new()
|
||||
var images_count: int = images.size()
|
||||
|
||||
var sprite_sheet: _Common.SpriteSheetInfo = _Common.SpriteSheetInfo.new()
|
||||
|
||||
if images_count == 0:
|
||||
var atlas_image = Image.new()
|
||||
atlas_image.set_data(1, 1, false, Image.FORMAT_RGBA8, PackedByteArray([0, 0, 0, 0]))
|
||||
result.success(sprite_sheet, atlas_image)
|
||||
return result
|
||||
|
||||
sprite_sheet.source_image_size = images.front().get_size()
|
||||
if not images.all(func(i: Image) -> bool: return i.get_size() == sprite_sheet.source_image_size):
|
||||
result.fail(ERR_INVALID_DATA, "Input images have different sizes")
|
||||
return result
|
||||
|
||||
sprite_sheet.sprites.resize(images_count)
|
||||
|
||||
var first_axis: int = _strips_direction
|
||||
var second_axis: int = 1 - first_axis
|
||||
|
||||
var max_image_used_rect: Rect2i
|
||||
var images_infos_cache: Dictionary # of arrays of images indices by image hashes
|
||||
|
||||
var unique_sprites_indices: Array[int]
|
||||
var collapsed_sprite: _Common.SpriteInfo = _Common.SpriteInfo.new()
|
||||
var images_used_rects: Array[Rect2i]
|
||||
|
||||
for image_index in images_count:
|
||||
var image: Image = images[image_index]
|
||||
var image_used_rect: Rect2i = image.get_used_rect()
|
||||
var is_image_invisible: bool = not image_used_rect.has_area()
|
||||
|
||||
if _collapse_transparent and is_image_invisible:
|
||||
sprite_sheet.sprites[image_index] = collapsed_sprite
|
||||
continue
|
||||
elif _merge_duplicates:
|
||||
var image_hash: int = _get_image_hash(image)
|
||||
var similar_images_indices: PackedInt32Array = \
|
||||
images_infos_cache.get(image_hash, PackedInt32Array())
|
||||
var is_duplicate_found: bool = false
|
||||
for similar_image_index in similar_images_indices:
|
||||
var similar_image: Image = images[similar_image_index]
|
||||
if image == similar_image or image.get_data() == similar_image.get_data():
|
||||
sprite_sheet.sprites[image_index] = \
|
||||
sprite_sheet.sprites[similar_image_index]
|
||||
is_duplicate_found = true
|
||||
break
|
||||
if similar_images_indices.is_empty():
|
||||
images_infos_cache[image_hash] = similar_images_indices
|
||||
similar_images_indices.push_back(image_index)
|
||||
if is_duplicate_found:
|
||||
continue
|
||||
|
||||
var sprite: _Common.SpriteInfo = _Common.SpriteInfo.new()
|
||||
sprite.region = image_used_rect
|
||||
sprite_sheet.sprites[image_index] = sprite
|
||||
unique_sprites_indices.push_back(image_index)
|
||||
if not is_image_invisible:
|
||||
max_image_used_rect = \
|
||||
image_used_rect.merge(max_image_used_rect) \
|
||||
if max_image_used_rect.has_area() else \
|
||||
image_used_rect
|
||||
|
||||
var unique_sprites_count: int = unique_sprites_indices.size()
|
||||
|
||||
if _edges_artifacts_avoidance_method == _Common.EdgesArtifactsAvoidanceMethod.TRANSPARENT_EXPANSION:
|
||||
sprite_sheet.source_image_size += Vector2i.ONE * 2
|
||||
|
||||
var grid_size: Vector2i
|
||||
grid_size[second_axis] = \
|
||||
unique_sprites_count / _max_cells_in_strip + \
|
||||
sign(unique_sprites_count % _max_cells_in_strip) \
|
||||
if _max_cells_in_strip > 0 else sign(unique_sprites_count)
|
||||
grid_size[first_axis] = \
|
||||
_max_cells_in_strip \
|
||||
if grid_size[second_axis] > 1 else \
|
||||
unique_sprites_count
|
||||
|
||||
var image_region: Rect2i = \
|
||||
max_image_used_rect \
|
||||
if _trim_sprites_to_overall_min_size else \
|
||||
Rect2i(Vector2i.ZERO, sprite_sheet.source_image_size)
|
||||
if _edges_artifacts_avoidance_method == _Common.EdgesArtifactsAvoidanceMethod.TRANSPARENT_EXPANSION:
|
||||
image_region = image_region.grow(1)
|
||||
|
||||
var atlas_size: Vector2i = grid_size * image_region.size
|
||||
match _edges_artifacts_avoidance_method:
|
||||
_Common.EdgesArtifactsAvoidanceMethod.NONE:
|
||||
pass
|
||||
_Common.EdgesArtifactsAvoidanceMethod.TRANSPARENT_SPACING:
|
||||
atlas_size += grid_size - Vector2i.ONE
|
||||
_Common.EdgesArtifactsAvoidanceMethod.SOLID_COLOR_SURROUNDING:
|
||||
atlas_size += grid_size + Vector2i.ONE
|
||||
_Common.EdgesArtifactsAvoidanceMethod.BORDERS_EXTRUSION:
|
||||
atlas_size += grid_size * 2
|
||||
_Common.EdgesArtifactsAvoidanceMethod.TRANSPARENT_EXPANSION:
|
||||
pass
|
||||
|
||||
var atlas_image = Image.create(atlas_size.x, atlas_size.y, false, Image.FORMAT_RGBA8)
|
||||
|
||||
if _edges_artifacts_avoidance_method == _Common.EdgesArtifactsAvoidanceMethod.SOLID_COLOR_SURROUNDING:
|
||||
atlas_image.fill(_sprites_surrounding_color)
|
||||
|
||||
var cell: Vector2i
|
||||
var cell_index: int
|
||||
for sprite_index in unique_sprites_indices:
|
||||
# calculate cell
|
||||
var sprite: _Common.SpriteInfo = sprite_sheet.sprites[sprite_index]
|
||||
if sprite == collapsed_sprite:
|
||||
continue
|
||||
sprite.region.size = image_region.size
|
||||
sprite.offset = image_region.position
|
||||
var image: Image = images[sprite_index]
|
||||
cell[first_axis] = cell_index % _max_cells_in_strip if _max_cells_in_strip > 0 else cell_index
|
||||
cell[second_axis] = cell_index / _max_cells_in_strip if _max_cells_in_strip > 0 else 0
|
||||
sprite.region.position = cell * image_region.size
|
||||
match _edges_artifacts_avoidance_method:
|
||||
_Common.EdgesArtifactsAvoidanceMethod.TRANSPARENT_SPACING:
|
||||
sprite.region.position += cell
|
||||
_Common.EdgesArtifactsAvoidanceMethod.SOLID_COLOR_SURROUNDING:
|
||||
sprite.region.position += cell + Vector2i.ONE
|
||||
_Common.EdgesArtifactsAvoidanceMethod.BORDERS_EXTRUSION:
|
||||
sprite.region.position += cell * 2 + Vector2i.ONE
|
||||
_Common.EdgesArtifactsAvoidanceMethod.TRANSPARENT_EXPANSION:
|
||||
pass
|
||||
atlas_image.blit_rect(image, image_region, sprite.region.position)# +
|
||||
#(Vector2i.ONE
|
||||
#if _edges_artifacts_avoidance_method == \
|
||||
# _Models.SpriteSheetModel.EdgesArtifactsAvoidanceMethod.TRANSPARENT_EXPANSION else
|
||||
#Vector2i.ZERO))
|
||||
match _edges_artifacts_avoidance_method:
|
||||
_Common.EdgesArtifactsAvoidanceMethod.BORDERS_EXTRUSION:
|
||||
_extrude_borders(atlas_image, sprite.region)
|
||||
cell_index += 1
|
||||
|
||||
result.success(sprite_sheet, atlas_image)
|
||||
return result
|
||||
@@ -0,0 +1 @@
|
||||
uid://c65mteocd0oco
|
||||
217
addons/nklbdev.importality/sprite_sheet_builder/packed.gd
Normal file
217
addons/nklbdev.importality/sprite_sheet_builder/packed.gd
Normal file
@@ -0,0 +1,217 @@
|
||||
@tool
|
||||
extends "_.gd"
|
||||
|
||||
const _RectPacker = preload("../rect_packer.gd")
|
||||
|
||||
class SpriteProps:
|
||||
extends RefCounted
|
||||
var images_props: Array[ImageProps]
|
||||
var atlas_region_props: AtlasRegionProps
|
||||
|
||||
var offset: Vector2i
|
||||
|
||||
func create_sprite(atlas_region_position: Vector2i) -> _Common.SpriteInfo:
|
||||
var sprite = _Common.SpriteInfo.new()
|
||||
sprite.region = Rect2i(atlas_region_position, atlas_region_props.size)
|
||||
sprite.offset = offset
|
||||
return sprite
|
||||
|
||||
class AtlasRegionProps:
|
||||
extends RefCounted
|
||||
var sprites_props: Array[SpriteProps]
|
||||
var images_props: Array[ImageProps]
|
||||
|
||||
var size: Vector2i
|
||||
|
||||
class ImageProps:
|
||||
extends RefCounted
|
||||
var sprite_props: SpriteProps
|
||||
var atlas_region_props: AtlasRegionProps
|
||||
|
||||
var image: Image
|
||||
var used_rect: Rect2i
|
||||
var used_fragment: Image
|
||||
var used_fragment_data: PackedByteArray
|
||||
var used_fragment_data_hash: int
|
||||
|
||||
func _init(image: Image) -> void:
|
||||
self.image = image
|
||||
used_rect = image.get_used_rect()
|
||||
if used_rect.has_area():
|
||||
used_fragment = image.get_region(used_rect)
|
||||
used_fragment_data = used_fragment.get_data()
|
||||
used_fragment_data_hash = hash(used_fragment_data)
|
||||
|
||||
class SpriteSheetBuildingContext:
|
||||
extends RefCounted
|
||||
var images_props: Array[ImageProps]
|
||||
var sprites_props: Array[SpriteProps]
|
||||
var atlas_regions_props: Array[AtlasRegionProps]
|
||||
var _similar_images_props_by_used_fragment_data_hash: Dictionary
|
||||
var _collapsed_image_props: ImageProps
|
||||
|
||||
func _init(images: Array[Image]) -> void:
|
||||
var images_count: int = images.size()
|
||||
images_props.resize(images_count)
|
||||
for image_index in images_count:
|
||||
images_props[image_index] = _process_image_props(ImageProps.new(images[image_index]))
|
||||
|
||||
func _process_image_props(image_props: ImageProps) -> ImageProps:
|
||||
if not image_props.used_rect.has_area():
|
||||
if _collapsed_image_props == null:
|
||||
_collapsed_image_props = image_props
|
||||
return _collapsed_image_props
|
||||
|
||||
var similar_images_props: Array[ImageProps]
|
||||
if not _similar_images_props_by_used_fragment_data_hash.has(image_props.used_fragment_data_hash):
|
||||
_similar_images_props_by_used_fragment_data_hash[image_props.used_fragment_data_hash] = similar_images_props
|
||||
else:
|
||||
similar_images_props = _similar_images_props_by_used_fragment_data_hash[image_props.used_fragment_data_hash]
|
||||
for similar_image_props in similar_images_props:
|
||||
if image_props.image == similar_image_props.image:
|
||||
# The same image found.
|
||||
return similar_image_props
|
||||
elif image_props.used_rect.size == similar_image_props.used_rect.size:
|
||||
if image_props.used_fragment_data == similar_image_props.used_fragment_data:
|
||||
if image_props.used_rect.position == similar_image_props.used_rect.position:
|
||||
# An image with equal content found.
|
||||
return similar_image_props
|
||||
else:
|
||||
# An image with equal, but offsetted content found.
|
||||
# It will have the same region, but new sprite.
|
||||
image_props.atlas_region_props = similar_image_props.atlas_region_props
|
||||
image_props.sprite_props = SpriteProps.new()
|
||||
image_props.sprite_props.offset = image_props.used_rect.position
|
||||
image_props.sprite_props.images_props.push_back(image_props)
|
||||
image_props.sprite_props.atlas_region_props = similar_image_props.atlas_region_props
|
||||
sprites_props.push_back(image_props.sprite_props)
|
||||
return image_props
|
||||
# A new unique image found.
|
||||
# It will have new region and sprite.
|
||||
image_props.atlas_region_props = AtlasRegionProps.new()
|
||||
image_props.atlas_region_props.size = image_props.used_rect.size
|
||||
image_props.sprite_props = SpriteProps.new()
|
||||
image_props.sprite_props.offset = image_props.used_rect.position
|
||||
image_props.sprite_props.images_props.push_back(image_props)
|
||||
image_props.sprite_props.atlas_region_props = image_props.atlas_region_props
|
||||
image_props.atlas_region_props.sprites_props.push_back(image_props.sprite_props)
|
||||
image_props.atlas_region_props.images_props.push_back(image_props)
|
||||
sprites_props.push_back(image_props.sprite_props)
|
||||
atlas_regions_props.push_back(image_props.atlas_region_props)
|
||||
similar_images_props.push_back(image_props)
|
||||
return image_props
|
||||
|
||||
func build_sprite_sheet(images: Array[Image]) -> SpriteSheetBuildingResult:
|
||||
var result: SpriteSheetBuildingResult = SpriteSheetBuildingResult.new()
|
||||
var images_count: int = images.size()
|
||||
|
||||
var sprite_sheet: _Common.SpriteSheetInfo = _Common.SpriteSheetInfo.new()
|
||||
|
||||
if images_count == 0:
|
||||
var atlas_image = Image.new()
|
||||
atlas_image.set_data(1, 1, false, Image.FORMAT_RGBA8, PackedByteArray([0, 0, 0, 0]))
|
||||
result.success(sprite_sheet, atlas_image)
|
||||
return result
|
||||
|
||||
sprite_sheet.source_image_size = images.front().get_size()
|
||||
if not images.all(func(i: Image) -> bool:
|
||||
return i.get_size() == sprite_sheet.source_image_size):
|
||||
result.fail(ERR_INVALID_DATA, "Input images have different sizes")
|
||||
return result
|
||||
|
||||
sprite_sheet.sprites.resize(images_count)
|
||||
|
||||
var context: SpriteSheetBuildingContext = SpriteSheetBuildingContext.new(images)
|
||||
var atlas_regions_count: int = context.atlas_regions_props.size()
|
||||
if atlas_regions_count == 0:
|
||||
# All sprites are collapsed
|
||||
var collapsed_sprite: _Common.SpriteInfo = _Common.SpriteInfo.new()
|
||||
for image_index in images_count:
|
||||
sprite_sheet.sprites[image_index] = collapsed_sprite
|
||||
var atlas_image = Image.new()
|
||||
atlas_image.set_data(1, 1, false, Image.FORMAT_RGBA8, PackedByteArray([0, 0, 0, 0]))
|
||||
result.success(sprite_sheet, atlas_image)
|
||||
return result
|
||||
|
||||
var atlas_regions_sizes: Array[Vector2i]
|
||||
atlas_regions_sizes.resize(atlas_regions_count)
|
||||
for atlas_region_index in atlas_regions_count:
|
||||
atlas_regions_sizes[atlas_region_index] = \
|
||||
context.atlas_regions_props[atlas_region_index].size
|
||||
|
||||
match _edges_artifacts_avoidance_method:
|
||||
_Common.EdgesArtifactsAvoidanceMethod.TRANSPARENT_SPACING, \
|
||||
_Common.EdgesArtifactsAvoidanceMethod.SOLID_COLOR_SURROUNDING:
|
||||
for atlas_region_index in atlas_regions_count:
|
||||
atlas_regions_sizes[atlas_region_index] += Vector2i.ONE
|
||||
_Common.EdgesArtifactsAvoidanceMethod.BORDERS_EXTRUSION, \
|
||||
_Common.EdgesArtifactsAvoidanceMethod.TRANSPARENT_EXPANSION:
|
||||
for atlas_region_index in atlas_regions_count:
|
||||
atlas_regions_sizes[atlas_region_index] += Vector2i.ONE * 2
|
||||
|
||||
var packing_result: _RectPacker.RectPackingResult = _RectPacker.pack(atlas_regions_sizes)
|
||||
if packing_result.error:
|
||||
result.fail(ERR_BUG, "Rect packing failed", packing_result)
|
||||
return result
|
||||
|
||||
match _edges_artifacts_avoidance_method:
|
||||
_Common.EdgesArtifactsAvoidanceMethod.TRANSPARENT_SPACING:
|
||||
packing_result.bounds -= Vector2i.ONE
|
||||
_Common.EdgesArtifactsAvoidanceMethod.SOLID_COLOR_SURROUNDING:
|
||||
packing_result.bounds += Vector2i.ONE
|
||||
for atlas_region_index in atlas_regions_count:
|
||||
packing_result.rects_positions[atlas_region_index] += Vector2i.ONE
|
||||
_Common.EdgesArtifactsAvoidanceMethod.BORDERS_EXTRUSION:
|
||||
for atlas_region_index in atlas_regions_count:
|
||||
packing_result.rects_positions[atlas_region_index] += Vector2i.ONE
|
||||
|
||||
var atlas_image: Image = Image.create(
|
||||
packing_result.bounds.x, packing_result.bounds.y, false, Image.FORMAT_RGBA8)
|
||||
|
||||
if _edges_artifacts_avoidance_method == _Common.EdgesArtifactsAvoidanceMethod.SOLID_COLOR_SURROUNDING:
|
||||
atlas_image.fill(_sprites_surrounding_color)
|
||||
|
||||
var extrude_sprites_borders: bool = _edges_artifacts_avoidance_method == \
|
||||
_Common.EdgesArtifactsAvoidanceMethod.BORDERS_EXTRUSION
|
||||
var expand_sprites: bool = _edges_artifacts_avoidance_method == \
|
||||
_Common.EdgesArtifactsAvoidanceMethod.TRANSPARENT_EXPANSION
|
||||
|
||||
var atlas_regions_positions_by_atlas_regions_props: Dictionary
|
||||
for atlas_region_index in atlas_regions_count:
|
||||
var atlas_region_props: AtlasRegionProps = context.atlas_regions_props[atlas_region_index]
|
||||
packing_result.rects_positions[atlas_region_index] += \
|
||||
Vector2i.ONE if expand_sprites else Vector2i.ZERO
|
||||
var image_props: ImageProps = atlas_region_props.images_props.front()
|
||||
atlas_image.blit_rect(image_props.used_fragment,
|
||||
Rect2i(Vector2i.ZERO, atlas_region_props.size),
|
||||
packing_result.rects_positions[atlas_region_index])
|
||||
if extrude_sprites_borders:
|
||||
_extrude_borders(atlas_image, Rect2i(
|
||||
packing_result.rects_positions[atlas_region_index],
|
||||
atlas_region_props.size))
|
||||
atlas_regions_positions_by_atlas_regions_props[atlas_region_props] = \
|
||||
packing_result.rects_positions[atlas_region_index]
|
||||
|
||||
var sprites_by_sprites_props: Dictionary
|
||||
for sprite_props in context.sprites_props:
|
||||
var sprite: _Common.SpriteInfo = sprite_props.create_sprite(
|
||||
atlas_regions_positions_by_atlas_regions_props[sprite_props.atlas_region_props])
|
||||
if expand_sprites:
|
||||
sprite.region = sprite.region.grow(1)
|
||||
sprite.offset -= Vector2i.ONE
|
||||
sprites_by_sprites_props[sprite_props] = sprite
|
||||
|
||||
var collapsed_sprite: _Common.SpriteInfo
|
||||
for image_index in images_count:
|
||||
var image_props: ImageProps = context.images_props[image_index]
|
||||
var sprite: _Common.SpriteInfo = sprites_by_sprites_props.get(image_props.sprite_props, null)
|
||||
if sprite == null:
|
||||
if collapsed_sprite == null:
|
||||
collapsed_sprite = _Common.SpriteInfo.new()
|
||||
sprite = collapsed_sprite
|
||||
sprite_sheet.sprites[image_index] = sprite
|
||||
|
||||
if expand_sprites:
|
||||
sprite_sheet.source_image_size += Vector2i.ONE * 2
|
||||
result.success(sprite_sheet, atlas_image)
|
||||
return result
|
||||
@@ -0,0 +1 @@
|
||||
uid://1gcef3dr85gs
|
||||
Reference in New Issue
Block a user