+3 votes

I'm trying to create my own 2D curve editor, and I'm stuck in the next step (see image):

I Know the position of green point (i get it with function curve.getclosestpoint(mousepos) from the Curve2D) and I need to know between which points it is (in this case is beetween point 1 and point 2) to add at the current Curve2D at this position (i this case, i need add the green point at index = 1)

Can you help me? Thank you

Curve2D Generator

in Engine by (184 points)

A couple of days ago I asked this question:

https://godotengine.org/qa/72842/convert-a-vector2-position-to-an-array-index-in-curve2d

Is it the same thing that you mean?

yes is the same. I had not seen your question.

I want get the index in which i need put the closest point return by the curve2D function (curve.getclosestpoint(to_point))

I was about to propose as a feature in github a function that returns the id in the array. But for doubts and ignorance I did not. Now that we are 2 with the same problem it would be worth proposing the feature if there is no other solution for this.

I have solved the problem myself, I put the solution here in case someone else was looking for it (Although I don't know if this will be the best way):

curve = a valid Curve2D

  1. Get closest point in curve2D
    var closest = curve.get_closest_point(at_position)
  2. get offset for the closest point
    var offset = curve.get_closest_offset(closest)
  3. call function below to get right index
    var index = get_curve_point_index_from_offset(offset)
func get_curve_point_index_from_offset(curve, offset):
  var curve_point_length = curve.get_point_count()
  if curve_point_length < 2: return curve_point_length
  for i in range(1, curve.get_point_count()):
      var current_point_offset = curve.get_closest_offset(curve.get_point_position(i))
      if current_point_offset > offset: return i
  return curve_point_length

Thanks newold, sometimes it just takes a little motivation ...

1 Answer

+1 vote

Your code works, but in certain situations the mouse did not detect me at the point. Or I didn't know how to implement it correctly. But it helped me to understand how the functions of Curve2D work a bit. So put this together, much longer but safe. There are details to be polished but nothing that an if cannot solve :-p, It is necessary to implement the control nodes (in and out). I leave it as an answer in case it serves someone.

extends Node2D
onready var curve = $Path2D.curve
var drag = false
var index = -1
enum Tools { SELECT, MOVE , DELETE, CREATE }
onready var current_tool = Tools.SELECT



func _input(event):
    if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.is_pressed():
        drag = true
        if current_tool == Tools.SELECT:
            for p in curve.get_point_count():
                if curve.get_point_position(p).distance_to(get_local_mouse_position()) < 10:
                    index = p
                    current_tool = Tools.MOVE   
                update()    


    if event is InputEventMouseMotion and drag == true:
        if current_tool == Tools.MOVE and index > -1:
            curve.set_point_position(index, curve.get_point_position(index) + event.relative)
            update()

    if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and !event.is_pressed():
        drag=false
        #index = null
        current_tool=Tools.SELECT
        update()

    if event is InputEventMouseButton and event.button_index == BUTTON_RIGHT and event.is_pressed():
        current_tool=Tools.CREATE
        curve.add_point(get_global_mouse_position()) 
        update()        


func _draw():
    if curve.get_point_count() > 0:
        draw_polyline(curve.get_baked_points(), Color.red, 2)
    for i in curve.get_point_count():
        var pos=curve.get_point_position(i) 
        draw_circle(pos, 5, Color.blue)
    if (current_tool == Tools.SELECT or current_tool == Tools.MOVE) and (index > -1 and index < curve.get_point_count()):       
        draw_circle(curve.get_point_position(index), 7 , Color.aliceblue)       
    print(index)
by (2,100 points)

It worked! You are my saviour!

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.