Jump to content
  • Advertisement
Sign in to follow this  
johnl87

Procedurally drawing a tube.

This topic is 2952 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This has been bothering me for years and I still can't figure it out. How does one draw a tube along a curve? I'm talking about how in all these demoscene demos they draw tentacles and tubes spawning out from somewhere and growing along a curve. How is that procedurally generated?

One idea I had was to create points around the tangent of the curve, but how would you keep the angle constant, would you just have one up vector and just rotate off of that? So maybe tessellate it with like 10 points all around to get a round object...

Another solution was to make it purely in shaders where you just make the color lighter as you go closer to the center of the curve so it just looks like it's round.

Am I over-thinking this? Does anyone have any ideas?

Share this post


Link to post
Share on other sites
Advertisement
I can't comment directly on the shader-based method, but the best way to generate a 'tube' mesh (IMO) is to 'walk' along the medial spline using a 'parallel transport frame', generating successive 'rings' of vertices as you go.

I've discussed this in some detail in previous threads, so if you're interested in this method, I'd try searching the forums for 'parallel transform frame'. (You should be able to find some good references, I think.)

Share this post


Link to post
Share on other sites
I did something like this a couple of years ago for a university project.
I went for the "rotate one vector approach", I had my curve defined as line segments, just a list of vectors, each giving the movement to the next point of the curve, so point_i = sum vector_i from 0 to i

For each pair of vectors, I calculated the tangent (just the average of both vectors), and the cross product, and created the "ring" by rotating the cross product using the tangent as rotation direction.

Share this post


Link to post
Share on other sites
I recently made a tube for cubic Bezier curve in 3D. This may be useful:

http://neure.ath.cx/curve.html

specifically see CubicBezierCurveTube.cs. While this code is somewhat specific to cubic Bezier curves, it should be fairly easy to adapt it to any curve. Initially you may choose fixed parameter steps instead of adaptive subdivision, and you might just apply tube ring without any cusp detection. However, if there are any sharp turns (cusps), you will need some logic to detect problematic cases, and then how to deal with them.

Share this post


Link to post
Share on other sites
Just found the article in GPU gems 2. So basically you use the previous tangent vector as a reference. Then you get the new tangent, calculate the cross product and get the third vector. Then based on the angle between the two tangents, you rotate around the third. That's perfect for a round object since I don't care about it banking.

And even if you want twisting and stuff, like in a ribbon, you can have another curve controlling the twist.

I'll post my code once I get home and write it.

Share this post


Link to post
Share on other sites
Quote:
Just found the article in GPU gems 2. So basically you use the previous tangent vector as a reference. Then you get the new tangent, calculate the cross product and get the third vector. Then based on the angle between the two tangents, you rotate around the third. That's perfect for a round object since I don't care about it banking.
Right, that's the 'parallel transport frame' I mentioned.

Share this post


Link to post
Share on other sites
@jyk yup, thanks for pointing me in the right direction. For those with the same problem here are some links with more info.

@tksuoran yeah you're talking about a frenet frame approach where if the curve changes, i.e. 2nd derivative changes sign (I guess?) you don't know what side the tangent should be on. By reusing the previous tangent to find the cross product, you ensure that the frame stays consistent through sharp turns. If you're building geometry around the curve it's nice if the points stay consistently on the same side.

A paper that goes into a lot of mathematical detail and proofs:

"Parallel Transport Approach to Curve Framing" by Hanson and Ma

and the game programming gems 2 link(I know I said GPU gems above, disregard that):
http://books.google.com/books?id=M2QYbTVd0VgC&lpg=PA215&ots=K4t0eyqKVS&dq=parallel%20transport%20frame%20gems%202&pg=PA215#v=onepage&q&f=false

Share this post


Link to post
Share on other sites
Quote:
Original post by johnl87
@tksuoran yeah you're talking about a frenet frame approach where if the curve changes, i.e. 2nd derivative changes sign (I guess?) you don't know what side the tangent should be on. By reusing the previous tangent to find the cross product, you ensure that the frame stays consistent through sharp turns. If you're building geometry around the curve it's nice if the points stay consistently on the same side.

A paper that goes into a lot of mathematical detail and proofs:

"Parallel Transport Approach to Curve Framing" by Hanson and Ma

and the game programming gems 2 link(I know I said GPU gems above, disregard that):
http://books.google.com/books?id=M2QYbTVd0VgC&lpg=PA215&ots=K4t0eyqKVS&dq=parallel%20transport%20frame%20gems%202&pg=PA215#v=onepage&q&f=false


Thanks for the links! They are certainly good references, I shall have a more careful look at them soon. As a small clarification, I do not reuse tangent, I reuse normal. Perhaps we are talking about the same thing with different names?

My approach is to numerically compute approximation of the tangent (based on two nearby position values) and maintain 'current' normal of the curve. This indeed minimizes ring twists that happen, I think, at the inflection points, like you described it.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!