how to draw curve line as mesh (in 2d, mesh generation)

Discussion in 'Rendering Technology and APIs' started by haochao, Feb 10, 2015.

  1. haochao

    Joined:
    Feb 10, 2015
    Messages:
    2
    Likes Received:
    0
    i just wanna make an effect of rope, and dragging it to wherever i want, and it also can bend without any constraint. before i decided to implement it, i've found that my naive algorithm isn't feasible , my rough steps as the following:

    1. using bezier or something else to generate curve point sets(red point as the following figure shows).
    2. to generate 2d curve mesh or quad based on previous and last point from the sets.
    For simplicity, i just straight line(blue line) instead of quad to show you this circumstance.

    in the above step 2, which result in triangles overlapping each other at round angle(as the figure shows).especially,the more curve point at the round angle,the more triangles overlap each other.so i'm looking for an elegant way to get rid of it. if you know please let me know,thank you. sorry for my bad english.


    figure 1: it's just a sketch,not program screenshot.

    [​IMG]
     

    Attached Files:

  2. iroboto

    iroboto Daft Funk
    Legend Regular Subscriber

    Joined:
    Mar 6, 2014
    Messages:
    8,706
    Likes Received:
    7,145
    Oh I had to do this for this game:
    You can see the curves coming out from the PC.

    Is that what you want to generate?

    lol the fps in this game was so awful. in retrospect, I wish a new a bit more about culling and draw calls this game really could have used it [more culling, less draw calls]
     
  3. haochao

    Joined:
    Feb 10, 2015
    Messages:
    2
    Likes Received:
    0

    yes. i just wanna implement this effect.
     
  4. iroboto

    iroboto Daft Funk
    Legend Regular Subscriber

    Joined:
    Mar 6, 2014
    Messages:
    8,706
    Likes Received:
    7,145
    You just need to join the last set of points as being the next set of points. If you are working with quads this should create joined points
    It's up to you how you'd like to generate the thickness, I wrote this in Lua, but I think it should be good enough pseudo code. so in this instance I'm writing to an array to be drawn, if you don't do it this method you could leverage a triangle strip, that would work as well.

    if vX(pv) ~= 0 and vY(pv) ~= 0 then
    vNormalize(pv); //normalize the perpendicular vector for thickness of the quad against the particular point on the bezier curve, the vector on the bezier curve we want to perpendicular is V1 - V0, so it shouldn't cross through the center point of the line, smoothness is dictated by how many points you want in a line.
    end

    vMultiply(mpv, pv, thickness_matrix*curve_width) // multiply the perpendicular vector by the thickness that you desire, I did it by percent which causes it to start thin and grow out to a thicker line.

    vAdd(result_0, v0,mpv) //now I take the point on the bezier curve add the thickness to V0
    vSubtract(result_1, v0,mpv) // subtract the thickness from V0, this is now 2 points of the quad
    vSubtract(result_2, v1,mpv) //subtract the thickness from V1, third point of quad
    vAdd(result_3, v1,mpv) //add thickness to V1 last point of the quad

    if i == 1 then
    writeFloat(bezier_array,vX(result_0)) //if this is the very first quad of the bezier curve that just write the quad directly into the array
    writeFloat(bezier_array,vY(result_0))
    writeFloat(bezier_array,vX(result_1))
    writeFloat(bezier_array,vY(result_1))
    else
    writeFloat(bezier_array, vX(curve_pt3rd)) //otherwise start with writing Point 4 of the last quad this is the X value
    writeFloat(bezier_array, vY(curve_pt3rd)) // Y value of Pt 4 of last quad
    writeFloat(bezier_array, vX(curve_pt2nd)) // X of Pt 3 of last quad
    writeFloat(bezier_array, vY(curve_pt2nd)) // Y of Pt 3 of last quad
    end;
    writeFloat(bezier_array,vX(result_2)) // now write a new point 3
    writeFloat(bezier_array,vY(result_2))
    writeFloat(bezier_array,vX(result_3)) // now write a new point 4
    writeFloat(bezier_array,vY(result_3))

    vSetX(curve_pt2nd, vX(result_2)) //set point 4 of new quad to the new point 1
    vSetY(curve_pt2nd, vY(result_2))
    vSetX(curve_pt3rd, vX(result_3)) //set point 3 of new quad to the new point 2
    vSetY(curve_pt3rd, vY(result_3))

    Loop until done.

    This would be way more efficient with a triangle strip, since each loop you are only adding 1 more point and then drawing a triangle... I guess generating points using a CPU isn't super efficient lol

    Anyone know if there is a better/easier/more efficient way of doing this?
     
    #4 iroboto, Feb 11, 2015
    Last edited: Feb 11, 2015
Loading...

Share This Page

  • About Us

    Beyond3D has been around for over a decade and prides itself on being the best place on the web for in-depth, technically-driven discussion and analysis of 3D graphics hardware. If you love pixels and transistors, you've come to the right place!

    Beyond3D is proudly published by GPU Tools Ltd.
Loading...