Merge pull request #49024 from groud/restore_tilemap_show_debug

Restore TileMap's debug collision shapes and add navigation.
This commit is contained in:
Rémi Verschelde 2021-06-01 12:51:28 +02:00 committed by GitHub
commit 0286495f59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 103 additions and 52 deletions

View File

@ -132,6 +132,10 @@
<member name="cell_quadrant_size" type="int" setter="set_quadrant_size" getter="get_quadrant_size" default="16">
The TileMap's quadrant size. Optimizes drawing by batching, using chunks of this size.
</member>
<member name="show_collision" type="int" setter="set_collision_visibility_mode" getter="get_collision_visibility_mode" enum="TileMap.VisibilityMode" default="0">
</member>
<member name="show_navigation" type="int" setter="set_navigation_visibility_mode" getter="get_navigation_visibility_mode" enum="TileMap.VisibilityMode" default="0">
</member>
<member name="tile_set" type="TileSet" setter="set_tileset" getter="get_tileset">
The assigned [TileSet].
</member>
@ -144,5 +148,11 @@
</signal>
</signals>
<constants>
<constant name="VISIBILITY_MODE_DEFAULT" value="0" enum="VisibilityMode">
</constant>
<constant name="VISIBILITY_MODE_FORCE_HIDE" value="2" enum="VisibilityMode">
</constant>
<constant name="VISIBILITY_MODE_FORCE_SHOW" value="1" enum="VisibilityMode">
</constant>
</constants>
</class>

View File

@ -314,37 +314,24 @@ void TileMap::set_quadrant_size(int p_size) {
emit_signal("changed");
}
void TileMap::_fix_cell_transform(Transform2D &xform, const TileMapCell &p_cell, const Vector2 &p_offset, const Size2 &p_sc) {
Size2 s = p_sc;
Vector2 offset = p_offset;
void TileMap::set_collision_visibility_mode(TileMap::VisibilityMode p_show_collision) {
show_collision = p_show_collision;
_recreate_quadrants();
emit_signal("changed");
}
// Flip/transpose: update the tile transform.
TileSetSource *source = *tile_set->get_source(p_cell.source_id);
TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
if (!atlas_source) {
return;
}
TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(p_cell.get_atlas_coords(), p_cell.alternative_tile));
if (tile_data->get_transpose()) {
SWAP(xform.elements[0].x, xform.elements[0].y);
SWAP(xform.elements[1].x, xform.elements[1].y);
SWAP(offset.x, offset.y);
SWAP(s.x, s.y);
}
TileMap::VisibilityMode TileMap::get_collision_visibility_mode() {
return show_collision;
}
if (tile_data->get_flip_h()) {
xform.elements[0].x = -xform.elements[0].x;
xform.elements[1].x = -xform.elements[1].x;
offset.x = s.x - offset.x;
}
void TileMap::set_navigation_visibility_mode(TileMap::VisibilityMode p_show_navigation) {
show_navigation = p_show_navigation;
_recreate_quadrants();
emit_signal("changed");
}
if (tile_data->get_flip_v()) {
xform.elements[0].y = -xform.elements[0].y;
xform.elements[1].y = -xform.elements[1].y;
offset.y = s.y - offset.y;
}
xform.elements[2] += offset;
TileMap::VisibilityMode TileMap::get_navigation_visibility_mode() {
return show_navigation;
}
void TileMap::update_dirty_quadrants() {
@ -1723,6 +1710,12 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_quadrant_size", "size"), &TileMap::set_quadrant_size);
ClassDB::bind_method(D_METHOD("get_quadrant_size"), &TileMap::get_quadrant_size);
ClassDB::bind_method(D_METHOD("set_collision_visibility_mode", "show_collision"), &TileMap::set_collision_visibility_mode);
ClassDB::bind_method(D_METHOD("get_collision_visibility_mode"), &TileMap::get_collision_visibility_mode);
ClassDB::bind_method(D_METHOD("set_navigation_visibility_mode", "show_navigation"), &TileMap::set_navigation_visibility_mode);
ClassDB::bind_method(D_METHOD("get_navigation_visibility_mode"), &TileMap::get_navigation_visibility_mode);
ClassDB::bind_method(D_METHOD("set_cell", "coords", "source_id", "atlas_coords", "alternative_tile"), &TileMap::set_cell, DEFVAL(-1), DEFVAL(TileSetSource::INVALID_ATLAS_COORDS), DEFVAL(TileSetSource::INVALID_TILE_ALTERNATIVE));
ClassDB::bind_method(D_METHOD("get_cell_source_id", "coords"), &TileMap::get_cell_source_id);
ClassDB::bind_method(D_METHOD("get_cell_atlas_coords", "coords"), &TileMap::get_cell_atlas_coords);
@ -1747,10 +1740,16 @@ void TileMap::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tile_set", PROPERTY_HINT_RESOURCE_TYPE, "TileSet"), "set_tileset", "get_tileset");
ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_quadrant_size", PROPERTY_HINT_RANGE, "1,128,1"), "set_quadrant_size", "get_quadrant_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "show_collision", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_collision_visibility_mode", "get_collision_visibility_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "show_navigation", PROPERTY_HINT_ENUM, "Default,Force Show,Force Hide"), "set_navigation_visibility_mode", "get_navigation_visibility_mode");
ADD_PROPERTY_DEFAULT("format", FORMAT_1);
ADD_SIGNAL(MethodInfo("changed"));
BIND_ENUM_CONSTANT(VISIBILITY_MODE_DEFAULT);
BIND_ENUM_CONSTANT(VISIBILITY_MODE_FORCE_HIDE);
BIND_ENUM_CONSTANT(VISIBILITY_MODE_FORCE_SHOW);
}
void TileMap::_tile_set_changed() {
@ -1759,12 +1758,6 @@ void TileMap::_tile_set_changed() {
}
TileMap::TileMap() {
rect_cache_dirty = true;
used_size_cache_dirty = true;
pending_update = false;
quadrant_size = 16;
format = FORMAT_1; // Assume lowest possible format if none is present
set_notify_transform(true);
set_notify_local_transform(false);
}

View File

@ -179,37 +179,45 @@ class TileMap : public Node2D {
GDCLASS(TileMap, Node2D);
public:
enum VisibilityMode {
VISIBILITY_MODE_DEFAULT,
VISIBILITY_MODE_FORCE_SHOW,
VISIBILITY_MODE_FORCE_HIDE,
};
private:
friend class TileSetPlugin;
// A compatibility enum to specify how is the data if formatted.
enum DataFormat {
FORMAT_1 = 0,
FORMAT_2,
FORMAT_3
};
mutable DataFormat format = FORMAT_1; // Assume lowest possible format if none is present;
// Properties.
Ref<TileSet> tile_set;
int quadrant_size;
Transform2D custom_transform;
// Map of cells
Map<Vector2i, TileMapCell> tile_map;
Vector2i _coords_to_quadrant_coords(const Vector2i &p_coords) const;
Map<Vector2i, TileMapQuadrant> quadrant_map;
SelfList<TileMapQuadrant>::List dirty_quadrant_list;
int quadrant_size = 16;
VisibilityMode show_collision = VISIBILITY_MODE_DEFAULT;
VisibilityMode show_navigation = VISIBILITY_MODE_DEFAULT;
// Updates.
bool pending_update = false;
// Rect.
Rect2 rect_cache;
bool rect_cache_dirty = true;
Rect2 used_size_cache;
bool used_size_cache_dirty;
mutable DataFormat format;
bool used_size_cache_dirty = true;
void _fix_cell_transform(Transform2D &xform, const TileMapCell &p_cell, const Vector2 &p_offset, const Size2 &p_sc);
// Map of cells.
Map<Vector2i, TileMapCell> tile_map;
// Quadrants management.
Map<Vector2i, TileMapQuadrant> quadrant_map;
Vector2i _coords_to_quadrant_coords(const Vector2i &p_coords) const;
SelfList<TileMapQuadrant>::List dirty_quadrant_list;
Map<Vector2i, TileMapQuadrant>::Element *_create_quadrant(const Vector2i &p_qk);
void _erase_quadrant(Map<Vector2i, TileMapQuadrant>::Element *Q);
@ -219,8 +227,7 @@ private:
void _clear_quadrants();
void _recompute_rect_cache();
void _update_all_items_material_state();
// Set and get tiles from data arrays.
void _set_tile_data(const Vector<int> &p_data);
Vector<int> _get_tile_data() const;
@ -251,6 +258,12 @@ public:
void set_quadrant_size(int p_size);
int get_quadrant_size() const;
void set_collision_visibility_mode(VisibilityMode p_show_collision);
VisibilityMode get_collision_visibility_mode();
void set_navigation_visibility_mode(VisibilityMode p_show_navigation);
VisibilityMode get_navigation_visibility_mode();
void set_cell(const Vector2i &p_coords, int p_source_id = -1, const Vector2i p_atlas_coords = TileSetSource::INVALID_ATLAS_COORDS, int p_alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE);
int get_cell_source_id(const Vector2i &p_coords) const;
Vector2i get_cell_atlas_coords(const Vector2i &p_coords) const;
@ -293,4 +306,7 @@ public:
TileMap();
~TileMap();
};
VARIANT_ENUM_CAST(TileMap::VisibilityMode);
#endif // TILE_MAP_H

View File

@ -4297,7 +4297,23 @@ void TileSetPluginAtlasPhysics::draw_quadrant_debug(TileMap *p_tile_map, TileMap
Ref<TileSet> tile_set = p_tile_map->get_tileset();
ERR_FAIL_COND(!tile_set.is_valid());
if (!p_tile_map->get_tree() || !(Engine::get_singleton()->is_editor_hint() || p_tile_map->get_tree()->is_debugging_collisions_hint())) {
if (!p_tile_map->get_tree()) {
return;
}
bool show_collision = false;
switch (p_tile_map->get_collision_visibility_mode()) {
case TileMap::VISIBILITY_MODE_DEFAULT:
show_collision = !Engine::get_singleton()->is_editor_hint() && (p_tile_map->get_tree() && p_tile_map->get_tree()->is_debugging_navigation_hint());
break;
case TileMap::VISIBILITY_MODE_FORCE_HIDE:
show_collision = false;
break;
case TileMap::VISIBILITY_MODE_FORCE_SHOW:
show_collision = true;
break;
}
if (!show_collision) {
return;
}
@ -4456,7 +4472,23 @@ void TileSetPluginAtlasNavigation::draw_quadrant_debug(TileMap *p_tile_map, Tile
Ref<TileSet> tile_set = p_tile_map->get_tileset();
ERR_FAIL_COND(!tile_set.is_valid());
if (!p_tile_map->get_tree() || !(Engine::get_singleton()->is_editor_hint() || p_tile_map->get_tree()->is_debugging_navigation_hint())) {
if (!p_tile_map->get_tree()) {
return;
}
bool show_navigation = false;
switch (p_tile_map->get_navigation_visibility_mode()) {
case TileMap::VISIBILITY_MODE_DEFAULT:
show_navigation = !Engine::get_singleton()->is_editor_hint() && (p_tile_map->get_tree() && p_tile_map->get_tree()->is_debugging_navigation_hint());
break;
case TileMap::VISIBILITY_MODE_FORCE_HIDE:
show_navigation = false;
break;
case TileMap::VISIBILITY_MODE_FORCE_SHOW:
show_navigation = true;
break;
}
if (!show_navigation) {
return;
}