Explorar o código

Merge pull request #49024 from groud/restore_tilemap_show_debug

Restore TileMap's debug collision shapes and add navigation.
Rémi Verschelde %!s(int64=4) %!d(string=hai) anos
pai
achega
0286495f59
Modificáronse 4 ficheiros con 103 adicións e 52 borrados
  1. 10 0
      doc/classes/TileMap.xml
  2. 27 34
      scene/2d/tile_map.cpp
  3. 32 16
      scene/2d/tile_map.h
  4. 34 2
      scene/resources/tile_set.cpp

+ 10 - 0
doc/classes/TileMap.xml

@@ -132,6 +132,10 @@
 		<member name="cell_quadrant_size" type="int" setter="set_quadrant_size" getter="get_quadrant_size" default="16">
 		<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.
 			The TileMap's quadrant size. Optimizes drawing by batching, using chunks of this size.
 		</member>
 		</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">
 		<member name="tile_set" type="TileSet" setter="set_tileset" getter="get_tileset">
 			The assigned [TileSet].
 			The assigned [TileSet].
 		</member>
 		</member>
@@ -144,5 +148,11 @@
 		</signal>
 		</signal>
 	</signals>
 	</signals>
 	<constants>
 	<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>
 	</constants>
 </class>
 </class>

+ 27 - 34
scene/2d/tile_map.cpp

@@ -314,37 +314,24 @@ void TileMap::set_quadrant_size(int p_size) {
 	emit_signal("changed");
 	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;
-
-	// 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);
-	}
+void TileMap::set_collision_visibility_mode(TileMap::VisibilityMode p_show_collision) {
+	show_collision = p_show_collision;
+	_recreate_quadrants();
+	emit_signal("changed");
+}
 
 
-	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;
-	}
+TileMap::VisibilityMode TileMap::get_collision_visibility_mode() {
+	return show_collision;
+}
 
 
-	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;
-	}
+void TileMap::set_navigation_visibility_mode(TileMap::VisibilityMode p_show_navigation) {
+	show_navigation = p_show_navigation;
+	_recreate_quadrants();
+	emit_signal("changed");
+}
 
 
-	xform.elements[2] += offset;
+TileMap::VisibilityMode TileMap::get_navigation_visibility_mode() {
+	return show_navigation;
 }
 }
 
 
 void TileMap::update_dirty_quadrants() {
 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("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("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("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_source_id", "coords"), &TileMap::get_cell_source_id);
 	ClassDB::bind_method(D_METHOD("get_cell_atlas_coords", "coords"), &TileMap::get_cell_atlas_coords);
 	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::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, "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_PROPERTY_DEFAULT("format", FORMAT_1);
 
 
 	ADD_SIGNAL(MethodInfo("changed"));
 	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() {
 void TileMap::_tile_set_changed() {
@@ -1759,12 +1758,6 @@ void TileMap::_tile_set_changed() {
 }
 }
 
 
 TileMap::TileMap() {
 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_transform(true);
 	set_notify_local_transform(false);
 	set_notify_local_transform(false);
 }
 }

+ 32 - 16
scene/2d/tile_map.h

@@ -179,37 +179,45 @@ class TileMap : public Node2D {
 	GDCLASS(TileMap, Node2D);
 	GDCLASS(TileMap, Node2D);
 
 
 public:
 public:
+	enum VisibilityMode {
+		VISIBILITY_MODE_DEFAULT,
+		VISIBILITY_MODE_FORCE_SHOW,
+		VISIBILITY_MODE_FORCE_HIDE,
+	};
+
 private:
 private:
 	friend class TileSetPlugin;
 	friend class TileSetPlugin;
 
 
+	// A compatibility enum to specify how is the data if formatted.
 	enum DataFormat {
 	enum DataFormat {
 		FORMAT_1 = 0,
 		FORMAT_1 = 0,
 		FORMAT_2,
 		FORMAT_2,
 		FORMAT_3
 		FORMAT_3
 	};
 	};
+	mutable DataFormat format = FORMAT_1; // Assume lowest possible format if none is present;
 
 
+	// Properties.
 	Ref<TileSet> tile_set;
 	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;
 	bool pending_update = false;
 
 
+	// Rect.
 	Rect2 rect_cache;
 	Rect2 rect_cache;
 	bool rect_cache_dirty = true;
 	bool rect_cache_dirty = true;
 	Rect2 used_size_cache;
 	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);
 	Map<Vector2i, TileMapQuadrant>::Element *_create_quadrant(const Vector2i &p_qk);
 	void _erase_quadrant(Map<Vector2i, TileMapQuadrant>::Element *Q);
 	void _erase_quadrant(Map<Vector2i, TileMapQuadrant>::Element *Q);
@@ -219,8 +227,7 @@ private:
 	void _clear_quadrants();
 	void _clear_quadrants();
 	void _recompute_rect_cache();
 	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);
 	void _set_tile_data(const Vector<int> &p_data);
 	Vector<int> _get_tile_data() const;
 	Vector<int> _get_tile_data() const;
 
 
@@ -251,6 +258,12 @@ public:
 	void set_quadrant_size(int p_size);
 	void set_quadrant_size(int p_size);
 	int get_quadrant_size() const;
 	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);
 	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;
 	int get_cell_source_id(const Vector2i &p_coords) const;
 	Vector2i get_cell_atlas_coords(const Vector2i &p_coords) const;
 	Vector2i get_cell_atlas_coords(const Vector2i &p_coords) const;
@@ -293,4 +306,7 @@ public:
 	TileMap();
 	TileMap();
 	~TileMap();
 	~TileMap();
 };
 };
+
+VARIANT_ENUM_CAST(TileMap::VisibilityMode);
+
 #endif // TILE_MAP_H
 #endif // TILE_MAP_H

+ 34 - 2
scene/resources/tile_set.cpp

@@ -4297,7 +4297,23 @@ void TileSetPluginAtlasPhysics::draw_quadrant_debug(TileMap *p_tile_map, TileMap
 	Ref<TileSet> tile_set = p_tile_map->get_tileset();
 	Ref<TileSet> tile_set = p_tile_map->get_tileset();
 	ERR_FAIL_COND(!tile_set.is_valid());
 	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;
 		return;
 	}
 	}
 
 
@@ -4456,7 +4472,23 @@ void TileSetPluginAtlasNavigation::draw_quadrant_debug(TileMap *p_tile_map, Tile
 	Ref<TileSet> tile_set = p_tile_map->get_tileset();
 	Ref<TileSet> tile_set = p_tile_map->get_tileset();
 	ERR_FAIL_COND(!tile_set.is_valid());
 	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;
 		return;
 	}
 	}