@@ -443,6 +443,14 @@ void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
443443 int len = curve->get_point_count ();
444444 Control *vpc = canvas_item_editor->get_viewport_control ();
445445
446+ debug_handle_lines.clear ();
447+ debug_handle_curve_transforms.clear ();
448+ debug_handle_sharp_transforms.clear ();
449+ debug_handle_smooth_transforms.clear ();
450+
451+ Transform2D handle_curve_transform = Transform2D ().scaled (curve_handle_size * 0.5 );
452+ Transform2D handle_point_transform = Transform2D ().scaled (handle_size * 0.5 );
453+
446454 for (int i = 0 ; i < len; i++) {
447455 Vector2 point = xform.xform (curve->get_point_position (i));
448456 // Determines the point icon to be used
@@ -452,34 +460,152 @@ void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
452460 Vector2 point_out = xform.xform (curve->get_point_position (i) + curve->get_point_out (i));
453461 if (point != point_out) {
454462 smooth = true ;
455- // Draw the line with a dark and light color to be visible on all backgrounds
456- vpc-> draw_line (point, point_out, Color ( 0 , 0 , 0 , 0.5 ), Math::round (EDSCALE) );
457- vpc-> draw_line (point, point_out, Color ( 1 , 1 , 1 , 0.5 ), Math::round (EDSCALE) );
458- vpc-> draw_texture_rect (curve_handle, Rect2 (point_out - curve_handle_size * 0.5 , curve_handle_size), false , Color ( 1 , 1 , 1 , 0.75 ) );
463+ debug_handle_lines. push_back (point);
464+ debug_handle_lines. push_back (point_out );
465+ handle_curve_transform. set_origin (point_out );
466+ debug_handle_curve_transforms. push_back (handle_curve_transform );
459467 }
460468 }
461469
462470 if (i > 0 ) {
463471 Vector2 point_in = xform.xform (curve->get_point_position (i) + curve->get_point_in (i));
464472 if (point != point_in) {
465473 smooth = true ;
466- // Draw the line with a dark and light color to be visible on all backgrounds
467- vpc-> draw_line (point, point_in, Color ( 0 , 0 , 0 , 0.5 ), Math::round (EDSCALE) );
468- vpc-> draw_line (point, point_in, Color ( 1 , 1 , 1 , 0.5 ), Math::round (EDSCALE) );
469- vpc-> draw_texture_rect (curve_handle, Rect2 (point_in - curve_handle_size * 0.5 , curve_handle_size), false , Color ( 1 , 1 , 1 , 0.75 ) );
474+ debug_handle_lines. push_back (point);
475+ debug_handle_lines. push_back (point_in );
476+ handle_curve_transform. set_origin (point_in );
477+ debug_handle_curve_transforms. push_back (handle_curve_transform );
470478 }
471479 }
472480
473- vpc->draw_texture_rect (
474- smooth ? path_smooth_handle : path_sharp_handle,
475- Rect2 (point - handle_size * 0.5 , handle_size),
476- false );
481+ handle_point_transform.set_origin (point);
482+ if (smooth) {
483+ debug_handle_smooth_transforms.push_back (handle_point_transform);
484+ } else {
485+ debug_handle_sharp_transforms.push_back (handle_point_transform);
486+ }
477487 }
478488
479489 if (on_edge) {
480490 Ref<Texture2D> add_handle = get_editor_theme_icon (SNAME (" EditorHandleAdd" ));
481491 p_overlay->draw_texture (add_handle, edge_point - add_handle->get_size () * 0.5 );
482492 }
493+
494+ RenderingServer *rs = RS::get_singleton ();
495+
496+ Array handles_array;
497+ handles_array.resize (Mesh::ARRAY_MAX);
498+
499+ handles_array[Mesh::ARRAY_VERTEX] = Vector<Vector2>(debug_handle_lines);
500+
501+ rs->mesh_clear (debug_mesh_rid);
502+ rs->mesh_add_surface_from_arrays (debug_mesh_rid, RS::PRIMITIVE_LINES, handles_array, Array (), Dictionary (), RS::ARRAY_FLAG_USE_2D_VERTICES);
503+ rs->canvas_item_add_mesh (vpc->get_canvas_item (), debug_mesh_rid, Transform2D (), Color (0.5 , 0.5 , 0.5 , 1.0 ));
504+
505+ // Add texture rects multimeshes for handle vertices.
506+
507+ uint32_t handle_curve_count = debug_handle_curve_transforms.size ();
508+ uint32_t handle_sharp_count = debug_handle_sharp_transforms.size ();
509+ uint32_t handle_smooth_count = debug_handle_smooth_transforms.size ();
510+
511+ // Add texture rects for curve handle vertices.
512+
513+ rs->multimesh_set_visible_instances (debug_handle_curve_multimesh_rid, 0 );
514+ if (handle_curve_count > 0 ) {
515+ if (rs->multimesh_get_instance_count (debug_handle_curve_multimesh_rid) != int (handle_curve_count)) {
516+ rs->multimesh_allocate_data (debug_handle_curve_multimesh_rid, handle_curve_count, RS::MULTIMESH_TRANSFORM_2D);
517+ }
518+
519+ Vector<float > multimesh_buffer;
520+ multimesh_buffer.resize (8 * handle_curve_count);
521+ float *multimesh_buffer_ptrw = multimesh_buffer.ptrw ();
522+
523+ const Transform2D *debug_handle_transforms_ptr = debug_handle_curve_transforms.ptr ();
524+
525+ for (uint32_t i = 0 ; i < handle_curve_count; i++) {
526+ const Transform2D &handle_transform = debug_handle_transforms_ptr[i];
527+
528+ multimesh_buffer_ptrw[i * 8 + 0 ] = handle_transform[0 ][0 ];
529+ multimesh_buffer_ptrw[i * 8 + 1 ] = handle_transform[1 ][0 ];
530+ multimesh_buffer_ptrw[i * 8 + 2 ] = 0 ;
531+ multimesh_buffer_ptrw[i * 8 + 3 ] = handle_transform[2 ][0 ];
532+ multimesh_buffer_ptrw[i * 8 + 4 ] = handle_transform[0 ][1 ];
533+ multimesh_buffer_ptrw[i * 8 + 5 ] = handle_transform[1 ][1 ];
534+ multimesh_buffer_ptrw[i * 8 + 6 ] = 0 ;
535+ multimesh_buffer_ptrw[i * 8 + 7 ] = handle_transform[2 ][1 ];
536+ }
537+
538+ rs->multimesh_set_buffer (debug_handle_curve_multimesh_rid, multimesh_buffer);
539+ rs->multimesh_set_visible_instances (debug_handle_curve_multimesh_rid, handle_curve_count);
540+
541+ rs->canvas_item_add_multimesh (vpc->get_canvas_item (), debug_handle_curve_multimesh_rid, curve_handle->get_rid ());
542+ }
543+
544+ // Add texture rects for sharp handle vertices.
545+
546+ rs->multimesh_set_visible_instances (debug_handle_sharp_multimesh_rid, 0 );
547+ if (handle_sharp_count > 0 ) {
548+ if (rs->multimesh_get_instance_count (debug_handle_sharp_multimesh_rid) != int (handle_sharp_count)) {
549+ rs->multimesh_allocate_data (debug_handle_sharp_multimesh_rid, handle_sharp_count, RS::MULTIMESH_TRANSFORM_2D);
550+ }
551+
552+ Vector<float > multimesh_buffer;
553+ multimesh_buffer.resize (8 * handle_sharp_count);
554+ float *multimesh_buffer_ptrw = multimesh_buffer.ptrw ();
555+
556+ const Transform2D *debug_handle_transforms_ptr = debug_handle_sharp_transforms.ptr ();
557+
558+ for (uint32_t i = 0 ; i < handle_sharp_count; i++) {
559+ const Transform2D &handle_transform = debug_handle_transforms_ptr[i];
560+
561+ multimesh_buffer_ptrw[i * 8 + 0 ] = handle_transform[0 ][0 ];
562+ multimesh_buffer_ptrw[i * 8 + 1 ] = handle_transform[1 ][0 ];
563+ multimesh_buffer_ptrw[i * 8 + 2 ] = 0 ;
564+ multimesh_buffer_ptrw[i * 8 + 3 ] = handle_transform[2 ][0 ];
565+ multimesh_buffer_ptrw[i * 8 + 4 ] = handle_transform[0 ][1 ];
566+ multimesh_buffer_ptrw[i * 8 + 5 ] = handle_transform[1 ][1 ];
567+ multimesh_buffer_ptrw[i * 8 + 6 ] = 0 ;
568+ multimesh_buffer_ptrw[i * 8 + 7 ] = handle_transform[2 ][1 ];
569+ }
570+
571+ rs->multimesh_set_buffer (debug_handle_sharp_multimesh_rid, multimesh_buffer);
572+ rs->multimesh_set_visible_instances (debug_handle_sharp_multimesh_rid, handle_sharp_count);
573+
574+ rs->canvas_item_add_multimesh (vpc->get_canvas_item (), debug_handle_sharp_multimesh_rid, curve_handle->get_rid ());
575+ }
576+
577+ // Add texture rects for smooth handle vertices.
578+
579+ rs->multimesh_set_visible_instances (debug_handle_smooth_multimesh_rid, 0 );
580+ if (handle_smooth_count > 0 ) {
581+ if (rs->multimesh_get_instance_count (debug_handle_smooth_multimesh_rid) != int (handle_smooth_count)) {
582+ rs->multimesh_allocate_data (debug_handle_smooth_multimesh_rid, handle_smooth_count, RS::MULTIMESH_TRANSFORM_2D);
583+ }
584+
585+ Vector<float > multimesh_buffer;
586+ multimesh_buffer.resize (8 * handle_smooth_count);
587+ float *multimesh_buffer_ptrw = multimesh_buffer.ptrw ();
588+
589+ const Transform2D *debug_handle_transforms_ptr = debug_handle_smooth_transforms.ptr ();
590+
591+ for (uint32_t i = 0 ; i < handle_smooth_count; i++) {
592+ const Transform2D &handle_transform = debug_handle_transforms_ptr[i];
593+
594+ multimesh_buffer_ptrw[i * 8 + 0 ] = handle_transform[0 ][0 ];
595+ multimesh_buffer_ptrw[i * 8 + 1 ] = handle_transform[1 ][0 ];
596+ multimesh_buffer_ptrw[i * 8 + 2 ] = 0 ;
597+ multimesh_buffer_ptrw[i * 8 + 3 ] = handle_transform[2 ][0 ];
598+ multimesh_buffer_ptrw[i * 8 + 4 ] = handle_transform[0 ][1 ];
599+ multimesh_buffer_ptrw[i * 8 + 5 ] = handle_transform[1 ][1 ];
600+ multimesh_buffer_ptrw[i * 8 + 6 ] = 0 ;
601+ multimesh_buffer_ptrw[i * 8 + 7 ] = handle_transform[2 ][1 ];
602+ }
603+
604+ rs->multimesh_set_buffer (debug_handle_smooth_multimesh_rid, multimesh_buffer);
605+ rs->multimesh_set_visible_instances (debug_handle_smooth_multimesh_rid, handle_smooth_count);
606+
607+ rs->canvas_item_add_multimesh (vpc->get_canvas_item (), debug_handle_smooth_multimesh_rid, curve_handle->get_rid ());
608+ }
483609}
484610
485611void Path2DEditor::_node_visibility_changed () {
@@ -795,6 +921,66 @@ Path2DEditor::Path2DEditor() {
795921 create_curve_button->hide ();
796922 add_child (create_curve_button);
797923 create_curve_button->connect (SceneStringName (pressed), callable_mp (this , &Path2DEditor::_create_curve));
924+
925+ ERR_FAIL_NULL (RS::get_singleton ());
926+ RenderingServer *rs = RS::get_singleton ();
927+
928+ debug_mesh_rid = rs->mesh_create ();
929+
930+ {
931+ debug_handle_mesh_rid = rs->mesh_create ();
932+
933+ Vector<Vector2> vertex_array;
934+ vertex_array.resize (4 );
935+ Vector2 *vertex_array_ptrw = vertex_array.ptrw ();
936+ vertex_array_ptrw[0 ] = Vector2 (-1.0 , -1.0 );
937+ vertex_array_ptrw[1 ] = Vector2 (1.0 , -1.0 );
938+ vertex_array_ptrw[2 ] = Vector2 (1.0 , 1.0 );
939+ vertex_array_ptrw[3 ] = Vector2 (-1.0 , 1.0 );
940+
941+ Vector<Vector2> uv_array;
942+ uv_array.resize (4 );
943+ Vector2 *uv_array_ptrw = uv_array.ptrw ();
944+ uv_array_ptrw[0 ] = Vector2 (0.0 , 0.0 );
945+ uv_array_ptrw[1 ] = Vector2 (1.0 , 0.0 );
946+ uv_array_ptrw[2 ] = Vector2 (1.0 , 1.0 );
947+ uv_array_ptrw[3 ] = Vector2 (0.0 , 1.0 );
948+
949+ Vector<int > index_array;
950+ index_array.resize (6 );
951+ int *index_array_ptrw = index_array.ptrw ();
952+ index_array_ptrw[0 ] = 0 ;
953+ index_array_ptrw[1 ] = 1 ;
954+ index_array_ptrw[2 ] = 3 ;
955+ index_array_ptrw[3 ] = 1 ;
956+ index_array_ptrw[4 ] = 2 ;
957+ index_array_ptrw[5 ] = 3 ;
958+
959+ Array mesh_arrays;
960+ mesh_arrays.resize (RS::ARRAY_MAX);
961+ mesh_arrays[RS::ARRAY_VERTEX] = vertex_array;
962+ mesh_arrays[RS::ARRAY_TEX_UV] = uv_array;
963+ mesh_arrays[RS::ARRAY_INDEX] = index_array;
964+
965+ rs->mesh_add_surface_from_arrays (debug_handle_mesh_rid, RS::PRIMITIVE_TRIANGLES, mesh_arrays, Array (), Dictionary (), RS::ARRAY_FLAG_USE_2D_VERTICES);
966+
967+ debug_handle_curve_multimesh_rid = rs->multimesh_create ();
968+ debug_handle_sharp_multimesh_rid = rs->multimesh_create ();
969+ debug_handle_smooth_multimesh_rid = rs->multimesh_create ();
970+
971+ rs->multimesh_set_mesh (debug_handle_curve_multimesh_rid, debug_handle_mesh_rid);
972+ rs->multimesh_set_mesh (debug_handle_sharp_multimesh_rid, debug_handle_mesh_rid);
973+ rs->multimesh_set_mesh (debug_handle_smooth_multimesh_rid, debug_handle_mesh_rid);
974+ }
975+ }
976+
977+ Path2DEditor::~Path2DEditor () {
978+ ERR_FAIL_NULL (RS::get_singleton ());
979+ RS::get_singleton ()->free (debug_mesh_rid);
980+ RS::get_singleton ()->free (debug_handle_curve_multimesh_rid);
981+ RS::get_singleton ()->free (debug_handle_sharp_multimesh_rid);
982+ RS::get_singleton ()->free (debug_handle_smooth_multimesh_rid);
983+ RS::get_singleton ()->free (debug_handle_mesh_rid);
798984}
799985
800986void Path2DEditorPlugin::edit (Object *p_object) {
0 commit comments