diff options
Diffstat (limited to 'scene/resources/tile_set.h')
-rw-r--r-- | scene/resources/tile_set.h | 149 |
1 files changed, 144 insertions, 5 deletions
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 716b66405f..d2238c26d2 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -60,6 +60,84 @@ class TileSetPluginAtlasRendering; class TileSetPluginAtlasPhysics; class TileSetPluginAtlasNavigation; +union TileMapCell { + struct { + int32_t source_id : 16; + int16_t coord_x : 16; + int16_t coord_y : 16; + int32_t alternative_tile : 16; + }; + + uint64_t _u64t; + TileMapCell(int p_source_id = -1, Vector2i p_atlas_coords = Vector2i(-1, -1), int p_alternative_tile = -1) { // default are INVALID_SOURCE, INVALID_ATLAS_COORDS, INVALID_TILE_ALTERNATIVE + source_id = p_source_id; + set_atlas_coords(p_atlas_coords); + alternative_tile = p_alternative_tile; + } + + Vector2i get_atlas_coords() const { + return Vector2i(coord_x, coord_y); + } + + void set_atlas_coords(const Vector2i &r_coords) { + coord_x = r_coords.x; + coord_y = r_coords.y; + } + + bool operator<(const TileMapCell &p_other) const { + if (source_id == p_other.source_id) { + if (coord_x == p_other.coord_x) { + if (coord_y == p_other.coord_y) { + return alternative_tile < p_other.alternative_tile; + } else { + return coord_y < p_other.coord_y; + } + } else { + return coord_x < p_other.coord_x; + } + } else { + return source_id < p_other.source_id; + } + } + + bool operator!=(const TileMapCell &p_other) const { + return !(source_id == p_other.source_id && coord_x == p_other.coord_x && coord_y == p_other.coord_y && alternative_tile == p_other.alternative_tile); + } +}; + +class TileMapPattern : public Resource { + GDCLASS(TileMapPattern, Resource); + + Vector2i size; + Map<Vector2i, TileMapCell> pattern; + + void _set_tile_data(const Vector<int> &p_data); + Vector<int> _get_tile_data() const; + +protected: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + + static void _bind_methods(); + +public: + void set_cell(const Vector2i &p_coords, int p_source_id, const Vector2i p_atlas_coords, int p_alternative_tile = 0); + bool has_cell(const Vector2i &p_coords) const; + void remove_cell(const Vector2i &p_coords, bool p_update_size = true); + int get_cell_source_id(const Vector2i &p_coords) const; + Vector2i get_cell_atlas_coords(const Vector2i &p_coords) const; + int get_cell_alternative_tile(const Vector2i &p_coords) const; + + TypedArray<Vector2i> get_used_cells() const; + + Vector2i get_size() const; + void set_size(const Vector2i &p_size); + bool is_empty() const; + + void clear(); +}; + class TileSet : public Resource { GDCLASS(TileSet, Resource); @@ -176,6 +254,30 @@ public: Vector2 offset; }; + class TerrainsPattern { + bool valid = false; + int bits[TileSet::CELL_NEIGHBOR_MAX]; + bool is_valid_bit[TileSet::CELL_NEIGHBOR_MAX]; + + int not_empty_terrains_count = 0; + + public: + bool is_valid() const; + bool is_erase_pattern() const; + + bool operator<(const TerrainsPattern &p_terrains_pattern) const; + bool operator==(const TerrainsPattern &p_terrains_pattern) const; + + void set_terrain(TileSet::CellNeighbor p_peering_bit, int p_terrain); + int get_terrain(TileSet::CellNeighbor p_peering_bit) const; + + void set_terrains_from_array(Array p_terrains); + Array get_terrains_as_array() const; + + TerrainsPattern(const TileSet *p_tile_set, int p_terrain_set); + TerrainsPattern() {} + }; + protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; @@ -225,6 +327,10 @@ private: Map<TerrainMode, Map<CellNeighbor, Ref<ArrayMesh>>> terrain_bits_meshes; bool terrain_bits_meshes_dirty = true; + LocalVector<Map<TileSet::TerrainsPattern, Set<TileMapCell>>> per_terrain_pattern_tiles; // Cached data. + bool terrains_cache_dirty = true; + void _update_terrains_cache(); + // Navigation struct NavigationLayer { uint32_t layers = 1; @@ -245,6 +351,8 @@ private: int next_source_id = 0; // --------------------- + LocalVector<Ref<TileMapPattern>> patterns; + void _compute_next_source_id(); void _source_changed(); @@ -384,6 +492,17 @@ public: void cleanup_invalid_tile_proxies(); void clear_tile_proxies(); + // Patterns. + int add_pattern(Ref<TileMapPattern> p_pattern, int p_index = -1); + Ref<TileMapPattern> get_pattern(int p_index); + void remove_pattern(int p_index); + int get_patterns_count(); + + // Terrains. + Set<TerrainsPattern> get_terrains_pattern_set(int p_terrain_set); + Set<TileMapCell> get_tiles_for_terrains_pattern(int p_terrain_set, TerrainsPattern p_terrain_tile_pattern); + TileMapCell get_random_tile_from_terrains_pattern(int p_terrain_set, TerrainsPattern p_terrain_tile_pattern); + // Helpers Vector<Vector2> get_tile_shape_polygon(); void draw_tile_shape(CanvasItem *p_canvas_item, Transform2D p_transform, Color p_color, bool p_filled = false, Ref<Texture2D> p_texture = Ref<Texture2D>()); @@ -479,8 +598,16 @@ private: void _compute_next_alternative_id(const Vector2i p_atlas_coords); - void _create_coords_mapping_cache(Vector2i p_atlas_coords); void _clear_coords_mapping_cache(Vector2i p_atlas_coords); + void _create_coords_mapping_cache(Vector2i p_atlas_coords); + + void _clear_tiles_outside_texture(); + + bool use_texture_padding = true; + Ref<ImageTexture> padded_texture; + bool padded_texture_needs_update = false; + void _queue_update_padded_texture(); + void _update_padded_texture(); protected: bool _set(const StringName &p_name, const Variant &p_value); @@ -492,6 +619,7 @@ protected: public: // Not exposed. virtual void set_tile_set(const TileSet *p_tile_set) override; + const TileSet *get_tile_set() const; virtual void notify_tile_data_properties_should_change() override; virtual void add_occlusion_layer(int p_index) override; virtual void move_occlusion_layer(int p_from_index, int p_to_pos) override; @@ -523,6 +651,10 @@ public: void set_texture_region_size(Vector2i p_tile_size); Vector2i get_texture_region_size() const; + // Padding. + void set_use_texture_padding(bool p_use_padding); + bool get_use_texture_padding() const; + // Base tiles. void create_tile(const Vector2i p_atlas_coords, const Vector2i p_size = Vector2i(1, 1)); void remove_tile(Vector2i p_atlas_coords); @@ -534,7 +666,7 @@ public: virtual Vector2i get_tile_id(int p_index) const override; bool has_room_for_tile(Vector2i p_atlas_coords, Vector2i p_size, int p_animation_columns, Vector2i p_animation_separation, int p_frames_count, Vector2i p_ignored_tile = INVALID_ATLAS_COORDS) const; - + PackedVector2Array get_tiles_to_be_removed_on_change(Ref<Texture2D> p_texture, Vector2i p_margins, Vector2i p_separation, Vector2i p_texture_region_size); Vector2i get_tile_at_coords(Vector2i p_atlas_coords) const; // Animation. @@ -565,11 +697,13 @@ public: // Helpers. Vector2i get_atlas_grid_size() const; - bool has_tiles_outside_texture(); - void clear_tiles_outside_texture(); Rect2i get_tile_texture_region(Vector2i p_atlas_coords, int p_frame = 0) const; Vector2i get_tile_effective_texture_offset(Vector2i p_atlas_coords, int p_alternative_tile) const; + // Getters for texture and tile region (padded or not) + Ref<Texture2D> get_runtime_texture() const; + Rect2i get_runtime_tile_texture_region(Vector2i p_atlas_coords, int p_frame = 0) const; + ~TileSetAtlasSource(); }; @@ -647,7 +781,7 @@ private: }; Vector2 linear_velocity; - float angular_velocity = 0.0; + double angular_velocity = 0.0; Vector<PolygonShapeTileData> polygons; }; Vector<PhysicsLayerTileData> physics; @@ -698,6 +832,9 @@ public: void set_allow_transform(bool p_allow_transform); bool is_allowing_transform() const; + // To duplicate a TileData object, needed for runtiume update. + TileData *duplicate(); + // Rendering void set_flip_h(bool p_flip_h); bool get_flip_h() const; @@ -745,6 +882,8 @@ public: int get_peering_bit_terrain(TileSet::CellNeighbor p_peering_bit) const; bool is_valid_peering_bit_terrain(TileSet::CellNeighbor p_peering_bit) const; + TileSet::TerrainsPattern get_terrains_pattern() const; // Not exposed. + // Navigation void set_navigation_polygon(int p_layer_id, Ref<NavigationPolygon> p_navigation_polygon); Ref<NavigationPolygon> get_navigation_polygon(int p_layer_id) const; |