mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-30 21:21:10 +00:00 
			
		
		
		
	TileSetEditor: Allow to toggle Convex/Concave collisions. Alternative fix to #24003
This commit is contained in:
		
							parent
							
								
									65084a70fd
								
							
						
					
					
						commit
						7b933d70a8
					
				
					 2 changed files with 170 additions and 34 deletions
				
			
		|  | @ -243,6 +243,7 @@ void TileSetEditor::_notification(int p_what) { | ||||||
| 			tools[ZOOM_1]->set_icon(get_icon("ZoomReset", "EditorIcons")); | 			tools[ZOOM_1]->set_icon(get_icon("ZoomReset", "EditorIcons")); | ||||||
| 			tools[ZOOM_IN]->set_icon(get_icon("ZoomMore", "EditorIcons")); | 			tools[ZOOM_IN]->set_icon(get_icon("ZoomMore", "EditorIcons")); | ||||||
| 			tools[VISIBLE_INFO]->set_icon(get_icon("InformationSign", "EditorIcons")); | 			tools[VISIBLE_INFO]->set_icon(get_icon("InformationSign", "EditorIcons")); | ||||||
|  | 			_update_toggle_shape_button(); | ||||||
| 
 | 
 | ||||||
| 			tool_editmode[EDITMODE_REGION]->set_icon(get_icon("RegionEdit", "EditorIcons")); | 			tool_editmode[EDITMODE_REGION]->set_icon(get_icon("RegionEdit", "EditorIcons")); | ||||||
| 			tool_editmode[EDITMODE_COLLISION]->set_icon(get_icon("StaticBody2D", "EditorIcons")); | 			tool_editmode[EDITMODE_COLLISION]->set_icon(get_icon("StaticBody2D", "EditorIcons")); | ||||||
|  | @ -411,6 +412,12 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) { | ||||||
| 	tools[SHAPE_NEW_POLYGON]->set_button_group(tg); | 	tools[SHAPE_NEW_POLYGON]->set_button_group(tg); | ||||||
| 	tools[SHAPE_NEW_POLYGON]->set_tooltip(TTR("Create a new polygon.")); | 	tools[SHAPE_NEW_POLYGON]->set_tooltip(TTR("Create a new polygon.")); | ||||||
| 
 | 
 | ||||||
|  | 	separator_shape_toggle = memnew(VSeparator); | ||||||
|  | 	toolbar->add_child(separator_shape_toggle); | ||||||
|  | 	tools[SHAPE_TOGGLE_TYPE] = memnew(ToolButton); | ||||||
|  | 	tools[SHAPE_TOGGLE_TYPE]->connect("pressed", this, "_on_tool_clicked", varray(SHAPE_TOGGLE_TYPE)); | ||||||
|  | 	toolbar->add_child(tools[SHAPE_TOGGLE_TYPE]); | ||||||
|  | 
 | ||||||
| 	separator_delete = memnew(VSeparator); | 	separator_delete = memnew(VSeparator); | ||||||
| 	toolbar->add_child(separator_delete); | 	toolbar->add_child(separator_delete); | ||||||
| 	tools[SHAPE_DELETE] = memnew(ToolButton); | 	tools[SHAPE_DELETE] = memnew(ToolButton); | ||||||
|  | @ -765,6 +772,7 @@ void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) { | ||||||
| 		} break; | 		} break; | ||||||
| 		default: {} | 		default: {} | ||||||
| 	} | 	} | ||||||
|  | 	_update_toggle_shape_button(); | ||||||
| 	workspace->update(); | 	workspace->update(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1367,8 +1375,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { | ||||||
| 										} | 										} | ||||||
| 
 | 
 | ||||||
| 										undo_redo->create_action(TTR("Edit Collision Polygon")); | 										undo_redo->create_action(TTR("Edit Collision Polygon")); | ||||||
| 										undo_redo->add_do_method(edited_collision_shape.ptr(), "set_points", points); | 										_set_edited_shape_points(points); | ||||||
| 										undo_redo->add_undo_method(edited_collision_shape.ptr(), "set_points", edited_collision_shape->get_points()); |  | ||||||
| 										undo_redo->add_do_method(this, "_select_edited_shape_coord"); | 										undo_redo->add_do_method(this, "_select_edited_shape_coord"); | ||||||
| 										undo_redo->add_undo_method(this, "_select_edited_shape_coord"); | 										undo_redo->add_undo_method(this, "_select_edited_shape_coord"); | ||||||
| 										undo_redo->commit_action(); | 										undo_redo->commit_action(); | ||||||
|  | @ -1446,7 +1453,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { | ||||||
| 									workspace->update(); | 									workspace->update(); | ||||||
| 								} else { | 								} else { | ||||||
| 									creating_shape = true; | 									creating_shape = true; | ||||||
| 									edited_collision_shape = Ref<ConvexPolygonShape2D>(); | 									_set_edited_collision_shape(Ref<ConvexPolygonShape2D>()); | ||||||
| 									current_shape.resize(0); | 									current_shape.resize(0); | ||||||
| 									current_shape.push_back(snap_point(pos)); | 									current_shape.push_back(snap_point(pos)); | ||||||
| 									workspace->update(); | 									workspace->update(); | ||||||
|  | @ -1466,7 +1473,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { | ||||||
| 					} else if (tools[SHAPE_NEW_RECTANGLE]->is_pressed()) { | 					} else if (tools[SHAPE_NEW_RECTANGLE]->is_pressed()) { | ||||||
| 						if (mb.is_valid()) { | 						if (mb.is_valid()) { | ||||||
| 							if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { | 							if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { | ||||||
| 								edited_collision_shape = Ref<ConvexPolygonShape2D>(); | 								_set_edited_collision_shape(Ref<ConvexPolygonShape2D>()); | ||||||
| 								current_shape.resize(0); | 								current_shape.resize(0); | ||||||
| 								current_shape.push_back(snap_point(shape_anchor)); | 								current_shape.push_back(snap_point(shape_anchor)); | ||||||
| 								current_shape.push_back(snap_point(shape_anchor + Vector2(current_tile_region.size.x, 0))); | 								current_shape.push_back(snap_point(shape_anchor + Vector2(current_tile_region.size.x, 0))); | ||||||
|  | @ -1511,6 +1518,45 @@ void TileSetEditor::_on_tool_clicked(int p_tool) { | ||||||
| 		undo_redo->add_do_method(workspace, "update"); | 		undo_redo->add_do_method(workspace, "update"); | ||||||
| 		undo_redo->add_undo_method(workspace, "update"); | 		undo_redo->add_undo_method(workspace, "update"); | ||||||
| 		undo_redo->commit_action(); | 		undo_redo->commit_action(); | ||||||
|  | 	} else if (p_tool == SHAPE_TOGGLE_TYPE) { | ||||||
|  | 		if (edited_collision_shape.is_valid()) { | ||||||
|  | 			Ref<ConvexPolygonShape2D> convex = edited_collision_shape; | ||||||
|  | 			Ref<ConcavePolygonShape2D> concave = edited_collision_shape; | ||||||
|  | 			Ref<Shape2D> previous_shape = edited_collision_shape; | ||||||
|  | 			Array sd = tileset->call("tile_get_shapes", get_current_tile()); | ||||||
|  | 
 | ||||||
|  | 			if (convex.is_valid()) { | ||||||
|  | 				// Make concave
 | ||||||
|  | 				undo_redo->create_action(TTR("Make Polygon Concave")); | ||||||
|  | 				Ref<ConcavePolygonShape2D> _concave = memnew(ConcavePolygonShape2D); | ||||||
|  | 				edited_collision_shape = _concave; | ||||||
|  | 				_set_edited_shape_points(_get_collision_shape_points(convex)); | ||||||
|  | 			} else if (concave.is_valid()) { | ||||||
|  | 				// Make convex
 | ||||||
|  | 				undo_redo->create_action(TTR("Make Polygon Convex")); | ||||||
|  | 				Ref<ConvexPolygonShape2D> _convex = memnew(ConvexPolygonShape2D); | ||||||
|  | 				edited_collision_shape = _convex; | ||||||
|  | 				_set_edited_shape_points(_get_collision_shape_points(concave)); | ||||||
|  | 			} else { | ||||||
|  | 				// Shoudn't haphen
 | ||||||
|  | 			} | ||||||
|  | 			for (int i = 0; i < sd.size(); i++) { | ||||||
|  | 				if (sd[i].get("shape") == previous_shape) { | ||||||
|  | 					undo_redo->add_undo_method(tileset.ptr(), "tile_set_shapes", get_current_tile(), sd.duplicate()); | ||||||
|  | 					sd.remove(i); | ||||||
|  | 					sd.insert(i, edited_collision_shape); | ||||||
|  | 					undo_redo->add_do_method(tileset.ptr(), "tile_set_shapes", get_current_tile(), sd); | ||||||
|  | 					undo_redo->add_do_method(this, "_select_edited_shape_coord"); | ||||||
|  | 					undo_redo->add_undo_method(this, "_select_edited_shape_coord"); | ||||||
|  | 					undo_redo->commit_action(); | ||||||
|  | 					break; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			_update_toggle_shape_button(); | ||||||
|  | 			workspace->update(); | ||||||
|  | 			workspace_container->update(); | ||||||
|  | 			helper->_change_notify(""); | ||||||
|  | 		} | ||||||
| 	} else if (p_tool == SELECT_NEXT) { | 	} else if (p_tool == SELECT_NEXT) { | ||||||
| 		_select_next_shape(); | 		_select_next_shape(); | ||||||
| 	} else if (p_tool == SELECT_PREVIOUS) { | 	} else if (p_tool == SELECT_PREVIOUS) { | ||||||
|  | @ -1629,6 +1675,48 @@ void TileSetEditor::_on_grid_snap_toggled(bool p_val) { | ||||||
| 	workspace->update(); | 	workspace->update(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | Vector<Vector2> TileSetEditor::_get_collision_shape_points(const Ref<Shape2D> &p_shape) { | ||||||
|  | 	Ref<ConvexPolygonShape2D> convex = p_shape; | ||||||
|  | 	Ref<ConcavePolygonShape2D> concave = p_shape; | ||||||
|  | 	if (convex.is_valid()) { | ||||||
|  | 		return convex->get_points(); | ||||||
|  | 	} else if (concave.is_valid()) { | ||||||
|  | 		Vector<Vector2> points; | ||||||
|  | 		for (int i = 0; i < concave->get_segments().size(); i += 2) { | ||||||
|  | 			points.push_back(concave->get_segments()[i]); | ||||||
|  | 		} | ||||||
|  | 		return points; | ||||||
|  | 	} else { | ||||||
|  | 		return Vector<Vector2>(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Vector<Vector2> TileSetEditor::_get_edited_shape_points() { | ||||||
|  | 	return _get_collision_shape_points(edited_collision_shape); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TileSetEditor::_set_edited_shape_points(const Vector<Vector2> points) { | ||||||
|  | 	Ref<ConvexPolygonShape2D> convex = edited_collision_shape; | ||||||
|  | 	Ref<ConcavePolygonShape2D> concave = edited_collision_shape; | ||||||
|  | 	if (convex.is_valid()) { | ||||||
|  | 		undo_redo->add_do_method(convex.ptr(), "set_points", points); | ||||||
|  | 		undo_redo->add_undo_method(convex.ptr(), "set_points", _get_edited_shape_points()); | ||||||
|  | 	} else if (concave.is_valid()) { | ||||||
|  | 		PoolVector2Array segments; | ||||||
|  | 		for (int i = 0; i < points.size() - 1; i++) { | ||||||
|  | 			segments.push_back(points[i]); | ||||||
|  | 			segments.push_back(points[i + 1]); | ||||||
|  | 		} | ||||||
|  | 		segments.push_back(points[points.size() - 1]); | ||||||
|  | 		segments.push_back(points[0]); | ||||||
|  | 		concave->set_segments(segments); | ||||||
|  | 		undo_redo->add_do_method(concave.ptr(), "set_segments", segments); | ||||||
|  | 		undo_redo->add_undo_method(concave.ptr(), "set_segments", concave->get_segments()); | ||||||
|  | 	} else { | ||||||
|  | 		// Invalid shape
 | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void TileSetEditor::_update_tile_data() { | void TileSetEditor::_update_tile_data() { | ||||||
| 	current_tile_data.clear(); | 	current_tile_data.clear(); | ||||||
| 	if (get_current_tile() < 0) | 	if (get_current_tile() < 0) | ||||||
|  | @ -1664,6 +1752,27 @@ void TileSetEditor::_update_tile_data() { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void TileSetEditor::_update_toggle_shape_button() { | ||||||
|  | 	Ref<ConvexPolygonShape2D> convex = edited_collision_shape; | ||||||
|  | 	Ref<ConcavePolygonShape2D> concave = edited_collision_shape; | ||||||
|  | 	separator_shape_toggle->show(); | ||||||
|  | 	tools[SHAPE_TOGGLE_TYPE]->show(); | ||||||
|  | 	if (edit_mode != EDITMODE_COLLISION || !edited_collision_shape.is_valid()) { | ||||||
|  | 		separator_shape_toggle->hide(); | ||||||
|  | 		tools[SHAPE_TOGGLE_TYPE]->hide(); | ||||||
|  | 	} else if (concave.is_valid()) { | ||||||
|  | 		tools[SHAPE_TOGGLE_TYPE]->set_icon(get_icon("ConvexPolygonShape2D", "EditorIcons")); | ||||||
|  | 		tools[SHAPE_TOGGLE_TYPE]->set_text("Make Convex"); | ||||||
|  | 	} else if (convex.is_valid()) { | ||||||
|  | 		tools[SHAPE_TOGGLE_TYPE]->set_icon(get_icon("ConcavePolygonShape2D", "EditorIcons")); | ||||||
|  | 		tools[SHAPE_TOGGLE_TYPE]->set_text("Make Concave"); | ||||||
|  | 	} else { | ||||||
|  | 		// Shoudn't happen
 | ||||||
|  | 		separator_shape_toggle->hide(); | ||||||
|  | 		tools[SHAPE_TOGGLE_TYPE]->hide(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void TileSetEditor::_select_next_tile() { | void TileSetEditor::_select_next_tile() { | ||||||
| 	Array tiles = _get_tiles_in_current_texture(true); | 	Array tiles = _get_tiles_in_current_texture(true); | ||||||
| 	if (tiles.size() == 0) { | 	if (tiles.size() == 0) { | ||||||
|  | @ -1842,11 +1951,11 @@ void TileSetEditor::_select_next_shape() { | ||||||
| 		} else { | 		} else { | ||||||
| 			int index = data.collisions.find(edited_collision_shape); | 			int index = data.collisions.find(edited_collision_shape); | ||||||
| 			if (index < 0) { | 			if (index < 0) { | ||||||
| 				edited_collision_shape = data.collisions[0]; | 				_set_edited_collision_shape(data.collisions[0]); | ||||||
| 			} else if (index == data.collisions.size() - 1) { | 			} else if (index == data.collisions.size() - 1) { | ||||||
| 				_select_next_subtile(); | 				_select_next_subtile(); | ||||||
| 			} else { | 			} else { | ||||||
| 				edited_collision_shape = data.collisions[index + 1]; | 				_set_edited_collision_shape(data.collisions[index + 1]); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		current_shape.resize(0); | 		current_shape.resize(0); | ||||||
|  | @ -1861,8 +1970,8 @@ void TileSetEditor::_select_next_shape() { | ||||||
| 		current_tile_region.position += shape_anchor; | 		current_tile_region.position += shape_anchor; | ||||||
| 
 | 
 | ||||||
| 		if (edited_collision_shape.is_valid()) { | 		if (edited_collision_shape.is_valid()) { | ||||||
| 			for (int i = 0; i < edited_collision_shape->get_points().size(); i++) { | 			for (int i = 0; i < _get_edited_shape_points().size(); i++) { | ||||||
| 				current_shape.push_back(edited_collision_shape->get_points()[i] + current_tile_region.position); | 				current_shape.push_back(_get_edited_shape_points()[i] + current_tile_region.position); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		workspace->update(); | 		workspace->update(); | ||||||
|  | @ -1877,7 +1986,7 @@ void TileSetEditor::_select_previous_shape() { | ||||||
| 		if (get_current_tile() != -1 && edit_mode == EDITMODE_COLLISION) { | 		if (get_current_tile() != -1 && edit_mode == EDITMODE_COLLISION) { | ||||||
| 			SubtileData data = current_tile_data[Vector2i(edited_shape_coord)]; | 			SubtileData data = current_tile_data[Vector2i(edited_shape_coord)]; | ||||||
| 			if (data.collisions.size() > 1) { | 			if (data.collisions.size() > 1) { | ||||||
| 				edited_collision_shape = data.collisions[data.collisions.size() - 1]; | 				_set_edited_collision_shape(data.collisions[data.collisions.size() - 1]); | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			return; | 			return; | ||||||
|  | @ -1894,22 +2003,23 @@ void TileSetEditor::_select_previous_shape() { | ||||||
| 			_select_previous_subtile(); | 			_select_previous_subtile(); | ||||||
| 			data = current_tile_data[Vector2i(edited_shape_coord)]; | 			data = current_tile_data[Vector2i(edited_shape_coord)]; | ||||||
| 			if (data.collisions.size() > 1) { | 			if (data.collisions.size() > 1) { | ||||||
| 				edited_collision_shape = data.collisions[data.collisions.size() - 1]; | 				_set_edited_collision_shape(data.collisions[data.collisions.size() - 1]); | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			int index = data.collisions.find(edited_collision_shape); | 			int index = data.collisions.find(edited_collision_shape); | ||||||
| 			if (index < 0) { | 			if (index < 0) { | ||||||
| 				edited_collision_shape = data.collisions[data.collisions.size() - 1]; | 				_set_edited_collision_shape(data.collisions[data.collisions.size() - 1]); | ||||||
| 			} else if (index == 0) { | 			} else if (index == 0) { | ||||||
| 				_select_previous_subtile(); | 				_select_previous_subtile(); | ||||||
| 				data = current_tile_data[Vector2i(edited_shape_coord)]; | 				data = current_tile_data[Vector2i(edited_shape_coord)]; | ||||||
| 				if (data.collisions.size() > 1) { | 				if (data.collisions.size() > 1) { | ||||||
| 					edited_collision_shape = data.collisions[data.collisions.size() - 1]; | 					_set_edited_collision_shape(data.collisions[data.collisions.size() - 1]); | ||||||
| 				} | 				} | ||||||
| 			} else { | 			} else { | ||||||
| 				edited_collision_shape = data.collisions[index - 1]; | 				_set_edited_collision_shape(data.collisions[index - 1]); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
| 		current_shape.resize(0); | 		current_shape.resize(0); | ||||||
| 		Rect2 current_tile_region = tileset->tile_get_region(get_current_tile()); | 		Rect2 current_tile_region = tileset->tile_get_region(get_current_tile()); | ||||||
| 		current_tile_region.position += WORKSPACE_MARGIN; | 		current_tile_region.position += WORKSPACE_MARGIN; | ||||||
|  | @ -1922,8 +2032,8 @@ void TileSetEditor::_select_previous_shape() { | ||||||
| 		current_tile_region.position += shape_anchor; | 		current_tile_region.position += shape_anchor; | ||||||
| 
 | 
 | ||||||
| 		if (edited_collision_shape.is_valid()) { | 		if (edited_collision_shape.is_valid()) { | ||||||
| 			for (int i = 0; i < edited_collision_shape->get_points().size(); i++) { | 			for (int i = 0; i < _get_edited_shape_points().size(); i++) { | ||||||
| 				current_shape.push_back(edited_collision_shape->get_points()[i] + current_tile_region.position); | 				current_shape.push_back(_get_edited_shape_points()[i] + current_tile_region.position); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		workspace->update(); | 		workspace->update(); | ||||||
|  | @ -1932,6 +2042,11 @@ void TileSetEditor::_select_previous_shape() { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void TileSetEditor::_set_edited_collision_shape(const Ref<Shape2D> &p_shape) { | ||||||
|  | 	edited_collision_shape = p_shape; | ||||||
|  | 	_update_toggle_shape_button(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void TileSetEditor::_set_snap_step(Vector2 p_val) { | void TileSetEditor::_set_snap_step(Vector2 p_val) { | ||||||
| 	snap_step.x = CLAMP(p_val.x, 0, 256); | 	snap_step.x = CLAMP(p_val.x, 0, 256); | ||||||
| 	snap_step.y = CLAMP(p_val.y, 0, 256); | 	snap_step.y = CLAMP(p_val.y, 0, 256); | ||||||
|  | @ -2228,16 +2343,29 @@ void TileSetEditor::draw_polygon_shapes() { | ||||||
| 				} | 				} | ||||||
| 				anchor += WORKSPACE_MARGIN; | 				anchor += WORKSPACE_MARGIN; | ||||||
| 				anchor += tileset->tile_get_region(t_id).position; | 				anchor += tileset->tile_get_region(t_id).position; | ||||||
| 				Ref<ConvexPolygonShape2D> shape = sd[i].shape; | 				Ref<Shape2D> shape = sd[i].shape; | ||||||
| 				if (shape.is_valid()) { | 				if (shape.is_valid()) { | ||||||
| 					Color c_bg; | 					Color c_bg; | ||||||
| 					Color c_border; | 					Color c_border; | ||||||
|  | 					Ref<ConvexPolygonShape2D> convex = shape; | ||||||
|  | 					bool is_convex = convex.is_valid(); | ||||||
| 					if ((tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE || coord == edited_shape_coord) && sd[i].shape == edited_collision_shape) { | 					if ((tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE || coord == edited_shape_coord) && sd[i].shape == edited_collision_shape) { | ||||||
| 						c_bg = Color(0, 1, 1, 0.5); | 						if (is_convex) { | ||||||
| 						c_border = Color(0, 1, 1); | 							c_bg = Color(0, 1, 1, 0.5); | ||||||
|  | 							c_border = Color(0, 1, 1); | ||||||
|  | 						} else { | ||||||
|  | 							c_bg = Color(0.8, 0, 1, 0.5); | ||||||
|  | 							c_border = Color(0.8, 0, 1); | ||||||
|  | 						} | ||||||
| 					} else { | 					} else { | ||||||
| 						c_bg = Color(0.9, 0.7, 0.07, 0.5); | 						if (is_convex) { | ||||||
| 						c_border = Color(0.9, 0.7, 0.07, 1); | 							c_bg = Color(0.9, 0.7, 0.07, 0.5); | ||||||
|  | 							c_border = Color(0.9, 0.7, 0.07, 1); | ||||||
|  | 
 | ||||||
|  | 						} else { | ||||||
|  | 							c_bg = Color(0.9, 0.45, 0.075, 0.5); | ||||||
|  | 							c_border = Color(0.9, 0.45, 0.075); | ||||||
|  | 						} | ||||||
| 					} | 					} | ||||||
| 					Vector<Vector2> polygon; | 					Vector<Vector2> polygon; | ||||||
| 					Vector<Color> colors; | 					Vector<Color> colors; | ||||||
|  | @ -2247,8 +2375,8 @@ void TileSetEditor::draw_polygon_shapes() { | ||||||
| 							colors.push_back(c_bg); | 							colors.push_back(c_bg); | ||||||
| 						} | 						} | ||||||
| 					} else { | 					} else { | ||||||
| 						for (int j = 0; j < shape->get_points().size(); j++) { | 						for (int j = 0; j < _get_collision_shape_points(shape).size(); j++) { | ||||||
| 							polygon.push_back(shape->get_points()[j] + anchor); | 							polygon.push_back(_get_collision_shape_points(shape)[j] + anchor); | ||||||
| 							colors.push_back(c_bg); | 							colors.push_back(c_bg); | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
|  | @ -2465,11 +2593,11 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) { | ||||||
| 		if (current_shape.size() >= 3) { | 		if (current_shape.size() >= 3) { | ||||||
| 			Ref<ConvexPolygonShape2D> shape = memnew(ConvexPolygonShape2D); | 			Ref<ConvexPolygonShape2D> shape = memnew(ConvexPolygonShape2D); | ||||||
| 
 | 
 | ||||||
| 			Vector<Vector2> segments; | 			Vector<Vector2> points; | ||||||
| 			float p_total = 0; | 			float p_total = 0; | ||||||
| 
 | 
 | ||||||
| 			for (int i = 0; i < current_shape.size(); i++) { | 			for (int i = 0; i < current_shape.size(); i++) { | ||||||
| 				segments.push_back(current_shape[i] - shape_anchor); | 				points.push_back(current_shape[i] - shape_anchor); | ||||||
| 
 | 
 | ||||||
| 				if (i != current_shape.size() - 1) | 				if (i != current_shape.size() - 1) | ||||||
| 					p_total += ((current_shape[i + 1].x - current_shape[i].x) * (-current_shape[i + 1].y + (-current_shape[i].y))); | 					p_total += ((current_shape[i + 1].x - current_shape[i].x) * (-current_shape[i + 1].y + (-current_shape[i].y))); | ||||||
|  | @ -2478,9 +2606,9 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) { | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if (p_total < 0) | 			if (p_total < 0) | ||||||
| 				segments.invert(); | 				points.invert(); | ||||||
| 
 | 
 | ||||||
| 			shape->set_points(segments); | 			shape->set_points(points); | ||||||
| 
 | 
 | ||||||
| 			undo_redo->create_action(TTR("Create Collision Polygon")); | 			undo_redo->create_action(TTR("Create Collision Polygon")); | ||||||
| 			// Necessary to get the version that returns a Array instead of a Vector.
 | 			// Necessary to get the version that returns a Array instead of a Vector.
 | ||||||
|  | @ -2573,7 +2701,7 @@ void TileSetEditor::select_coord(const Vector2 &coord) { | ||||||
| 	current_tile_region.position += WORKSPACE_MARGIN; | 	current_tile_region.position += WORKSPACE_MARGIN; | ||||||
| 	if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) { | 	if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) { | ||||||
| 		if (edited_collision_shape != tileset->tile_get_shape(get_current_tile(), 0)) | 		if (edited_collision_shape != tileset->tile_get_shape(get_current_tile(), 0)) | ||||||
| 			edited_collision_shape = tileset->tile_get_shape(get_current_tile(), 0); | 			_set_edited_collision_shape(tileset->tile_get_shape(get_current_tile(), 0)); | ||||||
| 		if (edited_occlusion_shape != tileset->tile_get_light_occluder(get_current_tile())) | 		if (edited_occlusion_shape != tileset->tile_get_light_occluder(get_current_tile())) | ||||||
| 			edited_occlusion_shape = tileset->tile_get_light_occluder(get_current_tile()); | 			edited_occlusion_shape = tileset->tile_get_light_occluder(get_current_tile()); | ||||||
| 		if (edited_navigation_shape != tileset->tile_get_navigation_polygon(get_current_tile())) | 		if (edited_navigation_shape != tileset->tile_get_navigation_polygon(get_current_tile())) | ||||||
|  | @ -2582,8 +2710,8 @@ void TileSetEditor::select_coord(const Vector2 &coord) { | ||||||
| 		if (edit_mode == EDITMODE_COLLISION) { | 		if (edit_mode == EDITMODE_COLLISION) { | ||||||
| 			current_shape.resize(0); | 			current_shape.resize(0); | ||||||
| 			if (edited_collision_shape.is_valid()) { | 			if (edited_collision_shape.is_valid()) { | ||||||
| 				for (int i = 0; i < edited_collision_shape->get_points().size(); i++) { | 				for (int i = 0; i < _get_edited_shape_points().size(); i++) { | ||||||
| 					current_shape.push_back(edited_collision_shape->get_points()[i] + current_tile_region.position); | 					current_shape.push_back(_get_edited_shape_points()[i] + current_tile_region.position); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} else if (edit_mode == EDITMODE_OCCLUSION) { | 		} else if (edit_mode == EDITMODE_OCCLUSION) { | ||||||
|  | @ -2610,13 +2738,13 @@ void TileSetEditor::select_coord(const Vector2 &coord) { | ||||||
| 		for (int i = 0; i < sd.size(); i++) { | 		for (int i = 0; i < sd.size(); i++) { | ||||||
| 			if (sd[i].autotile_coord == coord) { | 			if (sd[i].autotile_coord == coord) { | ||||||
| 				if (edited_collision_shape != sd[i].shape) | 				if (edited_collision_shape != sd[i].shape) | ||||||
| 					edited_collision_shape = sd[i].shape; | 					_set_edited_collision_shape(sd[i].shape); | ||||||
| 				found_collision_shape = true; | 				found_collision_shape = true; | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		if (!found_collision_shape) | 		if (!found_collision_shape) | ||||||
| 			edited_collision_shape = Ref<ConvexPolygonShape2D>(NULL); | 			_set_edited_collision_shape(Ref<ConvexPolygonShape2D>(NULL)); | ||||||
| 		if (edited_occlusion_shape != tileset->autotile_get_light_occluder(get_current_tile(), coord)) | 		if (edited_occlusion_shape != tileset->autotile_get_light_occluder(get_current_tile(), coord)) | ||||||
| 			edited_occlusion_shape = tileset->autotile_get_light_occluder(get_current_tile(), coord); | 			edited_occlusion_shape = tileset->autotile_get_light_occluder(get_current_tile(), coord); | ||||||
| 		if (edited_navigation_shape != tileset->autotile_get_navigation_polygon(get_current_tile(), coord)) | 		if (edited_navigation_shape != tileset->autotile_get_navigation_polygon(get_current_tile(), coord)) | ||||||
|  | @ -2631,8 +2759,8 @@ void TileSetEditor::select_coord(const Vector2 &coord) { | ||||||
| 		if (edit_mode == EDITMODE_COLLISION) { | 		if (edit_mode == EDITMODE_COLLISION) { | ||||||
| 			current_shape.resize(0); | 			current_shape.resize(0); | ||||||
| 			if (edited_collision_shape.is_valid()) { | 			if (edited_collision_shape.is_valid()) { | ||||||
| 				for (int j = 0; j < edited_collision_shape->get_points().size(); j++) { | 				for (int j = 0; j < _get_edited_shape_points().size(); j++) { | ||||||
| 					current_shape.push_back(edited_collision_shape->get_points()[j] + shape_anchor); | 					current_shape.push_back(_get_edited_shape_points()[j] + shape_anchor); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} else if (edit_mode == EDITMODE_OCCLUSION) { | 		} else if (edit_mode == EDITMODE_OCCLUSION) { | ||||||
|  |  | ||||||
|  | @ -34,6 +34,7 @@ | ||||||
| #include "editor/editor_name_dialog.h" | #include "editor/editor_name_dialog.h" | ||||||
| #include "editor/editor_node.h" | #include "editor/editor_node.h" | ||||||
| #include "scene/2d/sprite.h" | #include "scene/2d/sprite.h" | ||||||
|  | #include "scene/resources/concave_polygon_shape_2d.h" | ||||||
| #include "scene/resources/convex_polygon_shape_2d.h" | #include "scene/resources/convex_polygon_shape_2d.h" | ||||||
| #include "scene/resources/tile_set.h" | #include "scene/resources/tile_set.h" | ||||||
| 
 | 
 | ||||||
|  | @ -84,6 +85,7 @@ class TileSetEditor : public HSplitContainer { | ||||||
| 		BITMASK_CLEAR, | 		BITMASK_CLEAR, | ||||||
| 		SHAPE_NEW_POLYGON, | 		SHAPE_NEW_POLYGON, | ||||||
| 		SHAPE_NEW_RECTANGLE, | 		SHAPE_NEW_RECTANGLE, | ||||||
|  | 		SHAPE_TOGGLE_TYPE, | ||||||
| 		SHAPE_DELETE, | 		SHAPE_DELETE, | ||||||
| 		SHAPE_KEEP_INSIDE_TILE, | 		SHAPE_KEEP_INSIDE_TILE, | ||||||
| 		TOOL_GRID_SNAP, | 		TOOL_GRID_SNAP, | ||||||
|  | @ -130,7 +132,7 @@ class TileSetEditor : public HSplitContainer { | ||||||
| 	Vector2 snap_offset; | 	Vector2 snap_offset; | ||||||
| 	Vector2 snap_separation; | 	Vector2 snap_separation; | ||||||
| 
 | 
 | ||||||
| 	Ref<ConvexPolygonShape2D> edited_collision_shape; | 	Ref<Shape2D> edited_collision_shape; | ||||||
| 	Ref<OccluderPolygon2D> edited_occlusion_shape; | 	Ref<OccluderPolygon2D> edited_occlusion_shape; | ||||||
| 	Ref<NavigationPolygon> edited_navigation_shape; | 	Ref<NavigationPolygon> edited_navigation_shape; | ||||||
| 
 | 
 | ||||||
|  | @ -146,6 +148,7 @@ class TileSetEditor : public HSplitContainer { | ||||||
| 	HSeparator *separator_editmode; | 	HSeparator *separator_editmode; | ||||||
| 	HBoxContainer *toolbar; | 	HBoxContainer *toolbar; | ||||||
| 	ToolButton *tools[TOOL_MAX]; | 	ToolButton *tools[TOOL_MAX]; | ||||||
|  | 	VSeparator *separator_shape_toggle; | ||||||
| 	VSeparator *separator_bitmask; | 	VSeparator *separator_bitmask; | ||||||
| 	VSeparator *separator_delete; | 	VSeparator *separator_delete; | ||||||
| 	VSeparator *separator_grid; | 	VSeparator *separator_grid; | ||||||
|  | @ -197,7 +200,11 @@ private: | ||||||
| 	void _on_priority_changed(float val); | 	void _on_priority_changed(float val); | ||||||
| 	void _on_z_index_changed(float val); | 	void _on_z_index_changed(float val); | ||||||
| 	void _on_grid_snap_toggled(bool p_val); | 	void _on_grid_snap_toggled(bool p_val); | ||||||
|  | 	Vector<Vector2> _get_collision_shape_points(const Ref<Shape2D> &p_shape); | ||||||
|  | 	Vector<Vector2> _get_edited_shape_points(); | ||||||
|  | 	void _set_edited_shape_points(const Vector<Vector2> points); | ||||||
| 	void _update_tile_data(); | 	void _update_tile_data(); | ||||||
|  | 	void _update_toggle_shape_button(); | ||||||
| 	void _select_next_tile(); | 	void _select_next_tile(); | ||||||
| 	void _select_previous_tile(); | 	void _select_previous_tile(); | ||||||
| 	Array _get_tiles_in_current_texture(bool sorted = false); | 	Array _get_tiles_in_current_texture(bool sorted = false); | ||||||
|  | @ -206,6 +213,7 @@ private: | ||||||
| 	void _select_previous_subtile(); | 	void _select_previous_subtile(); | ||||||
| 	void _select_next_shape(); | 	void _select_next_shape(); | ||||||
| 	void _select_previous_shape(); | 	void _select_previous_shape(); | ||||||
|  | 	void _set_edited_collision_shape(const Ref<Shape2D> &p_shape); | ||||||
| 	void _set_snap_step(Vector2 p_val); | 	void _set_snap_step(Vector2 p_val); | ||||||
| 	void _set_snap_off(Vector2 p_val); | 	void _set_snap_off(Vector2 p_val); | ||||||
| 	void _set_snap_sep(Vector2 p_val); | 	void _set_snap_sep(Vector2 p_val); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Mariano Suligoy
						Mariano Suligoy