Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by SomeGuy22 · Mar 11, 2016 at 02:44 AM · meshgenerationsplinebezier

Generating a Flat Mesh from Spline/Bezier Curve?

I've been scratching my head over this problem for the past several days... I finally got something close to what I was hoping for.

Basically I'm attempting to create a new Mesh, the vertices will make a 2D road that follows a Bezier curve. I finally figured out that Meshes use Local Space, after doing the conversations I was able to get the curve to end in the right place. But now I'm stuck trying to figure out how to get both edges of the road to follow a curve. I basically need an extrude point along the sideways Vector of the current curve position.

This is my code for each iteration of a mesh part in the curve:

 for (var i2 = 0; i2 < curveResolution; i2++) {
             
             var newI2 : float = i2;
             var catT : float = newI2 / (curveResolution - 1);
                 // Get the point on our curve using the 4 points generated above
             var p : Vector3 = PointOnPath(catT, points[0], points[1], points[2], points[3]);
             var p2 : Vector3 = p;
             
             //What do I do with p2 to give the road thickness?
                 //and p starts in the center of the transform...
                 //how do I shift p over while still following the curve? 
             
                 
                 catVerts.Add(p);
             catVerts.Add(p2);
             
             if (catVerts.Count >= 4) {
                  // We have completed a new quad, create 2 triangles
              var start : int = catVerts.Count - 4;
              catTris.Add(start + 2);//0
              catTris.Add(start + 1);
              catTris.Add(start + 0);//2
              catTris.Add(start + 0);//1
                 catTris.Add(start + 3);
                 catTris.Add(start + 2);    
              }
              
         }

If that was too confusing basically what I need is a way to get the green lines here:

alt text

Obviously I have the black line from the PointOnPath function, but now I need the translations of it that will let create thickness for the road mesh.

Thanks! Or if you have your own example of Mesh Generation on a spline, that would be really helpful as well!

14576639169312.png (46.4 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by troien · Mar 11, 2016 at 01:59 PM

Recently I made something similar. How I got it to work is to not only get the point, but also get the forward at any given point along the path. (I used this tutorial, and there they included how to get the forward). Once you have the forward at that position, you also need an up in order to create a quaternion using Quaternion.LookRotation, since you want 2d, you can simply use Vector3.up I suppose.

Now that you have the rotation, you can calculate the point left and right to it using this simple calculation:

 Vector3 left = rotation * Vector3.left;
 Vector3 right = rotation * Vector3.right;

Now note that left and right here are just the offset to the PointAtPath, so you need to add them to that to get the correct position. You can ofcourse multiply Vector3.left and right by any value to get wider/smaller roads.

Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image SomeGuy22 · Mar 11, 2016 at 06:48 PM 0
Share

Thanks a ton! After a ton of tweaking, I got it to work somewhat correctly. However, now I'm getting some weird behaviour with short distance curves... The vertices are starting ahead/behind of where they're supposed to land. Do you know why that's happening?

avatar image SomeGuy22 · Mar 11, 2016 at 06:53 PM 0
Share

If it's any help, here's my current code:

 var velAtPoint = GetCurveVelocity(catT, points[0], points[1], points[3], road.transform).normalized;
                 
                 var rotAtPoint = Quaternion.LookRotation(velAtPoint, Vector3.up);
                 Debug.Log(rotAtPoint);
                 var left = rotAtPoint * -Vector3.right;
                 var right = rotAtPoint * Vector3.right;
                 
                 p += right;
                 p2 += left;

The CurveVelocity is the same as from the tutorial you linked to. I'm assu$$anonymous$$g this is what you meant by forward right?

avatar image SomeGuy22 · Mar 12, 2016 at 01:09 AM 0
Share

It seems like the points are messing up when the curve goes in a certain direction. When they go one way, everything works as expected. But the other way, the points will overshoot and shrink. Switching which point in the sequence gets the "left" vector only reverses the problem.

I tried the Vector3 Cross Product, hoping it would clear the issue, but the results are the same. Here's the code:

                         var velAtPoint = GetCurveVelocity(catT, points[0], points[1], points[3], road.transform).normalized;
                 
                 var crossAtPoint = Vector3.Cross(velAtPoint, Vector3.up);
                 
                 p += crossAtPoint;
                 p2 += -crossAtPoint;

Clearly I'm overlooking some sort of Vector $$anonymous$$ath issue... I just don't know what it is...

avatar image troien · Mar 12, 2016 at 12:02 PM 0
Share

with foward I mean the GetDirection method, wich in turn calls GetVelocity and normalizes it. Though normalizing shouldn't be needed when you use it just for the forward.

The getvelocity then calls this method

 public static Vector3 GetFirstDerivative(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
     {
         t = $$anonymous$$athf.Clamp01(t);
         float one$$anonymous$$inusT = 1f - t;
         return
             3f * one$$anonymous$$inusT * one$$anonymous$$inusT * (p1 - p0) +
             6f * one$$anonymous$$inusT * t * (p2 - p1) +
             3f * t * t * (p3 - p2);
     }

I coud use the result of this method as my forward. I personally haven't found any point at which it doesn't work (as long as I use Vector3.up for the LookRotation up at least). What points do you use when it doesn't work?

avatar image SomeGuy22 troien · Mar 12, 2016 at 02:46 PM 0
Share

That's exactly what I did--I just renamed GetVelocity into GetCurveVelocity. It still gets the First Derivative and as you can see above I normalize the result.

In theory everything should work. I even debugged the direction and the final rotation produced by LookRotation and everything seemed correct. It's only when I add it to the points then things start to mess up... At this point I'm not even doing the "curve" part of the curve, I'm just calling everything in a straight line to make sure it works. When the curve is built in the right direction, it seems to work as expected. But going left, the triangles inverse. And at close range, the points overshoot...

avatar image troien · Mar 12, 2016 at 07:50 PM 0
Share

If this comment is a duplicate plz ignore it... Unity answers buttons are not responding:(

And what if you remove the transform.TransformPoint inside the GetVelocity method? (So you basicallly only use GetFirstDerivative with the 4 points and t as parameter)?

For me this works :p Sadly I can't upload an image of it here, asunity answers throws a 405 error when I click the upload button :(

But perhaps in order to help you further I can post the code I used for my mesh generation. Note that this is code for a proof of concept, and not optimized, commented or even completely finished, however, it gets the job done for me :p

 private void Start()
 {
     $$anonymous$$esh mesh = new $$anonymous$$esh();
     List<Vector3> vertices = new List<Vector3>();
     List<int> triangles = new List<int>();
     List<Vector3> normals = new List<Vector3>();
      
     Vector3 Start = GetPoint(0f);
     Quaternion rotation = GetRotation(0);
     Vector3 left = rotation * Vector3.left;
     Vector3 right = rotation * Vector3.right;
     Vector3 up = rotation * Vector3.up;
     vertices.Add(Start + right);
     vertices.Add(Start + left);
     normals.Add(up);
     normals.Add(up);
     int triIndex = 0;
     
     int size = 10; // higher number means smoother but also more verts/tris
     for (int i = 0; i <= size; i++)
     {
         float t = (float)i / (float)size;
         Vector3 End = GetPoint(t);
         rotation = GetRotation(t);
      
         left = rotation * Vector3.left;
         right = rotation * Vector3.right;
         up = rotation * Vector3.up;
      
         vertices.Add(End + right);
         vertices.Add(End + left);
         normals.Add(up);
         normals.Add(up);
     
         triangles.Add(triIndex);
         triangles.Add(triIndex + 1);
         triangles.Add(triIndex + 2);
      
         triangles.Add(triIndex + 2);
         triangles.Add(triIndex + 1);
         triangles.Add(triIndex + 3);
      
         triIndex += 2;
      
         Start = End;
     }
      
     mesh.SetVertices(vertices);
     mesh.SetNormals(normals);
     mesh.SetTriangles(triangles, 0);
     GetComponent<$$anonymous$$eshFilter>().mesh = mesh;
 }
Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

39 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Mesh generated from bezier curve loop going outside loop 0 Answers

Mesh creation by code not working? 0 Answers

Connecting flatshaded vertices 0 Answers

Creating a mesh and assigning a material during edit time. 1 Answer

Dynamic batching after SetActive false and true? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges