6
\$\begingroup\$

Let's say, for example, that I have a working spline. I want to use this spline to create a mesh, but I'm not quite sure how to go about it. For example, I want to create a road along this spline. I can interpolate through the curve and generate my segments and use that. If I were just making a single straight line I could take the normal of that vector and extrude the endpoints to get the vertices for a quad and do it that way, but how should I handle the curve part? I can't just use the endpoints of one quad as the start of another because they won't line up at different angles.

What would be the proper way to extrude a spline into a mesh? I'm tagging this as Unity since that's what I'm using, though the answer I assume will be engine-agnostic.

\$\endgroup\$
9
\$\begingroup\$

Your idea is correct, you just have to work more on it.

Here is an article I wrote last year: http://blog.meltinglogic.com/2013/12/how-to-generate-procedural-racetracks/ It uses exactly what you described, and as you can see, the result is very good.

Here is the code which explains how the mesh was generated from the spline:

for(float i = 0; i <= 1.0f;)  
{  
    Vector2 p = CatmullRom.calculatePoint(dataSet, i);  
    Vector2 deriv = CatmullRom.calculateDerivative(dataSet, i);  
    float len = deriv.Length();  
    i += step / len;  
    deriv.divide(len);  
    deriv.scale(thickness);  
    deriv.set(-deriv.y, deriv.x);  
    Vector2 v1 = new Vector2();  
    v1.set(p).add(deriv);  
    vertices.add(v1);  
    Vector2 v2 = new Vector2();  
    v2.set(p).sub(deriv);  
    vertices.add(v2);  

    if(i > 1.0f) i = 1.0f;  
}

The idea behind this algorithm is, traverse through the spline by segments of step size, for each point on the spline, calculate its derivative, normalize it to get the normal, rotate it by 90°, then add two points to the vertice list: splinePoint + normal and splinePoint - normal. You'll have a stripe of vertices following the spline, you can easily generate it's indices, If you have problems generating those indices, just throw a comment and I'll edit the answer.

Some further clarifications:

  • Derivative is the same as tangent, in case your engine words it differently;
  • Incrementing step / derivativeLength to the time parameter is the right thing to do. Since the size of the spline differ from point to point, you must use this to keep going at a constant speed;
  • With that being said, step parameter should be defined in World Units, not Spline Percentage. (That is, if you set step to 5 and your units are pixels, then each segment will be put 5 pixels apart, and not each 5% of the spline);
  • Yes, thickness is some constant that you should fiddle around to find a good value. If your world units are pixels, then your mesh will be 2 * thickness thick;
  • If your engine doesnt support derivatives, try porting these: LibGDX Catmull Rom or LibGDX Bezier
  • In case you want details on the implementation of catmull derivatives, it seems that OP have already did the awesome job of asking on Math.SE, so go read that!
\$\endgroup\$
  • 1
    \$\begingroup\$ This works, thank you. I've managed to get the points along the spline, so if you have an article about how you managed to create the proper mesh and texturing, that would be great too.. \$\endgroup\$ – ssb May 18 '14 at 8:00
  • \$\begingroup\$ It actually wasn't texturing. It's more than one mesh, and they're colored :p \$\endgroup\$ – Gustavo Maciel May 19 '14 at 9:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.