mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-30 21:21:10 +00:00 
			
		
		
		
	Improve reliability of 2D shape editor redrawing
This commit is contained in:
		
							parent
							
								
									26fb911f79
								
							
						
					
					
						commit
						d8e39912f8
					
				
					 2 changed files with 34 additions and 72 deletions
				
			
		|  | @ -42,6 +42,7 @@ | |||
| #include "scene/resources/segment_shape_2d.h" | ||||
| #include "scene/resources/separation_ray_shape_2d.h" | ||||
| #include "scene/resources/world_boundary_shape_2d.h" | ||||
| #include "scene/scene_string_names.h" | ||||
| 
 | ||||
| void CollisionShape2DEditor::_node_removed(Node *p_node) { | ||||
| 	if (p_node == node) { | ||||
|  | @ -129,8 +130,6 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { | |||
| 				} else if (idx == 1) { | ||||
| 					capsule->set_height(parameter * 2); | ||||
| 				} | ||||
| 
 | ||||
| 				canvas_item_editor->update_viewport(); | ||||
| 			} | ||||
| 
 | ||||
| 		} break; | ||||
|  | @ -138,9 +137,6 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { | |||
| 		case CIRCLE_SHAPE: { | ||||
| 			Ref<CircleShape2D> circle = node->get_shape(); | ||||
| 			circle->set_radius(p_point.length()); | ||||
| 
 | ||||
| 			canvas_item_editor->update_viewport(); | ||||
| 
 | ||||
| 		} break; | ||||
| 
 | ||||
| 		case CONCAVE_POLYGON_SHAPE: { | ||||
|  | @ -158,19 +154,13 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { | |||
| 				} else { | ||||
| 					world_boundary->set_normal(p_point.normalized()); | ||||
| 				} | ||||
| 
 | ||||
| 				canvas_item_editor->update_viewport(); | ||||
| 			} | ||||
| 
 | ||||
| 		} break; | ||||
| 
 | ||||
| 		case SEPARATION_RAY_SHAPE: { | ||||
| 			Ref<SeparationRayShape2D> ray = node->get_shape(); | ||||
| 
 | ||||
| 			ray->set_length(Math::abs(p_point.y)); | ||||
| 
 | ||||
| 			canvas_item_editor->update_viewport(); | ||||
| 
 | ||||
| 		} break; | ||||
| 
 | ||||
| 		case RECTANGLE_SHAPE: { | ||||
|  | @ -194,8 +184,6 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { | |||
| 					pos += (size - (Point2)original) * 0.5 * RECT_HANDLES[idx] * 0.5; | ||||
| 					node->set_global_position(original_transform.xform(pos)); | ||||
| 				} | ||||
| 
 | ||||
| 				canvas_item_editor->update_viewport(); | ||||
| 			} | ||||
| 
 | ||||
| 		} break; | ||||
|  | @ -209,13 +197,9 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { | |||
| 				} else if (idx == 1) { | ||||
| 					seg->set_b(p_point); | ||||
| 				} | ||||
| 
 | ||||
| 				canvas_item_editor->update_viewport(); | ||||
| 			} | ||||
| 
 | ||||
| 		} break; | ||||
| 	} | ||||
| 	node->get_shape()->notify_property_list_changed(); | ||||
| } | ||||
| 
 | ||||
| void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { | ||||
|  | @ -233,10 +217,8 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { | |||
| 			} else if (idx == 1) { | ||||
| 				undo_redo->add_do_method(capsule.ptr(), "set_height", capsule->get_height()); | ||||
| 			} | ||||
| 			undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | ||||
| 			undo_redo->add_undo_method(capsule.ptr(), "set_radius", values[0]); | ||||
| 			undo_redo->add_undo_method(capsule.ptr(), "set_height", values[1]); | ||||
| 			undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | ||||
| 
 | ||||
| 		} break; | ||||
| 
 | ||||
|  | @ -244,9 +226,7 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { | |||
| 			Ref<CircleShape2D> circle = node->get_shape(); | ||||
| 
 | ||||
| 			undo_redo->add_do_method(circle.ptr(), "set_radius", circle->get_radius()); | ||||
| 			undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | ||||
| 			undo_redo->add_undo_method(circle.ptr(), "set_radius", p_org); | ||||
| 			undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | ||||
| 
 | ||||
| 		} break; | ||||
| 
 | ||||
|  | @ -263,14 +243,10 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { | |||
| 
 | ||||
| 			if (idx == 0) { | ||||
| 				undo_redo->add_do_method(world_boundary.ptr(), "set_distance", world_boundary->get_distance()); | ||||
| 				undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | ||||
| 				undo_redo->add_undo_method(world_boundary.ptr(), "set_distance", p_org); | ||||
| 				undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | ||||
| 			} else { | ||||
| 				undo_redo->add_do_method(world_boundary.ptr(), "set_normal", world_boundary->get_normal()); | ||||
| 				undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | ||||
| 				undo_redo->add_undo_method(world_boundary.ptr(), "set_normal", p_org); | ||||
| 				undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | ||||
| 			} | ||||
| 
 | ||||
| 		} break; | ||||
|  | @ -279,9 +255,7 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { | |||
| 			Ref<SeparationRayShape2D> ray = node->get_shape(); | ||||
| 
 | ||||
| 			undo_redo->add_do_method(ray.ptr(), "set_length", ray->get_length()); | ||||
| 			undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | ||||
| 			undo_redo->add_undo_method(ray.ptr(), "set_length", p_org); | ||||
| 			undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | ||||
| 
 | ||||
| 		} break; | ||||
| 
 | ||||
|  | @ -290,10 +264,8 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { | |||
| 
 | ||||
| 			undo_redo->add_do_method(rect.ptr(), "set_size", rect->get_size()); | ||||
| 			undo_redo->add_do_method(node, "set_global_transform", node->get_global_transform()); | ||||
| 			undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | ||||
| 			undo_redo->add_undo_method(rect.ptr(), "set_size", p_org); | ||||
| 			undo_redo->add_undo_method(node, "set_global_transform", original_transform); | ||||
| 			undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | ||||
| 
 | ||||
| 		} break; | ||||
| 
 | ||||
|  | @ -301,14 +273,10 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { | |||
| 			Ref<SegmentShape2D> seg = node->get_shape(); | ||||
| 			if (idx == 0) { | ||||
| 				undo_redo->add_do_method(seg.ptr(), "set_a", seg->get_a()); | ||||
| 				undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | ||||
| 				undo_redo->add_undo_method(seg.ptr(), "set_a", p_org); | ||||
| 				undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | ||||
| 			} else if (idx == 1) { | ||||
| 				undo_redo->add_do_method(seg.ptr(), "set_b", seg->get_b()); | ||||
| 				undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | ||||
| 				undo_redo->add_undo_method(seg.ptr(), "set_b", p_org); | ||||
| 				undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | ||||
| 			} | ||||
| 
 | ||||
| 		} break; | ||||
|  | @ -322,10 +290,6 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_e | |||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!node->get_shape().is_valid()) { | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!node->is_visible_in_tree()) { | ||||
| 		return false; | ||||
| 	} | ||||
|  | @ -410,38 +374,44 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_e | |||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| void CollisionShape2DEditor::_get_current_shape_type() { | ||||
| void CollisionShape2DEditor::_shape_changed() { | ||||
| 	canvas_item_editor->update_viewport(); | ||||
| 
 | ||||
| 	if (current_shape.is_valid()) { | ||||
| 		current_shape->disconnect(SceneStringNames::get_singleton()->changed, callable_mp(canvas_item_editor, &CanvasItemEditor::update_viewport)); | ||||
| 		current_shape = Ref<Shape2D>(); | ||||
| 		shape_type = -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!node) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	Ref<Shape2D> s = node->get_shape(); | ||||
| 	current_shape = node->get_shape(); | ||||
| 
 | ||||
| 	if (!s.is_valid()) { | ||||
| 	if (current_shape.is_valid()) { | ||||
| 		current_shape->connect(SceneStringNames::get_singleton()->changed, callable_mp(canvas_item_editor, &CanvasItemEditor::update_viewport)); | ||||
| 	} else { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (Object::cast_to<CapsuleShape2D>(*s)) { | ||||
| 	if (Object::cast_to<CapsuleShape2D>(*current_shape)) { | ||||
| 		shape_type = CAPSULE_SHAPE; | ||||
| 	} else if (Object::cast_to<CircleShape2D>(*s)) { | ||||
| 	} else if (Object::cast_to<CircleShape2D>(*current_shape)) { | ||||
| 		shape_type = CIRCLE_SHAPE; | ||||
| 	} else if (Object::cast_to<ConcavePolygonShape2D>(*s)) { | ||||
| 	} else if (Object::cast_to<ConcavePolygonShape2D>(*current_shape)) { | ||||
| 		shape_type = CONCAVE_POLYGON_SHAPE; | ||||
| 	} else if (Object::cast_to<ConvexPolygonShape2D>(*s)) { | ||||
| 	} else if (Object::cast_to<ConvexPolygonShape2D>(*current_shape)) { | ||||
| 		shape_type = CONVEX_POLYGON_SHAPE; | ||||
| 	} else if (Object::cast_to<WorldBoundaryShape2D>(*s)) { | ||||
| 	} else if (Object::cast_to<WorldBoundaryShape2D>(*current_shape)) { | ||||
| 		shape_type = WORLD_BOUNDARY_SHAPE; | ||||
| 	} else if (Object::cast_to<SeparationRayShape2D>(*s)) { | ||||
| 	} else if (Object::cast_to<SeparationRayShape2D>(*current_shape)) { | ||||
| 		shape_type = SEPARATION_RAY_SHAPE; | ||||
| 	} else if (Object::cast_to<RectangleShape2D>(*s)) { | ||||
| 	} else if (Object::cast_to<RectangleShape2D>(*current_shape)) { | ||||
| 		shape_type = RECTANGLE_SHAPE; | ||||
| 	} else if (Object::cast_to<SegmentShape2D>(*s)) { | ||||
| 	} else if (Object::cast_to<SegmentShape2D>(*current_shape)) { | ||||
| 		shape_type = SEGMENT_SHAPE; | ||||
| 	} else { | ||||
| 		shape_type = -1; | ||||
| 	} | ||||
| 
 | ||||
| 	canvas_item_editor->update_viewport(); | ||||
| } | ||||
| 
 | ||||
| void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { | ||||
|  | @ -449,16 +419,10 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!node->get_shape().is_valid()) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!node->is_visible_in_tree()) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	_get_current_shape_type(); | ||||
| 
 | ||||
| 	if (shape_type == -1) { | ||||
| 		return; | ||||
| 	} | ||||
|  | @ -559,6 +523,12 @@ void CollisionShape2DEditor::_notification(int p_what) { | |||
| 		case NOTIFICATION_EXIT_TREE: { | ||||
| 			get_tree()->disconnect("node_removed", callable_mp(this, &CollisionShape2DEditor::_node_removed)); | ||||
| 		} break; | ||||
| 
 | ||||
| 		case NOTIFICATION_PROCESS: { | ||||
| 			if (node && node->get_shape() != current_shape) { | ||||
| 				_shape_changed(); | ||||
| 			} | ||||
| 		} break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -569,26 +539,17 @@ void CollisionShape2DEditor::edit(Node *p_node) { | |||
| 
 | ||||
| 	if (p_node) { | ||||
| 		node = Object::cast_to<CollisionShape2D>(p_node); | ||||
| 
 | ||||
| 		_get_current_shape_type(); | ||||
| 
 | ||||
| 		set_process(true); | ||||
| 	} else { | ||||
| 		if (pressed) { | ||||
| 			set_handle(edit_handle, original_point); | ||||
| 			pressed = false; | ||||
| 		} | ||||
| 
 | ||||
| 		edit_handle = -1; | ||||
| 		shape_type = -1; | ||||
| 
 | ||||
| 		node = nullptr; | ||||
| 		set_process(false); | ||||
| 	} | ||||
| 
 | ||||
| 	canvas_item_editor->update_viewport(); | ||||
| } | ||||
| 
 | ||||
| void CollisionShape2DEditor::_bind_methods() { | ||||
| 	ClassDB::bind_method("_get_current_shape_type", &CollisionShape2DEditor::_get_current_shape_type); | ||||
| 	_shape_changed(); | ||||
| } | ||||
| 
 | ||||
| CollisionShape2DEditor::CollisionShape2DEditor() { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 kobewi
						kobewi