@@ -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,154 @@ 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+ rs->mesh_clear (debug_mesh_rid);
496+
497+ if (!debug_handle_lines.is_empty ()) {
498+ Array handles_array;
499+ handles_array.resize (Mesh::ARRAY_MAX);
500+
501+ handles_array[Mesh::ARRAY_VERTEX] = Vector<Vector2>(debug_handle_lines);
502+
503+ rs->mesh_add_surface_from_arrays (debug_mesh_rid, RS::PRIMITIVE_LINES, handles_array, Array (), Dictionary (), RS::ARRAY_FLAG_USE_2D_VERTICES);
504+ rs->canvas_item_add_mesh (vpc->get_canvas_item (), debug_mesh_rid, Transform2D (), Color (0.5 , 0.5 , 0.5 , 1.0 ));
505+ }
506+
507+ // Add texture rects multimeshes for handle vertices.
508+
509+ uint32_t handle_curve_count = debug_handle_curve_transforms.size ();
510+ uint32_t handle_sharp_count = debug_handle_sharp_transforms.size ();
511+ uint32_t handle_smooth_count = debug_handle_smooth_transforms.size ();
512+
513+ // Add texture rects for curve handle vertices.
514+
515+ rs->multimesh_set_visible_instances (debug_handle_curve_multimesh_rid, 0 );
516+ if (handle_curve_count > 0 ) {
517+ if (rs->multimesh_get_instance_count (debug_handle_curve_multimesh_rid) != int (handle_curve_count)) {
518+ rs->multimesh_allocate_data (debug_handle_curve_multimesh_rid, handle_curve_count, RS::MULTIMESH_TRANSFORM_2D);
519+ }
520+
521+ Vector<float > multimesh_buffer;
522+ multimesh_buffer.resize (8 * handle_curve_count);
523+ float *multimesh_buffer_ptrw = multimesh_buffer.ptrw ();
524+
525+ const Transform2D *debug_handle_transforms_ptr = debug_handle_curve_transforms.ptr ();
526+
527+ for (uint32_t i = 0 ; i < handle_curve_count; i++) {
528+ const Transform2D &handle_transform = debug_handle_transforms_ptr[i];
529+
530+ multimesh_buffer_ptrw[i * 8 + 0 ] = handle_transform[0 ][0 ];
531+ multimesh_buffer_ptrw[i * 8 + 1 ] = handle_transform[1 ][0 ];
532+ multimesh_buffer_ptrw[i * 8 + 2 ] = 0 ;
533+ multimesh_buffer_ptrw[i * 8 + 3 ] = handle_transform[2 ][0 ];
534+ multimesh_buffer_ptrw[i * 8 + 4 ] = handle_transform[0 ][1 ];
535+ multimesh_buffer_ptrw[i * 8 + 5 ] = handle_transform[1 ][1 ];
536+ multimesh_buffer_ptrw[i * 8 + 6 ] = 0 ;
537+ multimesh_buffer_ptrw[i * 8 + 7 ] = handle_transform[2 ][1 ];
538+ }
539+
540+ rs->multimesh_set_buffer (debug_handle_curve_multimesh_rid, multimesh_buffer);
541+ rs->multimesh_set_visible_instances (debug_handle_curve_multimesh_rid, handle_curve_count);
542+
543+ rs->canvas_item_add_multimesh (vpc->get_canvas_item (), debug_handle_curve_multimesh_rid, curve_handle->get_rid ());
544+ }
545+
546+ // Add texture rects for sharp handle vertices.
547+
548+ rs->multimesh_set_visible_instances (debug_handle_sharp_multimesh_rid, 0 );
549+ if (handle_sharp_count > 0 ) {
550+ if (rs->multimesh_get_instance_count (debug_handle_sharp_multimesh_rid) != int (handle_sharp_count)) {
551+ rs->multimesh_allocate_data (debug_handle_sharp_multimesh_rid, handle_sharp_count, RS::MULTIMESH_TRANSFORM_2D);
552+ }
553+
554+ Vector<float > multimesh_buffer;
555+ multimesh_buffer.resize (8 * handle_sharp_count);
556+ float *multimesh_buffer_ptrw = multimesh_buffer.ptrw ();
557+
558+ const Transform2D *debug_handle_transforms_ptr = debug_handle_sharp_transforms.ptr ();
559+
560+ for (uint32_t i = 0 ; i < handle_sharp_count; i++) {
561+ const Transform2D &handle_transform = debug_handle_transforms_ptr[i];
562+
563+ multimesh_buffer_ptrw[i * 8 + 0 ] = handle_transform[0 ][0 ];
564+ multimesh_buffer_ptrw[i * 8 + 1 ] = handle_transform[1 ][0 ];
565+ multimesh_buffer_ptrw[i * 8 + 2 ] = 0 ;
566+ multimesh_buffer_ptrw[i * 8 + 3 ] = handle_transform[2 ][0 ];
567+ multimesh_buffer_ptrw[i * 8 + 4 ] = handle_transform[0 ][1 ];
568+ multimesh_buffer_ptrw[i * 8 + 5 ] = handle_transform[1 ][1 ];
569+ multimesh_buffer_ptrw[i * 8 + 6 ] = 0 ;
570+ multimesh_buffer_ptrw[i * 8 + 7 ] = handle_transform[2 ][1 ];
571+ }
572+
573+ rs->multimesh_set_buffer (debug_handle_sharp_multimesh_rid, multimesh_buffer);
574+ rs->multimesh_set_visible_instances (debug_handle_sharp_multimesh_rid, handle_sharp_count);
575+
576+ rs->canvas_item_add_multimesh (vpc->get_canvas_item (), debug_handle_sharp_multimesh_rid, curve_handle->get_rid ());
577+ }
578+
579+ // Add texture rects for smooth handle vertices.
580+
581+ rs->multimesh_set_visible_instances (debug_handle_smooth_multimesh_rid, 0 );
582+ if (handle_smooth_count > 0 ) {
583+ if (rs->multimesh_get_instance_count (debug_handle_smooth_multimesh_rid) != int (handle_smooth_count)) {
584+ rs->multimesh_allocate_data (debug_handle_smooth_multimesh_rid, handle_smooth_count, RS::MULTIMESH_TRANSFORM_2D);
585+ }
586+
587+ Vector<float > multimesh_buffer;
588+ multimesh_buffer.resize (8 * handle_smooth_count);
589+ float *multimesh_buffer_ptrw = multimesh_buffer.ptrw ();
590+
591+ const Transform2D *debug_handle_transforms_ptr = debug_handle_smooth_transforms.ptr ();
592+
593+ for (uint32_t i = 0 ; i < handle_smooth_count; i++) {
594+ const Transform2D &handle_transform = debug_handle_transforms_ptr[i];
595+
596+ multimesh_buffer_ptrw[i * 8 + 0 ] = handle_transform[0 ][0 ];
597+ multimesh_buffer_ptrw[i * 8 + 1 ] = handle_transform[1 ][0 ];
598+ multimesh_buffer_ptrw[i * 8 + 2 ] = 0 ;
599+ multimesh_buffer_ptrw[i * 8 + 3 ] = handle_transform[2 ][0 ];
600+ multimesh_buffer_ptrw[i * 8 + 4 ] = handle_transform[0 ][1 ];
601+ multimesh_buffer_ptrw[i * 8 + 5 ] = handle_transform[1 ][1 ];
602+ multimesh_buffer_ptrw[i * 8 + 6 ] = 0 ;
603+ multimesh_buffer_ptrw[i * 8 + 7 ] = handle_transform[2 ][1 ];
604+ }
605+
606+ rs->multimesh_set_buffer (debug_handle_smooth_multimesh_rid, multimesh_buffer);
607+ rs->multimesh_set_visible_instances (debug_handle_smooth_multimesh_rid, handle_smooth_count);
608+
609+ rs->canvas_item_add_multimesh (vpc->get_canvas_item (), debug_handle_smooth_multimesh_rid, curve_handle->get_rid ());
610+ }
483611}
484612
485613void Path2DEditor::_node_visibility_changed () {
@@ -795,6 +923,66 @@ Path2DEditor::Path2DEditor() {
795923 create_curve_button->hide ();
796924 add_child (create_curve_button);
797925 create_curve_button->connect (SceneStringName (pressed), callable_mp (this , &Path2DEditor::_create_curve));
926+
927+ ERR_FAIL_NULL (RS::get_singleton ());
928+ RenderingServer *rs = RS::get_singleton ();
929+
930+ debug_mesh_rid = rs->mesh_create ();
931+
932+ {
933+ debug_handle_mesh_rid = rs->mesh_create ();
934+
935+ Vector<Vector2> vertex_array;
936+ vertex_array.resize (4 );
937+ Vector2 *vertex_array_ptrw = vertex_array.ptrw ();
938+ vertex_array_ptrw[0 ] = Vector2 (-1.0 , -1.0 );
939+ vertex_array_ptrw[1 ] = Vector2 (1.0 , -1.0 );
940+ vertex_array_ptrw[2 ] = Vector2 (1.0 , 1.0 );
941+ vertex_array_ptrw[3 ] = Vector2 (-1.0 , 1.0 );
942+
943+ Vector<Vector2> uv_array;
944+ uv_array.resize (4 );
945+ Vector2 *uv_array_ptrw = uv_array.ptrw ();
946+ uv_array_ptrw[0 ] = Vector2 (0.0 , 0.0 );
947+ uv_array_ptrw[1 ] = Vector2 (1.0 , 0.0 );
948+ uv_array_ptrw[2 ] = Vector2 (1.0 , 1.0 );
949+ uv_array_ptrw[3 ] = Vector2 (0.0 , 1.0 );
950+
951+ Vector<int > index_array;
952+ index_array.resize (6 );
953+ int *index_array_ptrw = index_array.ptrw ();
954+ index_array_ptrw[0 ] = 0 ;
955+ index_array_ptrw[1 ] = 1 ;
956+ index_array_ptrw[2 ] = 3 ;
957+ index_array_ptrw[3 ] = 1 ;
958+ index_array_ptrw[4 ] = 2 ;
959+ index_array_ptrw[5 ] = 3 ;
960+
961+ Array mesh_arrays;
962+ mesh_arrays.resize (RS::ARRAY_MAX);
963+ mesh_arrays[RS::ARRAY_VERTEX] = vertex_array;
964+ mesh_arrays[RS::ARRAY_TEX_UV] = uv_array;
965+ mesh_arrays[RS::ARRAY_INDEX] = index_array;
966+
967+ rs->mesh_add_surface_from_arrays (debug_handle_mesh_rid, RS::PRIMITIVE_TRIANGLES, mesh_arrays, Array (), Dictionary (), RS::ARRAY_FLAG_USE_2D_VERTICES);
968+
969+ debug_handle_curve_multimesh_rid = rs->multimesh_create ();
970+ debug_handle_sharp_multimesh_rid = rs->multimesh_create ();
971+ debug_handle_smooth_multimesh_rid = rs->multimesh_create ();
972+
973+ rs->multimesh_set_mesh (debug_handle_curve_multimesh_rid, debug_handle_mesh_rid);
974+ rs->multimesh_set_mesh (debug_handle_sharp_multimesh_rid, debug_handle_mesh_rid);
975+ rs->multimesh_set_mesh (debug_handle_smooth_multimesh_rid, debug_handle_mesh_rid);
976+ }
977+ }
978+
979+ Path2DEditor::~Path2DEditor () {
980+ ERR_FAIL_NULL (RS::get_singleton ());
981+ RS::get_singleton ()->free (debug_mesh_rid);
982+ RS::get_singleton ()->free (debug_handle_curve_multimesh_rid);
983+ RS::get_singleton ()->free (debug_handle_sharp_multimesh_rid);
984+ RS::get_singleton ()->free (debug_handle_smooth_multimesh_rid);
985+ RS::get_singleton ()->free (debug_handle_mesh_rid);
798986}
799987
800988void Path2DEditorPlugin::edit (Object *p_object) {
0 commit comments